From fbf3991638774314b52faefc3e6e0d545e8cd2f6 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Fri, 26 Apr 2024 12:53:50 +0100 Subject: [PATCH 001/123] Add missing space bar --- conda-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conda-env.yml b/conda-env.yml index 8c4d3582..359ab31a 100644 --- a/conda-env.yml +++ b/conda-env.yml @@ -11,5 +11,5 @@ dependencies: - graphviz - cython - pip - -pip: + - pip: - -r requirements.txt From 0e7642fca8f76cc8988e08053069dfe5f729e5a3 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 30 Apr 2024 13:02:56 +0100 Subject: [PATCH 002/123] Change introduction structure --- docs/md/pygom_workflow.md | 8 + docs/notebooks/model_solve.ipynb | 560 +++++++++++++++++++++++++++++++ docs/notebooks/model_spec.ipynb | 175 ++++++++++ 3 files changed, 743 insertions(+) create mode 100644 docs/md/pygom_workflow.md create mode 100644 docs/notebooks/model_solve.ipynb create mode 100644 docs/notebooks/model_spec.ipynb diff --git a/docs/md/pygom_workflow.md b/docs/md/pygom_workflow.md new file mode 100644 index 00000000..38f79a85 --- /dev/null +++ b/docs/md/pygom_workflow.md @@ -0,0 +1,8 @@ +# Pygom workflow + +The PyGom workflow is as follows + +1. Encapsulate the ODE system using a series of {class}`Transition` objects. +2. Feed this into a class {class}`DeterministicOde` or {class}`SimulateOde` depending on how solutions are required. +3. Use functionality to verify or update model specification. Find solutions etc. + diff --git a/docs/notebooks/model_solve.ipynb b/docs/notebooks/model_solve.ipynb new file mode 100644 index 00000000..2ec03c84 --- /dev/null +++ b/docs/notebooks/model_solve.ipynb @@ -0,0 +1,560 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "06b092c7", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import DeterministicOde" + ] + }, + { + "cell_type": "markdown", + "id": "46f1fc79", + "metadata": {}, + "source": [ + "6. And then initialize the model, which constructs our ODE system from all the information we have provided" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2d00708", + "metadata": {}, + "outputs": [], + "source": [ + "model = DeterministicOde(stateList, paramList, ode=odeList)" + ] + }, + { + "cell_type": "markdown", + "id": "db3a166f", + "metadata": {}, + "source": [ + "That is all the information required to define a simple SIR model. We can verify the model using" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39171530", + "metadata": {}, + "outputs": [], + "source": [ + "model.get_ode_eqn()" + ] + }, + { + "cell_type": "markdown", + "id": "bc3f2c5c", + "metadata": {}, + "source": [ + "where we can see the equations corresponding to their respective $S,I$ and $R$ state. " + ] + }, + { + "cell_type": "markdown", + "id": "ff37e8ad", + "metadata": {}, + "source": [ + "```{note}\n", + "The ordering of the equations is in the standard $S,I,R$ sequence because of how we defined the states initially. \n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "574a50f3", + "metadata": {}, + "source": [ + "We can rearrange the state list," + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11304d48", + "metadata": {}, + "outputs": [], + "source": [ + "# now we are going to define in a different order. note that the output ode changed with the input state\n", + "stateList = ['R', 'S', 'I']\n", + "\n", + "model = DeterministicOde(stateList, paramList, ode=odeList)\n", + "\n", + "model.get_ode_eqn()\n" + ] + }, + { + "cell_type": "markdown", + "id": "ed5aa20f", + "metadata": {}, + "source": [ + "and find that the set of ODEs comes out in the order that we specified. " + ] + }, + { + "cell_type": "markdown", + "id": "0d06bdf9", + "metadata": {}, + "source": [ + "```{tip}\n", + "In addition to showing the equation form of the ODEs, we can also display them as either symbols or latex code, which can save some extra typing when porting the equations to another document.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "83ea4dcb", + "metadata": {}, + "outputs": [], + "source": [ + "model.print_ode()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c05b408", + "metadata": {}, + "outputs": [], + "source": [ + "model.print_ode(True)" + ] + }, + { + "cell_type": "markdown", + "id": "3e7b28f3", + "metadata": {}, + "source": [ + "Here the SIR model was provided to PyGOM as a set ODEs by using the {class}`.Transition` to define them. \n", + "We have also provided the capability to obtain a *best guess* transition matrix when only the ODEs are available. See the section {doc}`unrollOde` for more information, and in particular {doc}`unrollSimple` for the continuing demonstration of the SIR model." + ] + }, + { + "cell_type": "markdown", + "id": "bdcecb64", + "metadata": {}, + "source": [ + "## Extracting model information\n", + "\n", + "We may wish to determine if the set of ODEs are linear. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "472627da", + "metadata": {}, + "outputs": [], + "source": [ + "model.linear_ode()" + ] + }, + { + "cell_type": "markdown", + "id": "0c24bd4d", + "metadata": {}, + "source": [ + "Since we know that the SIR model is not linear, we may want to have a look at the Jacobian.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "281970f1", + "metadata": {}, + "outputs": [], + "source": [ + "model.get_jacobian_eqn()" + ] + }, + { + "cell_type": "markdown", + "id": "189c4547", + "metadata": {}, + "source": [ + "Or maybe we want to know the gradient." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5440ae5", + "metadata": {}, + "outputs": [], + "source": [ + "model.get_grad_eqn()" + ] + }, + { + "cell_type": "markdown", + "id": "5971ef84", + "metadata": {}, + "source": [ + "```{Warning}\n", + "Invoking the functions that compute the derivatives, $f(x)$, `model.ode()` or `model.jacobian()`, will return an error\n", + "\n", + "These functions are used to solve the ODEs numerically, and require values of initial state values, time, and parameter values.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "2d52e99d", + "metadata": {}, + "source": [ + "For setting initial conditions, the numeric values of the states **must** be set in the same order that list of states appear. We can use the following to check the state ordering, as well as displaying all of the states that we have included." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fbf0da5a", + "metadata": {}, + "outputs": [], + "source": [ + "model.state_list" + ] + }, + { + "cell_type": "markdown", + "id": "32ce2410", + "metadata": {}, + "source": [ + "#TODO unsure if this is needed\n", + "\n", + "There is currently no mechanism to set the numeric initial conditions the states when the states are defined. This is because of an implementation issue with external package, such as solving an initial value problem." + ] + }, + { + "cell_type": "markdown", + "id": "7b7f8220", + "metadata": {}, + "source": [ + "## Initial value problem\n", + "\n", + "By setting the state initial conditions, time, and parameters, we can evaluate our model." + ] + }, + { + "cell_type": "markdown", + "id": "f6f00b34", + "metadata": {}, + "source": [ + "1. Define the model parameters. (We can call the parameters to check what we must provide.)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c163aa2f", + "metadata": {}, + "outputs": [], + "source": [ + "model.parameters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "696476fb", + "metadata": {}, + "outputs": [], + "source": [ + "paramEval = [('beta',0.5), ('gamma',1.0/3.0)]\n", + "\n", + "model.parameters = paramEval\n", + "\n", + "model.parameters" + ] + }, + { + "cell_type": "markdown", + "id": "e80ac7f8", + "metadata": {}, + "source": [ + "2. Provide initial conditions for the states." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b45e43c", + "metadata": {}, + "outputs": [], + "source": [ + "initialState = [0, 1, 1.27e-6]\n", + " \n", + "model.ode(state=initialState, t=1)" + ] + }, + { + "cell_type": "markdown", + "id": "105524d4", + "metadata": {}, + "source": [ + "\n", + "3. Implement an ODE solver.\n", + "\n", + "We are well equipped to solve an initial value problem, using the standard numerical integrator such as `odeint ` from `scipy.integrate`. We also used `matplotlib.pyplot` for plotting and `linspace ` to create the time vector." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c9e662c", + "metadata": {}, + "outputs": [], + "source": [ + "import scipy.integrate\n", + "import numpy\n", + "\n", + "t = numpy.linspace(0, 150, 100)\n", + "\n", + "solution = scipy.integrate.odeint(model.ode, initialState, t)" + ] + }, + { + "cell_type": "markdown", + "id": "75ccb76e", + "metadata": {}, + "source": [ + "We can plot our solution to observe a standard SIR shape." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5badfc50", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "plt.figure()\n", + "\n", + "plt.plot(t, solution[:,0], label='R')\n", + "\n", + "plt.plot(t, solution[:,1], label='S')\n", + "\n", + "plt.plot(t, solution[:,2], label='I')\n", + "\n", + "plt.xlabel('Time')\n", + "\n", + "plt.ylabel('Population proportion')\n", + "\n", + "plt.title('Standard SIR model')\n", + "\n", + "plt.legend(loc=0)\n", + "\n", + "#@savefig sir_plot.png In \n", + "\n", + "plt.show()\n", + "\n", + "#plt.close()\n" + ] + }, + { + "cell_type": "markdown", + "id": "2caa261e", + "metadata": {}, + "source": [ + "Alternatively, we can integrate and plot via the **ode** object which we initialized earlier." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b71d2931", + "metadata": {}, + "outputs": [], + "source": [ + "model.initial_values = (initialState, t[0])\n", + "\n", + "model.parameters = paramEval\n", + "\n", + "solution = model.integrate(t[1::])\n", + "\n", + "model.plot()" + ] + }, + { + "cell_type": "markdown", + "id": "58b41bf9", + "metadata": {}, + "source": [ + "We could solve the ODEs above using the Jacobian as well. Unfortunately, it does not help because the number of times the Jacobian was evaluated was zero, as expected given that our set of equations are not stiff." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e887ac3e", + "metadata": {}, + "outputs": [], + "source": [ + "#TODO what does this show?\n", + "%timeit solution1, output1 = scipy.integrate.odeint(model.ode, initialState, t, full_output=True)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5d3c7ddd", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "%timeit solution2, output2 = scipy.integrate.odeint(model.ode, initialState, t, Dfun=model.jacobian, mu=None, ml=None, full_output=True)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2de91b9e", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "%timeit solution3, output3 = model.integrate(t, full_output=True)" + ] + }, + { + "cell_type": "markdown", + "id": "f4707964", + "metadata": {}, + "source": [ + "It is important to note that we return our Jacobian as a dense square matrix. Hence, the two argument (mu,ml) for the ODE solver was set to `None` to let it know the output explicitly." + ] + }, + { + "cell_type": "markdown", + "id": "a0e384cc", + "metadata": {}, + "source": [ + "## Solving the forward sensitivity equation\n", + "\n", + "The sensitivity equations are also solved as an initial value problem. Let us redefine the model in the standard SIR order and we solve it with the sensitivity all set at zero, i.e. we do not wish to infer the initial value of the states." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b637cee", + "metadata": {}, + "outputs": [], + "source": [ + "stateList = ['S', 'I', 'R']\n", + "\n", + "model = DeterministicOde(stateList, paramList, ode=odeList)\n", + "\n", + "initialState = [1, 1.27e-6, 0]\n", + "\n", + "paramEval = [('beta', 0.5), ('gamma', 1.0/3.0)]\n", + "\n", + "model.parameters = paramEval\n", + "\n", + "solution = scipy.integrate.odeint(model.ode_and_sensitivity, numpy.append(initialState, numpy.zeros(6)), t)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8b63ba62", + "metadata": { + "tags": [ + "hide-output" + ] + }, + "outputs": [], + "source": [ + "{\n", + " \"tags\": [\n", + " \"hide-input\",\n", + " ]\n", + "}\n", + "f,axarr = plt.subplots(3,3);\n", + "\n", + "f.text(0.5,0.975,'SIR with forward sensitivity solved via ode',fontsize=16,horizontalalignment='center',verticalalignment='top')\n", + "\n", + "axarr[0,0].plot(t, solution[:,0])\n", + "\n", + "axarr[0,0].set_title('S')\n", + "\n", + "axarr[0,1].plot(t, solution[:,1])\n", + "\n", + "axarr[0,1].set_title('I')\n", + "\n", + "axarr[0,2].plot(t, solution[:,2]);\n", + "\n", + "axarr[0,2].set_title('R')\n", + "\n", + "axarr[1,0].plot(t, solution[:,3])\n", + "\n", + "axarr[1,0].set_title(r'state S parameter $beta$')\n", + "\n", + "axarr[2,0].plot(t, solution[:,4])\n", + "\n", + "axarr[2,0].set_title(r'state S parameter $gamma$')\n", + "\n", + "axarr[1,1].plot(t, solution[:,5])\n", + "\n", + "axarr[1,1].set_title(r'state I parameter $beta$')\n", + "\n", + "axarr[2,1].plot(t, solution[:,6])\n", + "\n", + "axarr[2,1].set_title(r'state I parameter $gamma$')\n", + "\n", + "axarr[1,2].plot(t, solution[:,7])\n", + "\n", + "axarr[1,2].set_title(r'state R parameter $beta$')\n", + "\n", + "axarr[2,2].plot(t, solution[:,8])\n", + "\n", + "axarr[2,2].set_title(r'state R parameter $gamma$')\n", + "\n", + "plt.tight_layout()\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "2f64d869", + "metadata": {}, + "source": [ + "This concludes the introductory example and we will be moving on to look at parameter estimation next in {doc}`estimate1` and the most important part in terms of setting up the ODE object; defining the equations in various different ways in {doc}`transition`." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.15" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/notebooks/model_spec.ipynb b/docs/notebooks/model_spec.ipynb new file mode 100644 index 00000000..116e6e15 --- /dev/null +++ b/docs/notebooks/model_spec.ipynb @@ -0,0 +1,175 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "5d9ccebd", + "metadata": {}, + "source": [ + "# Defining an ODE system\n", + "\n", + "There are 2 ways to encapsulate an ODE system.\n", + "\n", + "We first demonstrate how to encapsulate the relevant equations in a class which will eventually be used to solve them.\n", + "\n", + "One useful feature of PyGom is the ability to define the system in a variety of intuitive ways.\n", + "\n", + "In compartmental models, where the states represent counts of certain categories, the changes in these quantities\n", + "\n", + "## Example: SIR model\n", + "\n", + "Here we use a Susceptible-Infected-Removed epidemic model (an SIR model, for short) to demonstrate the different ways to specify a system.\n", + "The rates of change of each compartment are defined by the following equations\n", + "\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d} S}{\\mathrm{d} t} &= -\\beta SI \\\\\n", + "\\frac{\\mathrm{d} I}{\\mathrm{d} t} &= \\beta SI- \\gamma I \\\\\n", + "\\frac{\\mathrm{d} R}{\\mathrm{d} t} &= \\gamma I.\n", + "\\end{aligned}$$\n", + "\n", + "However, it is also true that this is the result of two transitions:\n", + "\n", + "$$\\begin{aligned}\n", + "S \\rightarrow I &= \\beta SI \\\\\n", + "I \\rightarrow R &= \\gamma I\n", + "\\end{aligned}$$\n", + "\n", + "\n", + "We can set this up as follows:" + ] + }, + { + "cell_type": "markdown", + "id": "586834ab", + "metadata": {}, + "source": [ + "1. Import the classes required to define the transitions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c80a36a", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import Transition, TransitionType" + ] + }, + { + "cell_type": "markdown", + "id": "0ec4c9d0", + "metadata": {}, + "source": [ + "2. Define our states, in this case the population states of **S**usceptible, **I**nfected and **R**emoved" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3ce016f2", + "metadata": {}, + "outputs": [], + "source": [ + "stateList = ['S', 'I', 'R']" + ] + }, + { + "cell_type": "markdown", + "id": "021a1927", + "metadata": {}, + "source": [ + "3. Define the set of parameters for our model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "441e2287", + "metadata": {}, + "outputs": [], + "source": [ + "paramList = ['beta', 'gamma']" + ] + }, + { + "cell_type": "markdown", + "id": "dfd736b2", + "metadata": {}, + "source": [ + "4. \n", + " i. Specify the transitions of the modelled states; this will form our ODE system" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b5f80ab0", + "metadata": {}, + "outputs": [], + "source": [ + "odeList = [\n", + " Transition(origin='S', equation='-beta*S*I', transition_type=TransitionType.ODE),\n", + " Transition(origin='I',equation='beta*S*I - gamma*I', transition_type=TransitionType.ODE),\n", + " Transition(origin='R', equation='gamma*I', transition_type=TransitionType.ODE) \n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "18c7fbac", + "metadata": {}, + "source": [ + "ii. Specify the transitions of the modelled states; this will form our ODE system" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a2761de1", + "metadata": {}, + "outputs": [], + "source": [ + "odeList2 = [\n", + " Transition(origin='S', destination='I', equation='beta*S*I', transition_type=TransitionType.T),\n", + " Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "21629e7b", + "metadata": {}, + "source": [ + "```{note}\n", + "Here, we have invoked a class from {class}`.Transition` to define the ODE object. We proceed here and ignore the details for now. The details of defining a transition object will be covered later in {doc}`transition`. Both the set of states and parameters should be defined when constructing the object, even though not explicitly enforced, to help clarify what we are trying to model. Similarly, this holds for the rest, such as the derived parameters and transitions, where we force the end user to input the different type of transition/process via the correct argument. See {ref}`transition:defining-the-equations` for an example when the input is wrong.\n", + "```" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.15" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From c0939abd427b41be027c7cacd1225b161b9e962a Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 11:19:03 +0100 Subject: [PATCH 003/123] Fix multiplication assignment bug --- pygom/loss/loss_type.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pygom/loss/loss_type.py b/pygom/loss/loss_type.py index 8cad7161..0d6fb41e 100644 --- a/pygom/loss/loss_type.py +++ b/pygom/loss/loss_type.py @@ -81,7 +81,8 @@ def residual(self, yhat, apply_weighting=True): else: resid = self._y - yhat if apply_weighting: - resid *= self._w + #resid *= self._w + resid = resid*self._w # above multiplication caused error return resid From 0a5fc17e748c6acded3a568b8a063e6386a0b0fe Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 11:44:22 +0100 Subject: [PATCH 004/123] Fix to get unroll to work when denominators are present in ODEs --- pygom/model/_ode_composition.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pygom/model/_ode_composition.py b/pygom/model/_ode_composition.py index 5596cb65..8972981b 100644 --- a/pygom/model/_ode_composition.py +++ b/pygom/model/_ode_composition.py @@ -393,10 +393,17 @@ def stripBDFromOde(fx, bd_list=None): term_in_expr = list(map(lambda x: x in fxi.expand().args, bd_list)) for j, term in enumerate(bd_list): fx_copy[i] -= term if term_in_expr[j] else 0 - # simplify converts it to an ImmutableMatrix, so we make it into # a mutable object again because we want the expanded form - return sympy.Matrix(sympy.simplify(fx_copy)).expand() + + # simplify() causes issues when we have terms with denominators as + # it will try to give all terms a common denominator thus + # potentially masking terms which should be matched. + # We try leaving it out for now, but some thorough testing is required + # of the unroll pipeline. + + # return sympy.Matrix(sympy.simplify(fx_copy)).expand() + return sympy.Matrix(fx_copy).expand() def odeToPureTransition(fx, states, output_remain=False): @@ -441,7 +448,7 @@ def _odeToPureTransition(fx, terms=None, A=None): Parameters ---------- fx: :class:`sympy.matrices.MatrixBase` - input ode in symbolic form, :math:`f(x)` + input ode with pure transitions in symbolic form, :math:`f(x)` terms: list of two element tuples which contains the matching terms From 59998c5e133901ce75a5daf813c1d8dab0b19560 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 14:06:52 +0100 Subject: [PATCH 005/123] Make SimulateOde main class by giving it both stochastic and deterministic solvers --- pygom/model/simulate.py | 195 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/pygom/model/simulate.py b/pygom/model/simulate.py index 0abf30f7..61a829c5 100644 --- a/pygom/model/simulate.py +++ b/pygom/model/simulate.py @@ -246,6 +246,198 @@ def sim(x): return Y, solutionList else: return Y + + def solve_determ(self, t, iteration=None, parallel=False, full_output=False): + ''' + Simulate the ode by generating new realization of the stochastic + parameters and integrate the system deterministically. + + Parameters + ---------- + t: array like + the range of time points which we want to see the result of + iteration: int + number of iterations you wish to simulate + parallel: bool, optional + Defaults to True + full_output: bool, optional + if we want additional information, Y_all in the return, + defaults to false + + Returns + ------- + Y: :class:`numpy.ndarray` + of shape (len(t), len(state)), mean of all the simulation + Y_all: :class:`np.ndarray` + of shape (iteration, len(t), len(state)) + ''' + if t is None: + raise InputError("Need to specify the time we wish to observe") + + # If parameters are not random then return one integration + if self._stochasticParam is None: + solution = self.integrate(t) + return solution + + # Otherwise, proceed for random parameters and verify expected extra parameters are present. + if iteration is None: + raise InputError("Need to specify the number of iterations") + + self._odeSolution = self.integrate(t) + + # try to compute the simulation in parallel + if parallel: + try: + for i in self._stochasticParam: + if isinstance(i, scipy.stats._distn_infrastructure.rv_frozen): + raise Exception("Cannot perform parallel simulation " + +"using a serialized object as distribution") + # check the type of parameter we have as input + import dask.bag + y = list() + for i in range(iteration): + y_i = list() + for key, rv in self._stochasticParam.items(): + y_i += [{key:rv.rvs(1)[0]}] + y += [y_i] + # y = [rv.rvs(iteration) for rv in self._stochasticParam.values()] + # y = np.array(list(zip(*y))) + def sim(x): + self.parameters = x + return self.integrate(t) + + # def sim(t1): return(self.integrate(t1)) + + # xtmp = dask.bag.from_sequence([t]*iteration) + xtmp = dask.bag.from_sequence(y) + solutionList = xtmp.map(sim).compute() + except Exception: # as e: + # print(e) + # print("Serial") + solutionList = [self.integrate(t) for i in range(iteration)] + else: + solutionList = [self.integrate(t) for i in range(iteration)] + + # now make our 3D array + # the first dimension is the number of iteration + Y = np.dstack(solutionList).mean(axis=2) + + if full_output: + return Y, solutionList + else: + return Y + + # Same as function below, just trying out new naming convention + def solve_stochast(self, t, iteration, parallel=False, + exact=False, full_output=False): + ''' + Simulate the ode using stochastic simulation. It switches + between a first reaction method and a :math:`\\tau`-leap + algorithm internally. When a parallel backend exists, then a new random + state (seed) will be used for each processor. This is due to a lack + of appropriate parallel seed random number generator in python. + + Parameters + ---------- + t: array like + the range of time points which we want to see the result of + or the final time point + iteration: int + number of iterations you wish to simulate + parallel: bool, optional + Defaults to True + exact: bool, optional + True if exact simulation is desired, defaults to False + full_output: bool, optional + if we want additional information, sim_T + + Returns + ------- + sim_X: list + of length iteration each with (len(t),len(state)) if t is a vector, + else it outputs unequal shape that was record of all the jumps + sim_T: list or :class:`numpy.ndarray` + if t is a single value, it outputs unequal shape that was + record of all the jumps. if t is a vector, it outputs t so that + it is a :class:`numpy.ndarray` instead + + ''' + + assert len(self._odeList) == 0, \ + "Currently only able to simulate when only transitions are present" + assert np.all(np.mod(self._x0, 1) == 0), \ + "Can only simulate a jump process with integer initial values" + + # this determines what type of output we want + timePoint = False + + if isinstance(t, Number):#, (int, float, np.int64, np.float64)): + finalT = t + elif isinstance(t, (list, tuple)): + t = np.array(t) + if len(t) == 1: + finalT = t + else: + finalT = t[-1:] + timePoint = True + elif isinstance(t, np.ndarray): + finalT = t[-1:] + timePoint = True + else: + raise InputError("Unknown data type for time") + + if self._transitionVectorCompile is None: + self._compileTransitionVector() + + if parallel: + try: + import dask.bag + logging.debug("Using Dask for parallel simulation") + def jump_partial(final_t): return(self._jump(final_t, + exact=exact, + full_output=True, + seed=True)) + + xtmp = dask.bag.from_sequence(np.ones(iteration)*finalT) + xtmp = xtmp.map(jump_partial).compute() + except Exception as e: + raise e + logging.warning("Parallel simulation failed reverting to serial") + xtmp = [self._jump(finalT, exact=exact, full_output=True) for _i in range(iteration)] + else: + logging.debug("Performing serial simulation") + xtmp = [self._jump(finalT, exact=exact, full_output=True) for _i in range(iteration)] + + xmat = list(zip(*xtmp)) + simXList, simTList = list(xmat[0]), list(xmat[1]) + ## print("Finish computation") + # now we want to fix our simulation, if they need fixing that is + # print timePoint + if timePoint: + for _i in range(len(simXList)): + # unroll, always the first element + # it is easy to remember that we are accessing the first + # element because pop is spelt similar to poop and we + # all know that your execute first in first out when you + # poop! + simX = simXList.pop(0) + simT = simTList.pop(0) + + x = self._extractObservationAtTime(simX, simT, t) + simTList.append(t) + simXList.append(x) + # note that we have to remain in list form because the number of + # simulation will be different if we are not dealing with + # a specific set of time points + + if full_output: + if timePoint: + return simXList, t + else: + return simXList, simTList + else: + return simXList + def simulate_jump(self, t, iteration, parallel=False, exact=False, full_output=False): @@ -361,6 +553,9 @@ def _jump(self, finalT, exact=False, full_output=True, seed=None): ''' Jumps from the initial time self._t0 to the input time finalT ''' + if isinstance(self._stochasticParam, dict): + self.parameters = self._stochasticParam + # initial time assert self._t0 is not None, "No initial time" assert self._x0 is not None, "No initial state" From bf75f3c1633943f3786f5dcba23c1ed6c9b2a5e3 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 14:08:59 +0100 Subject: [PATCH 006/123] Add some SimulateOde objects, currently they are only DeterministicOde. In future, SimulateOde might be only necessary class. --- pygom/model/common_models.py | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/pygom/model/common_models.py b/pygom/model/common_models.py index d5098020..13e1ed98 100644 --- a/pygom/model/common_models.py +++ b/pygom/model/common_models.py @@ -9,6 +9,7 @@ from .transition import TransitionType, Transition from .deterministic import DeterministicOde +from .simulate import SimulateOde def SIS(param=None): @@ -159,6 +160,53 @@ def SIR(param=None): return ode_obj +def SIR_N_stochastic(param=None, init=None): + """ + A standard SIR model [Brauer2008]_ with population N + + """ + stateList = ['S', 'I', 'R'] + paramList = ['beta', 'gamma', 'N'] + transitionList = [Transition(origin='S', destination='I', equation='beta*S*I/N', transition_type=TransitionType.T), + Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)] + + # initialize the model + ode_obj = SimulateOde(stateList, paramList, transition=transitionList) + + # set return, depending on whether we have input the parameters + + if param is not None: + ode_obj.parameters = param + + if init is not None: + ode_obj.initial_values = init + + return ode_obj + + +def SEIR_N_stochastic(param=None, init=None): + """ + A standard SIR model [Brauer2008]_ with population N + + """ + stateList = ['S', 'E', 'I', 'R'] + paramList = ['beta', 'alpha', 'gamma', 'N'] + transitionList = [Transition(origin='S', destination='E', equation='beta*S*I/N', transition_type=TransitionType.T), + Transition(origin='E', destination='I', equation='alpha*E', transition_type=TransitionType.T), + Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)] + + # initialize the model + ode_obj = SimulateOde(stateList, paramList, transition=transitionList) + + # set return, depending on whether we have input the parameters + if param is not None: + ode_obj.parameters = param + + if init is not None: + ode_obj.initial_values = init + + return ode_obj + def SIR_N(param=None): """ A standard SIR model [Brauer2008]_ with population N. This is the unnormalized From b2ddcfc1f02ec4b2b80d5de69b321e95032742ec Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 20:02:31 +0100 Subject: [PATCH 007/123] Fix bugs in NormalLoss and PoissonLoss declarations --- .../approximate_bayesian_computation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py b/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py index 01114f32..8262bb27 100644 --- a/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py +++ b/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py @@ -167,7 +167,7 @@ def create_loss(loss_type, parameters, ode, x0, t0, t, y, state_name, if loss_type == "SquareLoss": return SquareLoss(theta, ode, x0, t0, t, y, state_name, state_weight, target_param, target_state) - elif loss_type == NormalLoss: + elif loss_type == "NormalLoss": return NormalLoss(theta=theta, ode=ode, x0=x0, @@ -179,8 +179,8 @@ def create_loss(loss_type, parameters, ode, x0, t0, t, y, state_name, target_param=target_param, target_state=target_state) - elif loss_type == PoissonLoss: - return PoissonLoss(theta, ode, x0, t0, t, y, state_name, target_param, target_state) + elif loss_type == "PoissonLoss": + return PoissonLoss(theta, ode, x0, t0, t, y, state_name, state_weight, target_param, target_state) else: raise ValueError("Please choose from the available loss functions") From 61a7dfe8397f068523038a7e17627b855ac671c1 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 20:36:31 +0100 Subject: [PATCH 008/123] Intro edits --- docs/md/getting_started.md | 104 +++++++++++++++++++++---------------- docs/md/intro.md | 38 +++++++++++--- 2 files changed, 91 insertions(+), 51 deletions(-) diff --git a/docs/md/getting_started.md b/docs/md/getting_started.md index 561ec3e1..79904e57 100644 --- a/docs/md/getting_started.md +++ b/docs/md/getting_started.md @@ -1,5 +1,6 @@ -# Getting started +# Set up + -## Installing the package +## Installation -PyGOM can be downloaded from the GitHub repository. +### From source -https://github.com/PublicHealthEngland/pygom.git +Source code for PyGOM can be downloaded from the GitHub repository: https://github.com/ukhsa-collaboration/pygom -You will need to create an environment, for example using conda. +```bash +git clone https://github.com/ukhsa-collaboration/pygom.git +``` - conda env create -f conda-env.yml +```{note} +The latest fully reviewed version of PyGOM will be on the master branch and we recommend that users install the version from there. +``` -Alternatively, add dependencies to your own environment. +Dependencies may be added by creating an environment using conda - pip install -r requirements.txt +```bash +conda env create -f conda-env.yml +``` + +This environment should be active during the installation process + +```bash +conda activate pygom +``` + +Alternatively, you may add dependencies to your own environment. + +```bash +pip install -r requirements.txt +``` If you are working on a Windows machine you will also need to install: - [Graphviz](https://graphviz.org/) - [Visual C++](https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0) - [Visual C++ Build Tools](https://go.microsoft.com/fwlink/?LinkId=691126) -You can install the package via command line: +You you should be able to install the PyGOM package via command line: - python setup.py install - -or locally on a user level: +```bash +python setup.py install +``` - python setup.py install --user +If you anticipate making your own frequent changes to the PyGOM source files, it might be more convenient to install in develop mode instead: -```{note} -The latest fully reviewed version of PyGOM will be on master branch. We recommend that users install the version from this branch. +```bash +python setup.py develop ``` -Alternatively the latest release can be installed from [PyPI](https://pypi.org/project/pygom/): +### From PyPI - pip install pygom +Alternatively, the latest release can be installed from [PyPI](https://pypi.org/project/pygom/): -Please note that there are some redundant files that are being kept for -development purposes. +```bash +pip install pygom +``` + +```{note} +Please note that there are some redundant files that are being kept for development purposes. +``` ## Testing the package -Test files can be run from the command line prior to or after installation. +Test files can be run from the command line to check that installation has completed successfully - python setup.py test +```bash +python setup.py test +``` ## Building the documentation locally -Install additional packages: +The documentation which you are currently reading may be built locally. +First, install additional packages: - pip install -r docs/requirements.txt +```bash +pip install -r docs/requirements.txt +``` -Build the documentation: +Then build the documentation from command line - jupyter-book build docs/ +```bash +jupyter-book build docs +``` The html files will be saved in the local copy of your repository under: - pygom/docs/_build/html - - -## Using this documentation -This documentation is built using [JupyterBook](https://jupyterbook.org/en/stable/intro.html). To use the contents of a notebook as a starting point for trialing or developing your own models and analyses, you can download any of the examples within this documentation by using the download icon on the desired page (located at the top right). - -![download file](../images/download.png) - -## Contributing to PyGOM - -Please see the [contribution guidance](../../CONTRIBUTING.md) which outlines: -- required information for raising issues; -- the process by which code contributions should be incorporated; -- what is required by pull requests to PyGOM, including how to add to the documentation; -- how we will acknowledge your contributions. \ No newline at end of file + pygom/docs/_build/html \ No newline at end of file diff --git a/docs/md/intro.md b/docs/md/intro.md index 3f273853..5895f46a 100644 --- a/docs/md/intro.md +++ b/docs/md/intro.md @@ -1,17 +1,41 @@ # Welcome to the documentation for PyGOM -PyGOM (Python Generic ODE Model) is a Python package that aims to facilitate the application of ordinary differential equations (ODEs) in the real world, -with a focus in epidemiology. -This package helps the user define their ODE system in an intuitive manner and provides convenience functions - -making use of various algebraic and numerical libraries in the backend - that can be used in a straight forward fashion. +## What does this package do? -This is an open source project hosted on [Github](https://github.com/PublicHealthEngland/pygom). +PyGOM (Python Generic ODE Model) is a Python package which provides a simple interface to easily construct systems +governed by Ordinary Differential Equations (ODEs), with a focus on compartmental models and epidemiology. +This is backed by a comprehensive and easy to use tool–box which implements functions to easily perform common operations for ODE +systems such as solving, parameter estimation, and stochastic simulation. +The package source is freely available (hosted on [Github](https://github.com/PublicHealthEngland/pygom)) and organized in a way that permits easy extension. With both the algebraic and numeric calculations performed automatically (but still accessible), the end user is freed to focus on model development. -A manuscript containing a shortened motivation and use is hosted on [arxXiv](https://arxiv.org/abs/1803.06934). +## Using this documentation +This documentation is built using [JupyterBook](https://jupyterbook.org/en/stable/intro.html). To use the contents of a notebook as a starting point for trialing or developing your own models and analyses, you can download any of the examples within this documentation by using the download icon on the desired page (located at the top right). -#TODO insert intro text +![download file](../images/download.png) +## Contributing to PyGOM +Please see the [contribution guidance](https://github.com/ukhsa-collaboration/pygom/blob/master/CONTRIBUTING.md) which outlines: +- Required information for raising issues +- The process by which code contributions should be incorporated +- What is required by pull requests to PyGOM, including how to add to the documentation +- How we will acknowledge your contributions + + ```{tableofcontents} ``` From 5246fc106acadc0b91bf48e5869fa86a1517f3c6 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 21:49:46 +0100 Subject: [PATCH 009/123] ODE solving and simulation edits --- docs/md/solving.md | 10 + docs/notebooks/model_params.ipynb | 152 ++++++ docs/notebooks/model_solver.ipynb | 755 ++++++++++++++++++++++++++++++ 3 files changed, 917 insertions(+) create mode 100644 docs/md/solving.md create mode 100644 docs/notebooks/model_params.ipynb create mode 100644 docs/notebooks/model_solver.ipynb diff --git a/docs/md/solving.md b/docs/md/solving.md new file mode 100644 index 00000000..6c9635d4 --- /dev/null +++ b/docs/md/solving.md @@ -0,0 +1,10 @@ +# Producing forecasts + +Once the system of ODE's has been specified, PyGOM allows the user to numerically solve for both the deterministic and stochastic time evolution. +Furthermore, users may specify model parameters to take either fixed values or to be drawn randomly from a probability distribution. + +In this chapter, we will use an SIR model as our example system to introduce + +- How to prescribe parameters in {doc}`Parameterisation <../notebooks/model_params>` + +- How to obtain solutions and process the model output in {doc}`Finding ODE solutions <../notebooks/model_solver>` \ No newline at end of file diff --git a/docs/notebooks/model_params.ipynb b/docs/notebooks/model_params.ipynb new file mode 100644 index 00000000..5a43fd9b --- /dev/null +++ b/docs/notebooks/model_params.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e395ad9b", + "metadata": {}, + "source": [ + "# Parameterisation\n", + "\n", + "Until now, we have only dealt with parameters when it was necessary to inform PyGOM which of our symbols refer to states and which to parameters.\n", + "However, before PyGOM can find numerical solutions to the equations, it must be fed numerical parameter values.\n", + "\n", + "PyGOM's ODE solvers accept parameters in two forms: fixed, where they remain constant or random, where they are drawn at random from a given distribution.\n", + "We demonstrate these features on our model system, the SIR compartmental model. We start, as always, by encapsulating our ODE system in a pygom object from the previous section:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1679a48a", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import common_models\n", + "ode = common_models.SIR_N_stochastic()" + ] + }, + { + "cell_type": "markdown", + "id": "404cea05", + "metadata": {}, + "source": [ + "## Fixed parameters\n", + "\n", + "Defining fixed parameters is simple.\n", + "Here we assign $\\beta$, $\\gamma$ and $N$ as follows." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cc1bd57c", + "metadata": {}, + "outputs": [], + "source": [ + "fixed_param_set=[('beta', 0.3), ('gamma', 0.25), ('N', 1e4)]\n", + "ode.parameters=fixed_param_set" + ] + }, + { + "cell_type": "markdown", + "id": "b7f1018f", + "metadata": {}, + "source": [ + "\n", + "\n", + "## Random parameters\n", + "\n", + "Instead, imagine that we wish to run model simulations over a variety of parameter values to reflect our prior uncertainty on the values of those parameters.\n", + "A suitable choice of distribution for $\\gamma$ and $\\beta$ is a Gamma distribution, since it ensures that both parameters are positive as required.\n", + "In this example, we'll keep the total population, $N$, fixed, showing that a mixture of parameter types (fixed and random) is possible.\n", + "\n", + "To define our random distributions, we make use of the familiar syntax from [R](http://www.r-project.org/).\n", + "Unfortunately, we have to define it via a tuple, where the first item is the function handle (name) and the second the parameters. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52734403", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom.utilR import rgamma\n", + "random_param_set = dict() # container for random param set\n", + "random_param_set['gamma'] = (rgamma,{'shape':100, 'rate':400})\n", + "random_param_set['beta'] = (rgamma,{'shape':100, 'rate':333.33})\n", + "random_param_set['N'] = 1e4" + ] + }, + { + "cell_type": "markdown", + "id": "a4c4ca97", + "metadata": {}, + "source": [ + "Here, $\\gamma$ and $\\beta$ have means of 0.25 and 0.3 standard deviations of 0.025 and 0.03 respectively.\n", + "\n", + "When changing parameters, it is a good idea to define a new `SimulateOde` object, since there may be some calculated variables leftover from the previous parameter set." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24447ca7", + "metadata": {}, + "outputs": [], + "source": [ + "ode = common_models.SIR_N_stochastic()\n", + "ode.parameters=random_param_set" + ] + }, + { + "cell_type": "markdown", + "id": "b05c629f", + "metadata": {}, + "source": [ + "" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/notebooks/model_solver.ipynb b/docs/notebooks/model_solver.ipynb new file mode 100644 index 00000000..5e5c4e62 --- /dev/null +++ b/docs/notebooks/model_solver.ipynb @@ -0,0 +1,755 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Finding ODE solutions\n", + "\n", + "PyGOM allows the user to evaluate both the **deterministic** and **stochastic** time evolution of their ODE system using the class methods `solve_determ` and `solve_stochast` respectively. These methods work with fixed and random parameters as introduced in the {doc}`previous section <../notebooks/model_params>`.\n", + "\n", + "We begin by defining the series of ODEs and parameters which define our SIR system." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1679a48a", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "from pygom import SimulateOde, Transition, TransitionType\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "###################\n", + "# ODE specification\n", + "###################\n", + "\n", + "# Define SIR model\n", + "stateList = ['S', 'I', 'R']\n", + "paramList = ['beta', 'gamma', 'N']\n", + "transitionList = [Transition(origin='S', destination='I', equation='beta*S*I/N', transition_type=TransitionType.T),\n", + " Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)]\n", + "\n", + "# Total population is fixed\n", + "n_pop=1e4\n", + "\n", + "############\n", + "# Parameters\n", + "############\n", + "\n", + "beta_mn=0.35 # infectivity, beta. Gives the actual value for fixed params and mean for random distribution.\n", + "gamma_mn=0.25 # recovery rate, gamma.\n", + "\n", + "#######\n", + "# Fixed\n", + "#######\n", + "fixed_param_set=[('beta', beta_mn), ('gamma', gamma_mn), ('N', n_pop)]\n", + "\n", + "########\n", + "# Random\n", + "########\n", + "\n", + "# Recovery rate, gamma\n", + "gamma_var=(gamma_mn/10)**2 # Set the standard deviation to be 1/10th of the mean value\n", + "gamma_shape=(gamma_mn**2)/gamma_var\n", + "gamma_rate=gamma_mn/gamma_var\n", + "\n", + "# Infectivity parameter, beta\n", + "beta_var=(beta_mn/10)**2 # Set the standard deviation to be 1/10th of the mean value\n", + "beta_shape=(beta_mn**2)/beta_var\n", + "beta_rate=beta_mn/beta_var\n", + "\n", + "from pygom.utilR import rgamma\n", + "random_param_set = dict() # container for random param set\n", + "random_param_set['gamma'] = (rgamma,{'shape':gamma_shape, 'rate':gamma_rate})\n", + "random_param_set['beta'] = (rgamma,{'shape':beta_shape, 'rate':beta_rate})\n", + "random_param_set['N'] = n_pop" + ] + }, + { + "cell_type": "markdown", + "id": "e976c853", + "metadata": {}, + "source": [ + "In order to determine the time evolution of the system, we must supply initial conditions as well as the desired time points for the numerical solver.\n", + "It is generally a good idea to have the timestep an order of magnitude smaller than the fastest timescale of the system, in this case...." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e31cc4f", + "metadata": {}, + "outputs": [], + "source": [ + "# Initial conditions\n", + "i0=10\n", + "x0 = [n_pop-i0, i0, 0]\n", + "\n", + "# Time range and increments\n", + "tmax=200 # maximum time over which to run solver\n", + "dt=0.1 # timestep\n", + "n_timestep=int(tmax/dt) # number of iterations\n", + "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated" + ] + }, + { + "cell_type": "markdown", + "id": "ecd39e70", + "metadata": {}, + "source": [ + "## Deterministic time evolution\n", + "\n", + "To solve for the deterministic time evolution of the system, PyGOM uses `scipy.integrate.odeint`.\n", + "We begin with the simple (and likely familiar) case of fixed parameters.\n", + "\n", + "### Fixed parameters\n", + "\n", + "First, we initialise a `SimulateOde` object with our fixed parameters, `fixed_param_set`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "657a7646", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up pygom object (D_F suffix implies Deterministic_Fixed)\n", + "ode_D_F = SimulateOde(stateList, paramList, transition=transitionList)\n", + "ode_D_F.initial_values = (x0, t[0])\n", + "ode_D_F.parameters=fixed_param_set" + ] + }, + { + "cell_type": "markdown", + "id": "801dbfd6", + "metadata": {}, + "source": [ + "The solution is then found via `solve_determ`, specifying the required time steps not including the initial one." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f612095", + "metadata": {}, + "outputs": [], + "source": [ + "solution_D_F = ode_D_F.solve_determ(t[1::])" + ] + }, + { + "cell_type": "markdown", + "id": "a4d12509", + "metadata": {}, + "source": [ + "Plotting the output yields the familiar result, where infecteds initially increase in number exponentially until critical depletion of susceptibles sends the epidemic into decline." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2668b8ad", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", + "\n", + "axarr[0].plot(t, solution_D_F[:,0], color='C1')\n", + "axarr[1].plot(t, solution_D_F[:,1], color='C0')\n", + "axarr[2].plot(t, solution_D_F[:,2], color='C2')\n", + "\n", + "for idx, state in enumerate(stateList):\n", + " axarr[idx].set_title(state)\n" + ] + }, + { + "cell_type": "markdown", + "id": "0e516f09", + "metadata": {}, + "source": [ + "### Random parameters\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "bb53913b", + "metadata": {}, + "source": [ + "We now solve the same system, but for 1000 repetitions using randomly drawn parameters for each simulation.\n", + "This time we initialise the parameters with`random_param_set` and solve using `solve_determ` as before" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e7f1ee87", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up pygom object\n", + "ode_D_R = SimulateOde(stateList, paramList, transition=transitionList)\n", + "ode_D_R.initial_values = (x0, t[0])\n", + "\n", + "n_param_draws=1000 # number of parameters to draw\n", + "ode_D_R.parameters=random_param_set\n", + "Ymean, solution_D_R = ode_D_R.solve_determ(t[1::], n_param_draws, full_output=True)" + ] + }, + { + "cell_type": "markdown", + "id": "2221479d", + "metadata": {}, + "source": [ + "```{note}\n", + "Note that a message may be printed above where PyGOM is trying to connect to an\n", + "mpi backend, as our module has the capability to compute in parallel\n", + "using the IPython. We have simulated a total of 10 different solutions\n", + "using different parameters, the plots can be seen below.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "9bb7c942", + "metadata": {}, + "source": [ + "We visualise the output in 2 ways, first by viewing 50 randomly selected trajectories and also by viewing the confidence intervals (here 95% and 50%) and median calculated over the full 1000 solutions." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8849566b", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "y_D_R=np.dstack(solution_D_R) # unpack the data\n", + "\n", + "#########################\n", + "# Individual trajectories\n", + "#########################\n", + "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", + "\n", + "# Select 50 simulations to plot\n", + "import random\n", + "random.seed(10)\n", + "i_rand=random.sample(range(n_param_draws), 50)\n", + "\n", + "# Plot colours\n", + "colours=[\"C1\", \"C0\", \"C2\"]\n", + "\n", + "for i in i_rand:\n", + " for j in range(y_D_R.shape[1]):\n", + " axarr[j].plot(t, y_D_R[:,j,i], color=colours[j], alpha=0.2)\n", + "\n", + "for idx, state in enumerate(stateList):\n", + " axarr[idx].set_title(state)\n", + "\n", + "######################\n", + "# Confidence intervals\n", + "######################\n", + "\n", + "# Calculate 95%, 50% CIs and median.\n", + "y_D_R_lolo=np.percentile(y_D_R, 2.5, axis=2)\n", + "y_D_R_lo=np.percentile(y_D_R, 25, axis=2)\n", + "y_D_R_hi=np.percentile(y_D_R, 75, axis=2)\n", + "y_D_R_hihi=np.percentile(y_D_R, 97.5, axis=2)\n", + "y_D_R_md=np.percentile(y_D_R, 50, axis=2)\n", + "\n", + "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", + " \n", + "for i in range(0,3):\n", + " axarr[i].fill_between(t, y_D_R_lolo[:,i], y_D_R_hihi[:,i], alpha=0.2, facecolor=colours[i])\n", + " axarr[i].fill_between(t, y_D_R_lo[:,i], y_D_R_hi[:,i], alpha=0.4, facecolor=colours[i])\n", + " axarr[i].plot(t, y_D_R_md[:,i], color=colours[i])\n", + "\n", + "for idx, state in enumerate(stateList):\n", + " axarr[idx].set_title(state)\n" + ] + }, + { + "cell_type": "markdown", + "id": "39d66f12", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "id": "2f01a3d9", + "metadata": {}, + "source": [ + "## Stochastic evolution\n", + "\n", + "In a continuous Markov representation, each movement in the system is a result of a jump process.\n", + "More concretely, the probabilty of a move for transition $j$ is governed\n", + "by an exponential distribution such that\n", + "\n", + "$$\\Pr(\\text{process $j$ jump within time } \\tau) = \\lambda_{j} e^{-\\lambda_{j} \\tau},$$\n", + "\n", + "where $\\lambda_{j}$ is the rate of transition for process $j$ and $\\tau$\n", + "the time elapsed after current time $t$.\n", + "\n", + "Two of the commmon algorithms for the jump process have been\n", + "implemented for use during simulation; the reaction method [\\[Gillespie1977\\]]() and the $\\tau$-Leap method\n", + "[\\[Cao2006\\]](). The two change interactively depending on the size of the states.\n", + "\n", + "### Fixed parameters\n", + "\n", + "As previously, we define a model and pass our fixed parameters `fixed_param_set`.\n", + "However, this time we employ the function `solve_stochast`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "118a869b", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up pygom object\n", + "ode_S_F = SimulateOde(stateList, paramList, transition=transitionList)\n", + "ode_S_F.initial_values = (x0, t[0])\n", + "\n", + "n_sim=1000 # number of simulations\n", + "ode_S_F.parameters = fixed_param_set\n", + "solution_S_F, simT = ode_S_F.solve_stochast(t, n_sim, full_output=True)" + ] + }, + { + "cell_type": "markdown", + "id": "920d3a0b", + "metadata": {}, + "source": [ + "Before we inspect the epidemic time series, we plot the distribution of final epidemic sizes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a3698023", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "y_S_F=np.dstack(solution_S_F) # unpack the data\n", + "final_size_S_F=y_S_F[-1, 2, :]\n", + "\n", + "plt.figure(figsize=(3, 2.5))\n", + "plt.hist(final_size_S_F, bins=100, color=\"C0\")\n", + "\n", + "# Plot failed epidemics\n", + "i_success_S_F=np.where(final_size_S_F>2000)\n", + "y_fail_S_F=np.delete(y_S_F, obj=i_success_S_F, axis=2) \n", + "f, ax = plt.subplots(figsize=(3, 2.5))\n", + "\n", + "for i in range(min(y_fail_S_F.shape[2], 3)):\n", + " ax.plot(t[0:300], y_fail_S_F[0:300,1,i], color=\"C0\", alpha=0.5)" + ] + }, + { + "cell_type": "markdown", + "id": "39f93f66", + "metadata": {}, + "source": [ + "We see that a fraction, perhaps 4%, of the simulations have final sizes very close to zero.\n", + "In these cases, the chain of infecteds reaches stochastic extinction before an epidemic is able to take off.\n", + "We proceed to eliminate these when plotting our simulation outputs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f82a87ea", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "# Delete failed epidemics\n", + "i_fail_S_F=np.where(final_size_S_F<2000)\n", + "y_success_S_F=np.delete(y_S_F, obj=i_fail_S_F, axis=2) \n", + "\n", + "#########################\n", + "# Individual trajectories\n", + "#########################\n", + "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", + "\n", + "# Select 50 simulations to plot\n", + "i_rand=random.sample(range(y_success_S_F.shape[2]), 50)\n", + "\n", + "# Plot colours\n", + "colours=[\"C1\", \"C0\", \"C2\"]\n", + "\n", + "for i in i_rand:\n", + " for j in range(y_S_F.shape[1]):\n", + " axarr[j].plot(t, y_success_S_F[:,j,i], color=colours[j], alpha=0.2)\n", + "\n", + "for idx, state in enumerate(stateList):\n", + " axarr[idx].set_title(state)\n", + "\n", + "######################\n", + "# Confidence intervals\n", + "######################\n", + "\n", + "# Calculate 95%, 50% CIs and median.\n", + "y_S_F_lolo=np.percentile(y_success_S_F, 2.5, axis=2)\n", + "y_S_F_lo=np.percentile(y_success_S_F, 25, axis=2)\n", + "y_S_F_hi=np.percentile(y_success_S_F, 75, axis=2)\n", + "y_S_F_hihi=np.percentile(y_success_S_F, 97.5, axis=2)\n", + "y_S_F_md=np.percentile(y_success_S_F, 50, axis=2)\n", + "\n", + "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", + " \n", + "for i in range(0,3):\n", + " axarr[i].fill_between(t, y_S_F_lolo[:,i], y_S_F_hihi[:,i], alpha=0.2, facecolor=colours[i])\n", + " axarr[i].fill_between(t, y_S_F_lo[:,i], y_S_F_hi[:,i], alpha=0.4, facecolor=colours[i])\n", + " axarr[i].plot(t, y_S_F_md[:,i], color=colours[i])\n", + "\n", + "for idx, state in enumerate(stateList):\n", + " axarr[idx].set_title(state)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "e2b6b36b", + "metadata": {}, + "source": [ + "### Random parameters\n", + "\n", + "Finally, we explore a scenario where we wish to solve for a stochastic system with parameters drawn randomly from some distributions.\n", + "Using the random parameter set, `random_param_set`, defined previously" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f0c270ea", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up pygom object\n", + "ode_S_R = SimulateOde(stateList, paramList, transition=transitionList)\n", + "ode_S_R.initial_values = (x0, t[0])\n", + "\n", + "# In this case n_sim and n_param_draw mean the same thing since we have new parameter set per simulation\n", + "ode_S_R.parameters = random_param_set\n", + "solution_S_R, simT = ode_S_R.solve_stochast(t, n_sim, full_output=True)" + ] + }, + { + "cell_type": "markdown", + "id": "035eac47", + "metadata": {}, + "source": [ + "Again, we begin our analysis by inspecting the final size distribution." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91cb77b0", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "y_S_R=np.dstack(solution_S_R)\n", + "\n", + "final_size_S_R=y_S_R[-1, 2, :]\n", + "plt.figure(figsize=(3, 2.5))\n", + "plt.hist(final_size_S_R, bins=100)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "c54b61c9", + "metadata": {}, + "source": [ + "We see that the final size distribution is much more spread out, owing to increased variation in the parameters.\n", + "The cut off between failed and successful epidemics is less clear cut in this case and we set this by eye to be 2000.\n", + "Again, eliminating the failed epidemics we plot the model output" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a072686d", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "# Delete failed epidemics\n", + "i_fail_S_R=np.where(final_size_S_R<2000)\n", + "y_success_S_R=np.delete(y_S_R, obj=i_fail_S_R, axis=2) \n", + "\n", + "#########################\n", + "# Individual trajectories\n", + "#########################\n", + "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", + "\n", + "# Select 50 simulations to plot\n", + "i_rand=random.sample(range(y_success_S_R.shape[2]), 50)\n", + "\n", + "# Plot colours\n", + "colours=[\"C1\", \"C0\", \"C2\"]\n", + "\n", + "for i in i_rand:\n", + " for j in range(y_S_R.shape[1]):\n", + " axarr[j].plot(t, y_success_S_R[:,j,i], color=colours[j], alpha=0.2)\n", + "\n", + "for idx, state in enumerate(stateList):\n", + " axarr[idx].set_title(state)\n", + "\n", + "######################\n", + "# Confidence intervals\n", + "######################\n", + "\n", + "# Calculate 95%, 50% CIs and median.\n", + "y_S_R_lolo=np.percentile(y_success_S_R, 2.5, axis=2)\n", + "y_S_R_lo=np.percentile(y_success_S_R, 25, axis=2)\n", + "y_S_R_hi=np.percentile(y_success_S_R, 75, axis=2)\n", + "y_S_R_hihi=np.percentile(y_success_S_R, 97.5, axis=2)\n", + "y_S_R_md=np.percentile(y_success_S_R, 50, axis=2)\n", + "\n", + "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", + " \n", + "for i in range(0,3):\n", + " axarr[i].fill_between(t, y_S_R_lolo[:,i], y_S_R_hihi[:,i], alpha=0.2, facecolor=colours[i])\n", + " axarr[i].fill_between(t, y_S_R_lo[:,i], y_S_R_hi[:,i], alpha=0.4, facecolor=colours[i])\n", + " axarr[i].plot(t, y_S_R_md[:,i], color=colours[i])\n", + "\n", + "for idx, state in enumerate(stateList):\n", + " axarr[idx].set_title(state)" + ] + }, + { + "cell_type": "markdown", + "id": "57d2bc06", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "With two possible simulation methods and two possible parameter types, we have explored the four total model configurations.\n", + "We plot these results side by side for the infected compartment so we can observe the key differences." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b69ea71", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "ymax=1250\n", + "\n", + "#fig, axarr = plt.subplots(2,2, layout='constrained')\n", + "\n", + "# axarr[0][0].plot(t, solution_D_F[:,1], color=\"black\")\n", + "# axarr[0][0].set_ylim(bottom=0, top=ymax)\n", + "\n", + "# axarr[0][1].fill_between(t, y_S_F_lolo[:,j], y_S_F_hihi[:,j], alpha=0.3, facecolor='blue')\n", + "# axarr[0][1].fill_between(t, y_S_F_lo[:,j], y_S_F_hi[:,j], alpha=0.4, facecolor='blue')\n", + "# axarr[0][1].plot(t, y_S_F_md[:,j], color=\"black\")\n", + "# axarr[0][1].set_ylim(bottom=0, top=ymax)\n", + "\n", + "# axarr[1][0].fill_between(t, y_D_R_lolo[:,j], y_D_R_hihi[:,j], alpha=0.3, facecolor='blue')\n", + "# axarr[1][0].fill_between(t, y_D_R_lo[:,j], y_D_R_hi[:,j], alpha=0.4, facecolor='blue')\n", + "# axarr[1][0].plot(t, y_D_R_md[:,j], color=\"black\")\n", + "# axarr[1][0].set_ylim(bottom=0, top=ymax)\n", + "\n", + "# axarr[1][1].fill_between(t, y_S_R_lolo[:,j], y_S_R_hihi[:,j], alpha=0.3, facecolor='blue')\n", + "# axarr[1][1].fill_between(t, y_S_R_lo[:,j], y_S_R_hi[:,j], alpha=0.4, facecolor='blue')\n", + "# axarr[1][1].plot(t, y_S_R_md[:,j], color=\"black\")\n", + "# axarr[1][1].set_ylim(bottom=0, top=ymax)\n", + "\n", + "\n", + "fig, axarr2 = plt.subplots(2,2, layout='constrained', figsize=(10, 6))\n", + "\n", + "axarr2[0][0].plot(t, solution_D_F[:,1], color=\"C0\")\n", + "axarr2[0][0].set_ylim(bottom=0, top=ymax)\n", + "\n", + "i_rand=random.sample(range(n_param_draws), 50)\n", + "\n", + "for i in i_rand:\n", + " axarr2[0][1].plot(t, y_S_F[:,1,i], color=\"C0\", alpha=0.3)\n", + " axarr2[0][1].set_ylim(bottom=0, top=ymax)\n", + "\n", + " axarr2[1][0].plot(t, y_D_R[:,1,i], color=\"C0\", alpha=0.3)\n", + " axarr2[1][0].set_ylim(bottom=0, top=ymax)\n", + "\n", + " axarr2[1][1].plot(t, y_S_R[:,1,i], color=\"C0\", alpha=0.3)\n", + " axarr2[1][1].set_ylim(bottom=0, top=ymax)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "e1fe54a8", + "metadata": {}, + "source": [ + "" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ed58a1cf6cdb685b1a95019a821e15d4178d5da2 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 21:52:12 +0100 Subject: [PATCH 010/123] Parameter fitting edits --- docs/md/parameter_fitting.md | 10 +- docs/notebooks/paramfit/bvpSimple.ipynb | 250 +++++-- docs/notebooks/paramfit/params_via_abc.ipynb | 664 ++++++++++++++++++ .../paramfit/params_via_optimization.ipynb | 294 ++++++++ 4 files changed, 1149 insertions(+), 69 deletions(-) create mode 100644 docs/notebooks/paramfit/params_via_abc.ipynb create mode 100644 docs/notebooks/paramfit/params_via_optimization.ipynb diff --git a/docs/md/parameter_fitting.md b/docs/md/parameter_fitting.md index 4b252c67..7729d02f 100644 --- a/docs/md/parameter_fitting.md +++ b/docs/md/parameter_fitting.md @@ -1,8 +1,12 @@ # Parameter fitting -The following notebooks will demonstrate how to use the parameter fitting options within PyGOM. +In this chapter we outline how PyGOM may be used to estimate values for model parameters from data. +We focus on the common problem of finding epidemiological parameters from case data using Approximate Bayesian Computation (ABC). +We also demonstrate PyGom's ability to solve more commode ODE style problems like boundary value problems and +also ability to use more classical methods for optimization. -{doc}`../notebooks/paramfit/bvpSimple` + + \ No newline at end of file diff --git a/docs/notebooks/paramfit/bvpSimple.ipynb b/docs/notebooks/paramfit/bvpSimple.ipynb index 062c54f7..7b2d5d6e 100644 --- a/docs/notebooks/paramfit/bvpSimple.ipynb +++ b/docs/notebooks/paramfit/bvpSimple.ipynb @@ -25,46 +25,60 @@ "id": "1cfce26c", "metadata": {}, "source": [ - "\n", "## Simple model 1\n", "\n", "We are trying to find the solution to the second order differential\n", "equation\n", "\n", - "$$\\nabla^{2} y + |y| = 0$$\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d}^2 y}{\\mathrm{d} t^2} + |y| = 0\n", + "\\end{aligned}$$\n", "\n", - "subject to the boundary conditions $y(0) = 0$ and $y(4) = -2$. Convert\n", - "this into a set of first order ODEs\n", + "subject to the boundary conditions $y(0) = 0$ and $y(4) = -2$.\n", + "Convert this into a set of first order ODEs\n", "\n", "$$\\begin{aligned}\n", - "\\frac{d y_{0}}{dt} &= y_{1} \\\\\n", - "\\frac{d y_{1}}{dt} &= -|y_{0}|\n", + "\\frac{\\mathrm{d} y}{\\mathrm{d} t} &= z \\\\\n", + "\\frac{\\mathrm{d} z}{\\mathrm{d} t} &= -|y|\n", "\\end{aligned}$$\n", "\n", - "using an auxiliary variable $y_{1} = \\nabla y$ and $y_{0} = y$. \n", "Here we set up the system." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "594a9de8", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}z\\\\- \\left|{y}\\right|\\end{matrix}\\right]$" + ], + "text/plain": [ + "Matrix([\n", + "[ z],\n", + "[-Abs(y)]])" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "from pygom import Transition, TransitionType, DeterministicOde, SquareLoss\n", + "from pygom import Transition, TransitionType, SimulateOde, SquareLoss\n", "\n", "import matplotlib.pyplot as plt\n", "\n", - "stateList = ['y0', 'y1']\n", - "\n", + "stateList = ['y', 'z']\n", "paramList = []\n", "\n", - "ode1 = Transition(origin='y0', equation='y1', transition_type=TransitionType.ODE)\n", + "ode1 = Transition(origin='y', equation='z', transition_type=TransitionType.ODE)\n", + "ode2 = Transition(origin='z', equation='-abs(y)', transition_type=TransitionType.ODE)\n", "\n", - "ode2 = Transition(origin='y1', equation='-abs(y0)', transition_type=TransitionType.ODE)\n", - "\n", - "model = DeterministicOde(stateList, paramList, ode=[ode1, ode2])\n", + "model = SimulateOde(stateList, paramList, ode=[ode1, ode2])\n", "\n", "model.get_ode_eqn()" ] @@ -82,19 +96,15 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "9ae19c03", "metadata": {}, "outputs": [], "source": [ "import numpy\n", "\n", - "from scipy.optimize import minimize\n", - "\n", "initialState = [0.0, 1.0]\n", - "\n", "t = numpy.linspace(0, 4, 100)\n", - "\n", "model.initial_values = (initialState, t[0])\n", "\n", "solution = model.integrate(t[1::])" @@ -102,18 +112,37 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "id": "3952c813", "metadata": { "tags": [ "hide" ] }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "f = plt.figure()\n", - "model.plot()\n", - "plt.close()" + "model.plot()" ] }, { @@ -134,20 +163,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "aaf5a503", "metadata": {}, "outputs": [], "source": [ + "from scipy.optimize import minimize\n", + "\n", "theta = [0.0]\n", "\n", - "obj = SquareLoss(theta=theta, ode=model, x0=initialState, t0=t[0], \n", - " t=t[-1], y=[-2], state_name=['y0'], target_state=['y1'])\n", + "obj = SquareLoss(theta=theta,\n", + " ode=model,\n", + " t0=t[0], x0=initialState,\n", + " t=t[-1], y=[-2],\n", + " state_name=['y'], target_state=['z'])\n", "\n", "thetaHat = minimize(fun=obj.costIV, x0=[0.0])\n", - "\n", - "print(thetaHat)\n", - "\n", + "#print(thetaHat)\n", "model.initial_values = ([0.0] + thetaHat['x'].tolist(), t[0])\n", "\n", "solution = model.integrate(t[1::])" @@ -155,10 +187,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "id": "bffe9f2f", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "f = plt.figure()\n", "model.plot()\n", @@ -192,58 +244,76 @@ "\n", "#TODO add ref\n", "\n", - "$$\\nabla^{2} y + \\left(p - 2q \\cos(2x)\\right)y = 0$$\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d}^2 y}{\\mathrm{d} t^2} + \\left(p - 2q \\cos(2t)\\right) y = 0\n", + "\\end{aligned}$$\n", "\n", "and the aim is to compute the fourth eigenvalue $q=5$. There are three\n", "boundary conditions\n", "\n", - "$$\\nabla y(0) = 0, \\quad \\nabla y(\\pi) = 0, \\quad y(0) = 1$$\n", + "$$\\begin{aligned}\n", + "\\dot{y}(0)=0, \\quad \\dot{y}(\\pi)=0, \\quad y(0) = 1\n", + "\\end{aligned}$$\n", "\n", "and we aim to solve it by converting it to a first order ODE and tackle\n", "it as an IVP. As our model object does not allow the use of the time\n", "component in the equations, we introduce a anxiliary state $\\tau$ that\n", "replaces time $t$. Rewrite the equations using\n", - "$y_{0} = y, y_{1} = \\nabla y$ and define our model as" + "$z=\\dot{y}(t)$ and define our model as" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "afcf4558", "metadata": {}, "outputs": [], "source": [ - "stateList = ['y0', 'y1', 'tau']\n", + "stateList = ['y', 'z', 'tau']\n", "\n", - "IparamList = ['p']\n", + "paramList = ['p']\n", "\n", - "ode1 = Transition('y0', 'y1', TransitionType.ODE)\n", + "ode1 = Transition(transition_type=TransitionType.ODE, origin='y', equation='z')\n", + "ode2 = Transition(transition_type=TransitionType.ODE, origin='z', equation='-(p - 2*5*cos(2*tau))*y', )\n", + "ode3 = Transition(transition_type=TransitionType.ODE, origin='tau', equation='1')\n", "\n", - "ode2 = Transition('y1', '-(p - 2*5*cos(2*tau))*y0', TransitionType.ODE)\n", + "model = SimulateOde(stateList, paramList, ode=[ode1, ode2, ode3])\n", "\n", - "ode3 = Transition('tau', '1', TransitionType.ODE)\n", - "\n", - "model = DeterministicOde(stateList, paramList, ode=[ode1, ode2, ode3])\n", + "model.parameters = [('p', 15.0)]\n", "\n", "theta = [1.0, 1.0, 0.0]\n", - "\n", - "p = 15.0\n", - "\n", - "t = numpy.linspace(0, numpy.pi)\n", - "\n", - "model.parameters = [('p',p)]\n", - "\n", "model.initial_values = (theta, t[0])\n", "\n", + "t = numpy.linspace(0, numpy.pi)\n", "solution = model.integrate(t[1::])" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "c75eea5c", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "f = plt.figure()\n", "model.plot()\n", @@ -263,13 +333,39 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "110edf3a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: Optimization terminated successfully.\n", + " success: True\n", + " status: 0\n", + " fun: 4.6125586631762084e-15\n", + " x: [ 1.349e+01]\n", + " nit: 5\n", + " jac: [ 7.657e-08]\n", + " hess_inv: [[ 1.759e+00]]\n", + " nfev: 12\n", + " njev: 6\n" + ] + } + ], "source": [ - "obj = SquareLoss(15.0, model, x0=[1.0, 0.0, 0.0], t0=0.0, \n", - " t=numpy.pi, y=0.0, state_name='y1')\n", + "obj = SquareLoss(15.0,\n", + " ode=model,\n", + " t0=t[0], x0=[1.0, 0.0, 0.0], \n", + " t=t[-1], y=0.0,\n", + " state_name='y')\n", + "\n", + "obj = SquareLoss(theta=theta,\n", + " ode=model,\n", + " t0=t[0], x0=initialState,\n", + " t=t[-1], y=[-2],\n", + " state_name=['y'], target_state=['z'])\n", "\n", "xhatObj = minimize(obj.cost,[15])\n", "\n", @@ -284,10 +380,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "653c998f", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "f = plt.figure()\n", "\n", @@ -322,12 +438,6 @@ "\n", "[1] " ] - }, - { - "cell_type": "markdown", - "id": "ef9004bd", - "metadata": {}, - "source": [] } ], "metadata": { @@ -337,8 +447,16 @@ "name": "python3" }, "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", "name": "python", - "version": "3.9.15" + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" }, "vscode": { "interpreter": { diff --git a/docs/notebooks/paramfit/params_via_abc.ipynb b/docs/notebooks/paramfit/params_via_abc.ipynb new file mode 100644 index 00000000..8592329b --- /dev/null +++ b/docs/notebooks/paramfit/params_via_abc.ipynb @@ -0,0 +1,664 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "cad1d1d4", + "metadata": {}, + "source": [ + "# Parameter Estimation: Approximate Bayesian Computation" + ] + }, + { + "cell_type": "markdown", + "id": "05daf2f1", + "metadata": {}, + "source": [ + "An exercise central to the study of infectious diseases is inference of epidemic parameters from incidence data.\n", + "In this chapter we demonstrate how PyGOM uses Approximate Bayesian Computation to offer estimates for parameters with credible intervals.\n", + "\n", + "As an example, we use a synthetic data set produced by PyGOM's `solve_stochast ` function.\n", + "This is a stochastic epidemic simulation of an SEIR model with parameters:\n", + "\n", + "$\\beta=0.35,\\quad \\alpha=0.5,\\quad \\gamma=0.25,\\quad n_{\\text{pop}}=10^4,\\quad I(t=0)=5$\n", + "\n", + "Loading in the data file" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "de300402", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "out = np.loadtxt('seir_epi_data.txt')\n", + "t=out[:,0]\n", + "sol_i_r=out[:,1:3]" + ] + }, + { + "cell_type": "markdown", + "id": "0ba66de0", + "metadata": {}, + "source": [ + "We inspect the time series of the infected and removed populations." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "7660a673", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'R')" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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r4WJroS4W5+YEHeTHYgdLLMHokhFtV1zyqs61Uu1Oxv1QjeBvCSdOndBc8qrVFFtD24nAUS9hx56SN/+9rc7VY+pra2Vw+HQpEmT3M8lJyfrhhtu0Pbt2yVJe/bs0YULFzza5OXlqaioyN1mx44dslqt7kBeksaMGSOr1epu401TU5MaGho8HgDgUlFt19w1vgN5qS1BLglxES8I5oEwc2Vl7c0SGUPSkg01cbePnjwCgHnr1q1TVVWVli1b1uk1V6nZnJwcj+dzcnLcrzkcDvXt21cDBgzotk12dnan42dnZ7vbeLNs2TL3Hnur1aqBAwf6d3IAYpY/2eultr3yrFZEvGDPPBBmu2pPdpqR7wm7s1G7ak/GzV5ystoD5h05ckQPP/yw3nrrLaWkpHTZzmLxnMkyDKPTcx11bOOtva/jLFy4UI8++qj764aGBgJ6AJKknX894dfnJPbKI54wMw+EWd3p3gfywThWJOtqW4LD2ciWA8CLPXv2qK6uTqNGjVKfPn3Up08fbdmyRf/2b/+mPn36uGfkO86e19XVuV+z2Wxqbm5WfX19t20+++yzTt//888/7zTr315ycrLS09M9HgBQUW3XQ69WmW6fa21LHgzEC4J5IMyy07qeJQvnsSJVd9sSXM/F45YDoDs33nij9u/fr71797of11xzjb7//e9r7969+upXvyqbzabKykr3e5qbm7VlyxaNHTtWkjRq1CglJSV5tLHb7aqurna3KS4ultPp1K5du9xt/vznP8vpdLrbAIAZrhv3p85fMP0e9soj3rDMHgghb6Xnrs3PkC09RY6Gns+quzK3xsPdaF/bEgzF35YDwJe0tDQVFRV5PJeamqrMzEz386WlpVq6dKkKCgpUUFCgpUuXqn///po5c6YkyWq1avbs2VqwYIEyMzOVkZGhxx57TMOGDXMn1Lvyyis1efJk3XfffXrhhRcktZWmmzp1qulM9gDgbz6hBItUNmMk2+wQdwjmgRDprvRc4xctXt/jurd8//X5+t17R3XqXOe706428XI32uxWgnjZcgAEyuOPP67z589r7ty5qq+v1+jRo/XWW2+5a8xL0ooVK9SnTx/dcccdOn/+vG688UatXr3aXWNekl599VX98Ic/dGe9nz59usrKykJ+PgCil7/5hMpmjNDNwwnkEX+oMw+EgGupmL+/bAP6J2nZ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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.rcParams['figure.figsize'] = [10, 4]\n", + "f, axarr = plt.subplots(1,2, layout='constrained')\n", + "axarr[0].scatter(t, sol_i_r[:,0])\n", + "axarr[1].scatter(t, sol_i_r[:,1])\n", + "axarr[0].set_title('I')\n", + "axarr[1].set_title('R')" + ] + }, + { + "cell_type": "markdown", + "id": "b6a77aab", + "metadata": {}, + "source": [ + "```{note}\n", + "We typically do not have access to information regarding the total infected population. More commonly reported is the number of new cases in a given time period (or infection times). Furthermore, we are unlikely to know the removed population, unless, for example, the disease results in death.\n", + "\n", + "The purpose of this chapter is to demonstrate model fitting given a set of data and so these departures from reality shouldn't undermine the key messages.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "ba9907fd", + "metadata": {}, + "source": [ + "In the next sections, we are going to use PyGOM to obtain estimates for unknown values $\\beta$, $\\alpha$ and $\\gamma$ (assuming that the total population $N$ and initial number of infecteds $I(t=0)$ are known).\n", + "\n", + "```{note}\n", + "Again, it is rather unrealistic to know $I(t=0)$ or $N$\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "31ebefaa", + "metadata": {}, + "source": [ + "## Fitting an SEIR model (with Infected and Removed known)\n", + "\n", + "To obtain parameter estimates from data, we must provide a candidate model and specify the unknown parameters which we are interested in. Information regarding the candidate model is contained in `abc.create_loss()`, which requires:\n", + "1) A `SimulateOde` object which describes the system of ODE's\n", + "2) The loss function, which describes how we assume observations are distributed about the mean value (calculated via the `SimulateOde` object)\n", + "3) `abc.Parameter` which tells us which parameters we are interested in and their prior distributions.\n", + "4) The data to which we are fitting\n", + "\n", + "We start by specifying the ODE system. In this first example, we are going to assume (correctly) that the underlying process is an SEIR model.\n", + "We need to let the model know the value of $N$, however, a feature of PyGOM is that we must pass values for all parameters.\n", + "This usually acts to ensure that we do not under-specify the set of parameters when running simulations.\n", + "Thus, even though the other parameters ($\\beta$, $\\alpha$ and $\\gamma$) are unknown, the model expects some values and so for now we can just pass zeros, which will be overrode later when we specify ABC parameters." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "160c27ec", + "metadata": {}, + "outputs": [], + "source": [ + "# Set up pygom object from common models\n", + "from pygom import common_models\n", + "\n", + "n_pop=1e4\n", + "paramEval=[('beta', 0), ('alpha', 0), ('gamma', 0), ('N', n_pop)]\n", + "\n", + "ode_SEIR = common_models.SEIR_N_stochastic(param=paramEval)" + ] + }, + { + "cell_type": "markdown", + "id": "da9675c6", + "metadata": {}, + "source": [ + "The `Parameter` class is used to specify the parameters we wish to infer and their prior probability distributions.\n", + "We can choose from any of the distributions included in Pygom, here we use a uniform distribution." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "42291b82", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import approximate_bayesian_computation as abc\n", + "\n", + "parameters = [abc.Parameter('beta', 'unif', 0, 1, logscale=False),\n", + " abc.Parameter('alpha', 'unif', 0, 2, logscale=False),\n", + " abc.Parameter('gamma', 'unif', 0, 1, logscale=False)]" + ] + }, + { + "cell_type": "markdown", + "id": "11aa81ca", + "metadata": {}, + "source": [ + "Finally, we must decide how observations are produced from the underlying model.\n", + "If we assume that each data point is the result of a random draw from a poisson process with mean equal to the SEIR model output at that timepoint, we use the option `PoissonLoss` as our loss function when calling `create_loss` below. Now we combine everything together, including the initial conditions which we are assuming are known." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "dd353fe2", + "metadata": {}, + "outputs": [], + "source": [ + "i0=5\n", + "x0=[n_pop-i0, 0, i0, 0]\n", + "\n", + "from pygom import PoissonLoss\n", + "\n", + "objSEIR = abc.create_loss(\"PoissonLoss\", # Loss function\n", + " parameters, # Unknown parameters and prior distributions\n", + " ode_SEIR, # Model\n", + " x0, t[0], # Initial conditions and timepoints\n", + " t[1:], sol_i_r[1:,:], # Data timepoints and I, R values\n", + " ['I', 'R']) # Names of compartments in data\n", + "\n", + "abcSEIR = abc.ABC(objSEIR, parameters)" + ] + }, + { + "cell_type": "markdown", + "id": "4009b7ba", + "metadata": {}, + "source": [ + "A sequential Monte Carlo method (ABC-SMC) is used for param inference. This approach considers a series of generations, with each generation using a smaller threshold than the previous. The first generation is equivalent to the standard ABC algorithm, in the sense that parameters are sampled from prior distributions. In subsequent generations, candidate parameters are proposed by perturbing weighted samples from the previous generation. Here, we use a multivariate normal distribution with optimal local covariance matrix to perform the perturbation.\n", + "\n", + "The ABC-SMC method requires a couple of additional arguments to `get_posterior_sample`:\n", + "- G - the number of generations\n", + "- q - a quantile (0 < q < 1). Whilst it is possible to specify a list of tolerances to use in each generation, it is difficult to know what these should be. When specifying q, the tolerance for the current generation is set to the q-th quantile of the distances from the previous generation. Larger values of q will result in smaller reductions in thresholds but a higher acceptance rate.\n", + "\n", + "We run for 6 generations on our data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3c235ba", + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "random.seed(1)\n", + "\n", + "abcSEIR.get_posterior_sample(N=250, tol=np.inf, G=6, q=0.25, progress=True)" + ] + }, + { + "cell_type": "markdown", + "id": "c950e11a", + "metadata": {}, + "source": [ + "If we want to run the method for a few more generations, there is no need to start from the beginning. Instead, we can use `continue_posterior_sample` along with the `next_tol` attribute to set the tolerance. Let's perform 2 additional iterations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52063687", + "metadata": {}, + "outputs": [], + "source": [ + "abcSEIR.continue_posterior_sample(N=250, tol=abcSEIR.next_tol, G=2, q=0.25, progress=True)" + ] + }, + { + "cell_type": "markdown", + "id": "83092942", + "metadata": {}, + "source": [ + "There are built in methods to plot the posterior distribution and the corresponding fit to the data " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e4dfa76f", + "metadata": {}, + "outputs": [], + "source": [ + "abcSEIR.plot_posterior_histograms();\n", + "abcSEIR.plot_pointwise_predictions();" + ] + }, + { + "cell_type": "markdown", + "id": "614572bc", + "metadata": {}, + "source": [ + "The posterior draws are contained within `abcSIR.res`.\n", + "This can be useful if output needs to be saved, or for calculation credible intervals." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0cea2db3", + "metadata": {}, + "outputs": [], + "source": [ + "print(f'beta={np.median(abcSEIR.res[:,0]):.3f} ({np.quantile(abcSEIR.res[:,0], 0.025):.3f}, {np.quantile(abcSEIR.res[:,0], 0.975):.3f})')\n", + "print(f'alpha={np.median(abcSEIR.res[:,1]):.3f} ({np.quantile(abcSEIR.res[:,1], 0.025):.3f}, {np.quantile(abcSEIR.res[:,1], 0.975):.3f})')\n", + "print(f'gamma={np.median(abcSEIR.res[:,2]):.3f} ({np.quantile(abcSEIR.res[:,2], 0.025):.3f}, {np.quantile(abcSEIR.res[:,2], 0.975):.3f})')" + ] + }, + { + "cell_type": "markdown", + "id": "5c7611b2", + "metadata": {}, + "source": [ + "## Fitting an SEIR model (with only Infected known)\n", + "\n", + "We now fit the same model, but assume we only have access to data concerning the infected component.\n", + "All that changes code-wise is that we omit the recovered time series when inputting the data and specify that we only have information for the infected population in the last argument of `create_loss`. We run the ABC algorithm for 8 generations." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "6132aacd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Generation 1 \n", + " tolerance = inf \n", + " acceptance rate = 70.42%\n", + "\n", + "Generation 2 \n", + " tolerance = 68844.11979 \n", + " acceptance rate = 17.04%\n", + "\n", + "Generation 3 \n", + " tolerance = 12938.27625 \n", + " acceptance rate = 16.18%\n", + "\n", + "Generation 4 \n", + " tolerance = 3996.71842 \n", + " acceptance rate = 7.81%\n", + "\n", + "Generation 5 \n", + " tolerance = 1544.33260 \n", + " acceptance rate = 5.69%\n", + "\n", + "Generation 6 \n", + " tolerance = 932.12762 \n", + " acceptance rate = 4.59%\n", + "\n", + "Generation 7 \n", + " tolerance = 786.20244 \n", + " acceptance rate = 4.26%\n", + "\n", + "Generation 8 \n", + " tolerance = 745.97669 \n", + " acceptance rate = 9.37%\n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\users\\joseph.gibson\\pygom\\pygom\\approximate_bayesian_computation\\approximate_bayesian_computation.py:556: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown\n", + " f.show()\n", + "c:\\users\\joseph.gibson\\pygom\\pygom\\approximate_bayesian_computation\\approximate_bayesian_computation.py:634: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown\n", + " f.show()\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Posterior median estimates: beta=0.359, alpha=0.53, gamma=0.26 \n" + ] + }, + { + "data": { + "image/png": "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N1MjdANIZOFWugndgLMI3R4VbejOzPT/u29f8KenABAtt63plsx13bt3M9YBSFxspAa4A6Hbo6LZSE0yN1MzDKm83N4+AfAmt00vl8xKd3U1G0cCSFzhhm7WdAPOInR7VDRruiV2MAdgv8OHzbYbppdLwTuYc9kwAImqvunlrOkGYofQ7VHRTi+3hm7WdQOwgxunlwcq3RI7mANIXGykBrgDodujGju9XKLSDcAebttITeJa3QCSA2u6AXcgdHsU08sBuIUb13RbQzeVbgCJyjq93OcL/h5ruoHYIXR7VLSV7sAlwyRCNwB7uH1NN5VuAInKWuk+/nzPOr28sjI2/QG8itDtUY29ZJhE6AZgD7dXutlIDUCiqq/SbT3/s54XArAfodujrNOIIgnd1kr3vn22dQdISIWFhTr77LOVkZGhrKwsXXXVVdq4cWODj1u2bJkGDBig5s2bq3v37po+fXoMeutebgzdbKQGIBmEW+lmejngLEK3R9kxvZzQDa9btmyZ7rrrLq1cuVKLFy/WsWPHNGLECB08eDDkY4qKijR69GhdcMEFWrdunR566CHdc889mj9/fgx77i5u30iNSjdgr3A+sDQMQ5MmTVJeXp7S09M1bNgwffbZZ3HqceKyhu76Kt2EbsBZhG6PinZ6OaEbML399tu65ZZb1KdPH/Xr10+zZs3S9u3btWbNmpCPmT59urp06aIpU6aod+/e+tGPfqTbbrtNkydPjmHP3cW6ptstle7mzaUWLfxtKt2AvcL5wPLJJ5/UU089palTp2rVqlXKycnRJZdcov3798ex54kn3Ot0E7oBZ0UQt5BMqHQD9isvL5cktbPOTT7OBx98oBEjRgTdN3LkSM2cOVNHjx5VM+t2sh7hxunlkr/afegQoRuw29tvvx10e9asWcrKytKaNWt04YUXyjAMTZkyRQ8//LCuueYaSdKcOXOUnZ2tefPm6Y477ohHtxNSuNfpJnQDzqLS7VHRXjKsRQtzehIbqQEmwzCUn5+v888/X3379g15XGlpqbKzs4Puy87O1rFjx7R79+46H1NZWamKioqgr2Ti5tAtSXv2sMkQ4KTjP7AsKipSaWlp0AeUaWlpGjp0qN5///06nyPZx8loUekG3IHQ7VHRVrqbNDGnXH77/0gAksaNG6ePP/5YL730UoPH+o5bWGcYRp33BxQWFioz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/ssvvzRatGhhjB8/3vj888+N559/3mjWrJnxt7/9LcY9b1ik7238+PHGE088YfznP/8xNm3aZBQUFBjNmjUz1q5dG+Oe1y/S9xWwb98+o3v37saIESOMfv36xaazEYjmfX33u981Bg0aZCxevNgoKioyPvzwQ+Pf//53DHsdnkjf24oVK4wmTZoYv//9740vv/zSWLFihdGnTx/jqquuinHP67dw4ULj4YcfNubPn29IMl577bV6j0+k8cMqmcfJaET681iyZIkhydi4caNRUlJS+3Xs2LEY99wZXvk7CFekP49k/v0YOXKkMWvWLOPTTz811q9fb1x22WVGly5djAMHDoR8TKL+fiTrOJms55KGwfmkVSKcT3Iu6WfX2BHz0H3OOecYY8eODbrvtNNOMx588ME6j584caJx2mmnBd13xx13GOeee65jfYxWpO+tLqeffrrx6KOP2t21Ron2fV1//fXGT3/6U+PnP/+5KwfJSN/XW2+9ZWRmZhp79uyJRfcaJdL39pvf/Mbo3r170H1PP/200alTJ8f62FjhDJSJNH5YJfM4GY1Ifx6BULV3794Y9C6+kvnvIBqRhG4v/H6UlZUZkoxly5aFPCZRfz+SdZxM1nNJw+B8MiBRzic5l/Sza+yI6fTyqqoqrVmzRiNGjAi6f8SIEXr//ffrfMwHH3xwwvEjR47U6tWrdfToUcf6Gqlo3tvxampqtH//frVr186JLkYl2vc1a9Ysbd26VT//+c+d7mJUonlfCxYs0MCBA/Xkk0/qpJNOUs+ePXXffffp8OHDsehy2KJ5b0OGDNGOHTu0cOFCGYahXbt26W9/+5suu+yyWHTZMYkyflgl8zgZjcaMrf3791dubq4uvvhiLVmyxMluuloy/340hhd+P8rLyyWp3vOKRPz9SNZxMlnPJSXOJ60S4XySc0mTXWNHTEP37t27VV1drezs7KD7s7OzVVpaWudjSktL6zz+2LFj2r17t2N9jVQ07+14v/3tb3Xw4EF9//vfd6KLUYnmfW3evFkPPvig/vznPyslJSUW3YxYNO/ryy+/1HvvvadPP/1Ur732mqZMmaK//e1vuuuuu2LR5bBF896GDBmiP//5z7r++uuVmpqqnJwctWnTRs8880wsuuyYRBk/rJJ5nIxGND+P3NxczZgxQ/Pnz9err76qXr166eKLL9by5ctj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SdKtt96qf//733r55Zf18ccf67rrrtOll16qzZs3a8iQIZoyZYpat26tkpISlZSU6L777pPkD+u//OUv9dFHH+n1119XUVGRbrnllji+SwAI38GDB5Wfn69Vq1bpX//6l5o0aaKrr75aNTU1IR9z//33a/LkyVq1apWysrL03e9+V0ePHq39/qFDhzR58mS9+OKLWr58ubZv3147Zkr+E9wxY8ZoxYoVWrlypXr06KHRo0dr//79jr5XAKhLfn6+/v3vf2vBggVavHixVqxYEfRBYLjnepMmTdLUqVP1/vvvq7i4WN///vc1ZcoUzZs3T2+++aYWL16sZ555Jugxc+bMUYcOHfSf//xHd999t37yk5/ouuuu05AhQ7R27VqNHDlSN910U21Yr6mpUadOnfSXv/xFn3/+uX72s5/poYce0l/+8hdHf0ZIMAYQJ0OHDjV69+5t1NTU1N73wAMPGL179za2bNli+Hw+Y+fOnUGPufjii42CggLDMAxj1qxZRmZmZoOv85///MeQZOzfv9/W/gNALJSVlRmSjE8++cQoKioyJBnr1q0zDMMwlixZYkgyXn755drj9+zZY6SnpxuvvPKKYRj+sVKSsWXLltpjnn32WSM7Ozvkax47dszIyMgw/v73vzvzpgAghIqKCqNZs2bGX//619r79u3bZ7Ro0cIYP358nY85/lwvMDb+85//rD2msLDQkGRs3bq19r477rjDGDlyZO3toUOHGueff37t7WPHjhktW7Y0brrpptr7SkpKDEnGBx98EPI93Hnnnca1114b/ptG0qPSjbg699xz5fP5am8PHjxYmzdv1urVq2UYhnr27KlWrVrVfi1btizkNMuAdevW6corr1TXrl2VkZGhYcOGSZK2b9/u5FsBAFts3bpVN9xwg7p3767WrVurW7dukuofwwYPHlzbbteunXr16qUNGzbU3teiRQudcsoptbdzc3ODpmKWlZVp7Nix6tmzpzIzM5WZmakDBw4wbgKIuS+//FJHjx7VOeecU3tfZmamevXqVXs73HO9M888s7adnZ2tFi1aqHv37kH3Hb8E0fqYpk2bqn379jrjjDOCHiMp6HHTp0/XwIED1bFjR7Vq1UrPP/884yeCpMS7A0AoTZs21Zo1a9S0adOg+1u1ahXyMQcPHtSIESM0YsQIzZ07Vx07dtT27ds1cuRIVVVVOd1lAGi0K664Qp07d9bzzz+vvLw81dTUqG/fvhGPYdYPNJs1a3bC94xv98+QpFtuuUXffPONpkyZoq5duyotLU2DBw9m3AQQc4GxyTqGWe+P5FzPOvb5fL46x8Ljl+7UdczxzyOp9nF/+ctfdO+99+q3v/2tBg8erIyMDP3mN7/Rhx9+GPF7R/IidCOuVq5cecLtHj16qH///qqurlZZWZkuuOCCOh+bmpqq6urqoPu++OIL7d69W48//rg6d+4sSVq9erUznQcAm+3Zs0cbNmzQH/7wh9qx77333mvwcStXrlSXLl0kSXv37tWmTZt02mmnhf26K1as0HPPPafRo0dLkoqLi7V79+4o3gEANM4pp5yiZs2a6T//+U/tuVxFRYU2b96soUOHuu5cb8WKFRoyZIjuvPPO2vsampUJ72F6OeKquLhY+fn52rhxo1566SU988wzGj9+vHr27Kkbb7xRN998s1599VUVFRVp1apVeuKJJ7Rw4UJJ0sknn6wDBw7oX//6l3bv3q1Dhw6pS5cuSk1N1TPPPKMvv/xSCxYs0C9/+cs4v0sACE/btm3Vvn17zZgxQ1u2bNG7776r/Pz8Bh/3i1/8Qv/617/06aef6pZbblGHDh101VVXhf26p556ql588UVt2LBBH374oW688Ualp6c34p0AQHQyMjI0ZswY3X///VqyZIk+++wz3XbbbWrSpIl8Pp/rzvVOPfVUrV69Wu+88442bdqkRx55RKtWrYpbf+BOhG7E1c0336zDhw/rnHPO0V133aW7775b/+///T9J0qxZs3TzzTfr//7v/9SrVy9997vf1Ycfflj7qeaQIUM0duxYXX/99erYsaOefPJJdezYUbNnz9Zf//pXnX766Xr88cc1efLkeL5FAAhbkyZN9PLLL2vNmjXq27ev7r33Xv3mN79p8HGPP/64xo8frwEDBqikpEQLFixQampq2K/7pz/9SXv37lX//v1100036Z577lFWVlZj3goARO2pp57S4MGDdfnll+s73/mOzjvvPPXu3VvNmzd33bne2LFjdc011+j666/XoEGDtGfPnqCqNyBJPsO6qAsAACSMpUuXavjw4dq7d6/atGkT7+4AgCMOHjyok046Sb/97W91++23x7s7QMRY0w0AAADANdatW6cvvvhC55xzjsrLy/WLX/xCknTllVfGuWdAdAjdAAAAAFxl8uTJ2rhxo1JTUzVgwACtWLFCHTp0iHe3gKgwvRwAAAAAAIewkRoAAAAAAA4hdAMAAAAA4BBCNwAAAAAADiF0AwAAAADgEEI3AAAAAAAOIXQDAAAAAOAQQjcAAAAAAA4hdAMAAAAA4BBCNwAAAAAADvn/uyF2ld5Bp8gAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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ntbeeJYuXSoGDRok/Pz8RHR0tLj//vtFcXFxF4+6Zdf6+9gTc0NLmAOZAz2BObD75kBP5T+ZED3wOD8RERERERFRD8BruomIiIiIiIjchEU3ERERERERkZuw6CYiIiIiIiJyExbdRERERERERG7CopuIiIiIiIjITVh0ExEREREREbkJi24iIiIiIiIiN2HRTUREREREROQmLLrJpyxcuBBDhw719DCIiIiIiMhHyIQQwtODIOoMMpms1ftnzpyJZcuWwWKxIDQ0tItGRUREREREvoxFN3mN0tJS6ft169bhlVdewYkTJ6Q2Pz8/6PV6TwyNiIiIiIh8FE8vJ68RFRUlbXq9HjKZrEnb1aeXP/DAA5g2bRpef/11REZGolevXli0aBHsdjt++ctfIiQkBHFxcfj4449dnuv8+fOYPn06goODERoaiqlTp+Ls2bNdGzAREREREXV7LLrJ523evBkXLlzA9u3bsWTJEixcuBCTJ09GcHAw9uzZg1mzZmHWrFkoKioCAJjNZowdOxaBgYHYvn07du7cicDAQEycOBFWq9XD0RARERERUXfCopt8XkhICJYuXYqkpCQ89NBDSEpKgtlsxq9//WsMGDAA8+fPh1qtxnfffQcAWLt2LeRyOf785z8jPT0dKSkpWLlyJQoLC7F161bPBkNERERERN2K0tMDIPK01NRUyOX/+/wpMjISaWlp0m2FQoHQ0FCUl5cDAPbv349Tp05Bp9O57KehoQGnT5/umkETEREREVGPwKKbfJ5KpXK5LZPJmm1zOp0AAKfTiYyMDKxevbrJvsLDw903UCIiIiIi6nFYdBO10/Dhw7Fu3TpEREQgKCjI08MhIiIiIqJujNd0E7XT/fffj7CwMEydOhU7duxAQUEBtm3bhjlz5qC4uNjTwyMiIiIiom6ERTdRO/n7+2P79u2Ij4/H3XffjZSUFDz00EOor6/nkW8iIiIiInIhE0IITw+CiIiIiIiIyBvxSDcRERERERGRm7DoJiIiIiIiInITFt1EREREREREbsKim4iIiIiIiMhNWHQTERERERERuQmLbiIiIiIiIiI3YdFNRERERERE5CYsuomIiIiIiIjchEU3ERERERERkZuw6CYiIiIiIiJyExbdRERERERERG7CopuIiIiIiIjITf4/nnevc3nYcIMAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "objSEIR2 = abc.create_loss(\"PoissonLoss\",\n", + " parameters,\n", + " ode_SEIR,\n", + " x0, t[0],\n", + " t[1:], sol_i_r[1:,0], # now we only pass one column of epi data\n", + " ['I']) # now we only have information regarding the infected compartment\n", + "\n", + "abcSEIR2 = abc.ABC(objSEIR2, parameters)\n", + "\n", + "abcSEIR2.get_posterior_sample(N=250, tol=np.inf, G=8, q=0.25, progress=True)\n", + "abcSEIR2.plot_posterior_histograms();\n", + "abcSEIR2.plot_pointwise_predictions();" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b9fb499c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "beta=0.359 (0.330, 0.399)\n", + "alpha=0.526 (0.383, 0.740)\n", + "gamma=0.258 (0.242, 0.278)\n" + ] + } + ], + "source": [ + "print(f'beta={np.median(abcSEIR2.res[:,0]):.3f} ({np.quantile(abcSEIR2.res[:,0], 0.025):.3f}, {np.quantile(abcSEIR2.res[:,0], 0.975):.3f})')\n", + "print(f'alpha={np.median(abcSEIR2.res[:,1]):.3f} ({np.quantile(abcSEIR2.res[:,1], 0.025):.3f}, {np.quantile(abcSEIR2.res[:,1], 0.975):.3f})')\n", + "print(f'gamma={np.median(abcSEIR2.res[:,2]):.3f} ({np.quantile(abcSEIR2.res[:,2], 0.025):.3f}, {np.quantile(abcSEIR2.res[:,2], 0.975):.3f})')" + ] + }, + { + "cell_type": "markdown", + "id": "c6542afd", + "metadata": {}, + "source": [ + "We still see good estimates, even though we have constrained the model with one fewer state.\n", + "\n", + "## Fitting an SIR model (with only Infected known)\n", + "\n", + "Of course, we may not know the underlying mechanisms and might instead attempt to fit an SIR model to the infected data.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d328eee8", + "metadata": {}, + "outputs": [], + "source": [ + "parameters = [abc.Parameter('beta', 'unif', 0, 1, logscale=False),\n", + " abc.Parameter('gamma', 'unif', 0, 1, logscale=False)]\n", + "\n", + "# Params\n", + "paramEval=[('beta', 0), ('gamma', 0), ('N', n_pop)]\n", + "\n", + "# Initial conditions now doen't require E0\n", + "x0=[n_pop-i0, i0, 0]\n", + "\n", + "# Set up pygom object\n", + "ode_SIR = common_models.SIR_N_stochastic(param=paramEval)\n", + "\n", + "objSIR = abc.create_loss(\"PoissonLoss\", parameters, ode_SIR, x0, t[0], t[1:], sol_i_r[1:,0], ['I'])\n", + "abcSIR = abc.ABC(objSIR, parameters)\n", + "\n", + "abcSIR.get_posterior_sample(N=250, tol=np.inf, G=8, q=0.25, progress=True)\n", + "\n", + "abcSIR.plot_posterior_histograms();\n", + "abcSIR.plot_pointwise_predictions();" + ] + }, + { + "cell_type": "markdown", + "id": "4f3d6704", + "metadata": {}, + "source": [ + "Although we see smaller CI's this actually reflects the difficulty in model fitting and is not an indication of precision." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b9bb60c9", + "metadata": {}, + "outputs": [], + "source": [ + "print(f'beta={np.median(abcSEIR.res[:,0]):.3f} ({np.quantile(abcSEIR.res[:,0], 0.025):.3f}, {np.quantile(abcSEIR.res[:,0], 0.975):.3f})')\n", + "print(f'gamma={np.median(abcSEIR.res[:,1]):.3f} ({np.quantile(abcSEIR.res[:,1], 0.025):.3f}, {np.quantile(abcSEIR.res[:,1], 0.975):.3f})')" + ] + }, + { + "cell_type": "markdown", + "id": "68de3e94", + "metadata": {}, + "source": [ + "## Initial conditions\n", + "\n", + "In addition to inferring model parameters, the ABC methods can be used to estimate initial conditions, after all, it is unlikely that $I(t=0)$ is known with certainty.\n", + "To do this, the state that we wish to estimate the initial condition for should be included in the `parameters`:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "85dc7fa9", + "metadata": {}, + "outputs": [], + "source": [ + "parameters = [abc.Parameter('beta', 'unif', 0, 1, logscale=False),\n", + " abc.Parameter('alpha', 'unif', 0, 2, logscale=False),\n", + " abc.Parameter('gamma', 'unif', 0, 1, logscale=False),\n", + " abc.Parameter('I', 'unif', 0, 20, logscale=False)]" + ] + }, + { + "cell_type": "markdown", + "id": "061f2654", + "metadata": {}, + "source": [ + "The remaining code remains the same as before. Again we still need to pass variables even if they are unknown. In this case i0." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "ca613e08", + "metadata": {}, + "outputs": [], + "source": [ + "i0=5\n", + "x0=[n_pop-i0, 0, i0, 0]\n", + "\n", + "objSEIR3 = abc.create_loss(\"PoissonLoss\",\n", + " parameters,\n", + " ode_SEIR,\n", + " x0, t[0],\n", + " t[1:], sol_i_r[1:,0], # now we only pass one column of epi data\n", + " ['I']) # now we only have information regarding the infected compartment\n", + "\n", + "abcSEIR3 = abc.ABC(objSEIR3, parameters)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "2ba62e53", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Generation 1 \n", + " tolerance = inf \n", + " acceptance rate = 75.99%\n", + "\n", + "Generation 2 \n", + " tolerance = 56870.05009 \n", + " acceptance rate = 13.30%\n", + "\n", + "Generation 3 \n", + " tolerance = 18012.48554 \n", + " acceptance rate = 12.99%\n", + "\n", + "Generation 4 \n", + " tolerance = 4926.70805 \n", + " acceptance rate = 6.67%\n", + "\n", + "Generation 5 \n", + " tolerance = 2036.33956 \n", + " acceptance rate = 4.54%\n", + "\n", + "Generation 6 \n", + " tolerance = 1180.79752 \n", + " acceptance rate = 2.87%\n", + "\n", + "Generation 7 \n", + " tolerance = 879.70651 \n", + " acceptance rate = 1.33%\n", + "\n", + "Generation 8 \n", + " tolerance = 781.66943 \n", + " acceptance rate = 0.70%\n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\users\\joseph.gibson\\pygom\\pygom\\approximate_bayesian_computation\\approximate_bayesian_computation.py:556: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown\n", + " f.show()\n", + "c:\\users\\joseph.gibson\\pygom\\pygom\\approximate_bayesian_computation\\approximate_bayesian_computation.py:634: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown\n", + " f.show()\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAGGCAYAAABmGOKbAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAADlIElEQVR4nOzdeXiU1dn48e/sWyaTzEwmC9khCSEJ+45WBdwRcaltKfxcq31VlIpVcXmr1ULFurRYrVoFraK+fS1WscoiCipLQlizh+z7ZJ1Mktlnfn9A5jWACpgQSM7nup6LZOZk5jwkOXnu55xz35JAIBBAEARBEARBEARBEIR+Jx3sDgiCIAiCIAiCIAjCUCWCbkEQBEEQBEEQBEEYICLoFgRBEARBEARBEIQBIoJuQRAEQRAEQRAEQRggIugWBEEQBEEQBEEQhAEigm5BEARBEARBEARBGCAi6BYEQRAEQRAEQRCEASKCbkEQBEEQBEEQBEEYICLoFgRBEARBEARBEIQBIoJuYVjbvXs311xzDfHx8ahUKiIjI5kxYwbLli0b7K4JgiAMuLVr1yKRSL7z+PLLLwe7i4IgCGdE73i4Z8+ewe6KMATJB7sDgjBYPvnkE+bPn8+FF17IqlWriI6OpqGhgT179vDee+/x7LPPDnYXBUEQzog1a9YwevTo4x4fM2bMIPRGEARBEIYWEXQLw9aqVatISkpi48aNyOX/96vw85//nFWrVg1izwRBEM6szMxMJk+ePNjdEARBEIQhSSwvF4at1tZWzGZzn4C7l1QqfjUEQRAEQRAEQfjxRGQhDFszZsxg9+7d3HPPPezevRuPxzPYXRIEQRgUPp8Pr9fb5/D5fIPdLUEQBEEYEkTQLQxbf/zjHznvvPNYvXo106dPR6fTMWvWLP74xz/S1dU12N0TBEE4Y6ZPn45CoehzqFSqwe6WIAiCIAwJYk+3MGyZTCa++uor9uzZw+eff86ePXv48ssvWb58Oa+88go5OTmYzebB7qYgCMKAe+utt0hPT+/zmEQiGaTeCIIgCMLQIoJuYdibPHlyMIGQx+PhwQcf5Pnnn2fVqlUioZogCMNCenq6SKQmCIIgCANELC8XhG9RKBT87ne/AyAvL2+QeyMIgiAIgiAIwrlOBN3CsNXQ0HDCxwsLCwGIiYk5k90RBEEQBEEQBGEIEsvLhWHr0ksvJTY2lquuuorRo0fj9/vZv38/zz77LCEhIdx7772D3UVBEIQzIi8vD6/Xe9zjI0eOJCIiYhB6JAiCIAhDhwi6hWHr0Ucf5d///jfPP/88DQ0NuFwuoqOjmTt3LsuXLz8uqZAgCMJQdfPNN5/w8ddee43bbrvtDPdGEARBEIYWSSAQCAx2JwRBEARBEARBEARhKBJ7ugVBEARBEARBEARhgIigWxAEQRAEQRAEQRAGiAi6BUEQBEEQBEEQBGGAiKBbEARBEARBEARBEAaICLoFQRAEQRAEQRAEYYCIoFsQBEEQBEEQBEEQBsiwrtPt9/upr69Hr9cjkUgGuzuCIJwlAoEAdrudmJgYpNKhe29SjIGCIJyIGAMFQRjOBmIMHNZBd319PXFxcYPdDUEQzlI1NTXExsYOdjcGjBgDBUH4PmIMFARhOOvPMfCUg+7t27fzzDPPkJubS0NDA+vXr2fBggXB5wOBAE888QSvvvoq7e3tTJs2jb/+9a9kZGQE27hcLu6//37effddHA4Hc+bM4aWXXupzUu3t7dxzzz189NFHAMyfP5/Vq1cTFhYWbFNdXc1dd93F1q1b0Wg0LFy4kD/96U8olcqTOhe9Xg8c+Q8NDQ091f8KQRCGqM7OTuLi4oJjxFAlxkBBEE5EjIGCIAxnAzEGnnLQ3d3dzbhx47j55pu57rrrjnt+1apVPPfcc6xdu5bU1FSeeuopLr74YoqLi4MdX7p0KR9//DHvvfceJpOJZcuWMW/ePHJzc5HJZAAsXLiQ2tpaPvvsMwBuv/12Fi9ezMcffwyAz+fjyiuvJCIigq+//prW1lZuvPFGAoEAq1evPqlz6V1KFBoaKgZbQRCOM9SXG4oxUBCE7yPGQEEQhrP+HAMlgUAg8GM68u2Z7kAgQExMDEuXLuXBBx8EjsxqR0ZG8vTTT3PHHXdgs9mIiIjgH//4Bz/72c+A/1ve85///IdLL72UwsJCxowZw65du5g2bRoAu3btYsaMGRQVFZGWlsann37KvHnzqKmpISYmBoD33nuPm266CavVelKDZ2dnJwaDAZvNJgZbQRCChsvYMFzOUxCEUzNcxobhcp6CIJyagRgb+nVPd0VFBY2NjVxyySXBx1QqFRdccAE7duzgjjvuIDc3F4/H06dNTEwMmZmZ7Nixg0svvZSdO3diMBiCATfA9OnTMRgM7Nixg7S0NHbu3ElmZmYw4Aa49NJLcblc5ObmctFFFx3XP5fLhcvlCn7e2dl5aif46KMgl4NKBWr1kePbHx/7+Xd9LJfDEL97LAiCIAiCIAiCIPRz0N3Y2AhAZGRkn8cjIyOpqqoKtlEqlYSHhx/XpvfrGxsbsVgsx72+xWLp0+bY9wkPD0epVAbbHGvlypU88cQTp3FmQCBAYMUKJKe/MOD/XkoqJaDRENDrITSUgMEAej0YDBAaiiQs7P+OiAiIjPy/w2SCo0vwBUEQBOFYLpeL1tZW7HY7Xq8XuVyOTqfDZDKh0WgGu3uCIAhnVG8m6o6ODhwOB16vF6VSSVhYGEajMbi1VRAG0oBkLz92/XsgEPjBNfHHtjlR+9Np823Lly/nvvvuC37eu0n+pAQCBO65B2tdHb6uLiRuN9JvHx7P//3b+/G3Hpd5vf/Xb78fSXc3dHfDd9wg+M5uSKX4wsPxmUz4oqLwx8URiI+HhARkycnIkpNRJCQglQ/rxPSCIAjDjt1up7Kykurqanp6evD7/X3+Hmo0GuLi4khMTOyTlFQQBGEoCgQCNDc3U1ZWRlNTE263u8/zMpkMk8lESkoKMTExQz6HgTC4+jUyi4qKAo7MQkdHRwcft1qtwVnpqKgo3G437e3tfWa7rVYrM2fODLZpamo67vWbm5v7vM7u3bv7PN/e3o7H4zluBryXSqVCpVKd3slJpUhfeIETv/IRfr8/ePh8PrxH//X5fPg8HnwOB77ubnzd3XhtNnxtbfg7OvC1t+Nva0Pa1YXs20d3N0qbDVVHB2qbDVVXFxK/H3lrK/LWVigpOWE/fCoV9rg4XElJ+FJT8Y8eTWDcOBRpaWi0WjQajbirJwiCMET4fD7Ky8spLi6mu7sbrVaLyWTqU1vU7/fT09NDcXExVVVVJCUlkZaWdvp/EwXhR3j55Zd5+eWXqaysBCAjI4P//u//5vLLLwf6rxKOMHw5HA4KCwuprKzE6/Wi1+sxGAx9AmuPx0NLSwutra3ExcWRmZmJVqsdxF4LQ1m/Bt1JSUlERUWxefNmJkyYAIDb7Wbbtm08/fTTAEyaNAmFQsHmzZu54YYbAGhoaCAvL49Vq1YBMGPGDGw2G9nZ2UydOhWA3bt3Y7PZgoH5jBkz+MMf/kBDQ0MwwN+0aRMqlYpJkyb152mdNKlU+qMLqAcCAXw+H263O3jYXS5aXC6cXV24amtx19YitVpRNDWhampC29yM1molpKUFTVsbMpcL/eHD6A8fhs2bg6/tCgmhY9QoGtLScGZmwtSpqJOSCAkJQafTodPpRDAuCIJwDnG5XOzfv5+qqirUajUWi+WEszVSqTQ41vf09FBYWEhzczMTJkzAaDQOQs+F4Sw2NpY//vGPjBo1CoA333yTq6++mn379pGRkdFvlXCE4clqtbJ//37a2towGAxoNBr8fj9NTU309PSg1WqxWCwoFArMZjNOp5Py8nJsNhsTJkzAbDYP9ikIQ9ApZy/v6uri8OHDAEyYMIHnnnuOiy66CKPRSHx8PE8//TQrV65kzZo1pKSksGLFCr788ss+A+V//dd/sWHDBtauXYvRaOT++++ntbW1z0B5+eWXU19fzyuvvAIcKRmWkJDQp2TY+PHjiYyM5JlnnqGtrY2bbrqJBQsWnHTJsHM1a2UgEMDj8eBwOOjp6aGnpye4V6XbZkNeU4OuuprQujrCGhow1Nair6xE6vEc91r2yEisWVm0TpxI56RJ6OLiMBqNhIaGBgcqsdxGGG7O1bHhVA2X8xyqHA4He/bsob6+PpjT5GT5fD5aW1vR6XRMnDixz+o0QRiMscFoNPLMM89wyy239EslnJMhxsChx2q1kpOTQ09PDyaTCYB9+/aRk5NDd3c3Ho+Hnp4e9Ho9F154IZMmTUIqleL3+2ltbUWj0TBp0iQxJg5zZ0X28j179vTJDN67R/rGG29k7dq1PPDAAzgcDu68887gkqBNmzb1KS7+/PPPI5fLueGGG4JLgtauXdvnzuQ777zDPffcE8xyPn/+fF588cXg8zKZjE8++YQ777yTWbNmodFoWLhwIX/6059O/X/hHCORSFAqlSiVSgwGQ5/nPB4Pdrudzs5OOjo6KGlpOTLIdHdjqK7GUlWFqaKCsNJSdJWV6Jua0Dc1MXLLFgISCe3JydRPmsTBqVNxjRpFiF5PZGQk4eHhGI1G1Gr1IJ21IAiC0Mvj8bB3717q6uowm83ITzGPh0wmIyIigra2NnJycpg8eXKfaiCCcKb4fD7++c9/0t3dzYwZM/qtEs6J/OgqNsJZra2tjdzcXBwOB2azmerqaj799FMKCwvR6XR0dXXR3d2NQqGgqamJ4uJi0tLSuOGGG0hISMBsNgdfY+rUqVgsFvx+P9XV1djtdvR6PfHx8T96VaswPP2oOt3nuuFwhzMQCNDd3U17ezttbW00NTXR1dWFx+NB4/Uy4vBhLAcPYszNRXc0w3yv7pgYaqdPp3zmTLri41Gr1URERBAZGYnZbCYkJETMggtD0nAYG2D4nOdQEwgEOHDgAMXFxRiNRhQKxY96rba2NlQqFdOmTSMiIqIfeyqcq87E2HDo0CFmzJiB0+kkJCSEdevWccUVV7Bjxw5mzZpFXV1dnxtBt99+O1VVVWzcuJF169Zx88039wmgAS655BKSkpKCqySP9fjjj5+wio0YA8993d3d7Nixg46OjmDAvXHjRqqqqjAYDEdWg3Z3Ex8fT0JCAnq9nqqqKqqqqjAajVx//fUkJCQQCARobW1Fr9djMpn44osvqKmpob29Hb/fT3x8PIsWLeqTX0AYes6KmW7h3CKRSAgJCSEkJIS4uDj8fj8dHR20tLRQV1dHtVZLaVoaqkWLMDmdWPbuxfzNNxj37EFXX0/av/5F2r/+RWdqKjUXXsjhqVOprq5GpVJhNBoZMWIEFouFkJCQwT5VQRCEYaG2tpaysjJCQ0N/VMANR/5GGI1GWlpa2Lt3LzNmzBDBh3BGpKWlsX//fjo6Ovjggw+48cYb2bZtW/D5/qiEc6wfVcVGOGt5vV4OHDhAW1sbERERBAIBdu3ahUQiIVKnY2ptLZm1tWT6/WgbGrDn5dFsNlMZFsbmkBAOd3ayc+dO4uLikEqlmEwm9u3bR25uLnq9np6eHpxOJy6Xix07drB7927uu+8+5s2bN9inLpxDRNA9zEilUoxGI0ajkZSUFGw2G01NTVRXV2P1+WicMoWQiy4iJBDAtHs3kZ9/jnH3bkJLSsgoKSF9zRqaZs+m/IoraPB4qK+vR61WExkZSWxsLJGRkT/6IlAQBEE4se7ubvLz85FIJP1Wc1sikWA2m7Farezbt48ZM2ac0v5wQTgdSqUymEht8uTJ5OTk8Oc//zm4j/vHVsI5kR9VxUY4KwUCAYqKiqipqcFoNCKVSqmvr6ehpoZFra3M3bOHsG+V7QWwNDczsrKS6cANwCfh4TzX1MS+lBQmTZpEIBAIVoNob28nMjKS8ePHI5VKaW1tJS8vjxdeeIGkpCQx4y2cNLEpYRiTSCSEhYWRlpbG7NmzOe+880hMTMTj8VBvt1M2eTKHnnqKnf/7v5QuWYJ91CikHg/RGzcy6957ufh3vyO9tBSFXE5NTQ07d+5k69atFBUV0dXVNdinJwhnrcTERCQSyXHHXXfdBcBNN9103HPTp0/v8xoul4slS5ZgNpvR6XTMnz+f2trawTgd4QwJBAIUFBTQ0dHRJ9DoDxKJBJPJFKwmMox3ngmDJBAI4HK5+lTC6dVbCac3oP52JZxevT+73xd0C0NPfX09JSUlhISEoFAoqKqqIu/113nyiy+4ftcuwrxeapRK3o6L452f/5yVc+bwSHQ0744YQbHRiBS4qr2d9WVlON99l6qqKqxWK7W1tTQ1NSGRSJDJZGzbto2NGzdy6NAh/H4/NTU1PP7445SXl+P3+wf7v0E4B4iZbgE4klQnKiqKqKgoOjs7qampobKyEqvVikajwX3NNdRdcw2hBQWMWL+eiG3bMBQUMPaxx0geOZLK//f/aJoxA3t3N/v376ekpIS4uDgSEhIIDw8Xe78F4VtycnLw+XzBz/Py8rj44ov56U9/GnzssssuY82aNcHPj515FOVyhp+6ujqqq6sJCwsbkDFVLpcTFhZGeXk54eHhJCUl9ft7CALAww8/zOWXX05cXBx2u5333nuPL7/8ks8++wyJRMLSpUtZsWIFKSkpwUo4Wq2WhQsXAmAwGLj11ltZtmwZJpMpWAknKyuLuXPnDvLZCWdKd3d38CahTqejqqoKyerVrMjNPfK8QsEzkZG8p1JhMJlIlcvJrqkhPiMD78SJFCiVRFRWcvWnn5LQ2sojubl8/fTTbPvpT6mqqiI0NBSz2Ux5eTlms5nY2NjgaiOAvXv38uCDDzJ16lTmzZtHenr6YP53CGc5kUhNJBH6Tj09PVRVVVFeXk5XV1ewlrdEIkHZ1saIDz5gxPr1yB0OALqSkym74w7aJk+mx+Ggq6sLlUpFTEwMycnJmEwmEXwL54QzPTYsXbqUDRs2UFpaikQi4aabbqKjo4MPP/zwhO1FuZzhx+VysX37djo7O4NlcAZKR0cHcrmc888//7gKGcLwMNBjw6233srnn39OQ0MDBoOBsWPH8uCDD3LxxRcDR2a9n3jiCV555ZVgJZy//vWvZGZmBl/D6XTy29/+lnXr1gUr4bz00kuntEdbjIHnrkAgQE5ODhUVFcEEkE2/+x2/+PprAP6l0fCPrCzUycns3r0buVyOVCpFpVJx0UUXodfrkUgk+Hw+WurruWzHDq4uKUEKHDKbucVsRm02o9Vq0ev1jB07lrKyMrKzs4mIiMBisQBHtm1GR0ejVCq55ZZbROA9RAzE2CCCbjHY/qCenh7KysqoqKjA4XAQFhYW3BMlt9mI/eADYv/1L+Td3QC0TZrE4bvvpjshAafTid1uR6FQEBMTw6hRozAajSL4Fs5qZ3JscLvdxMTEcN999/Hwww8DR5aXf/jhhyiVSsLCwrjgggv4wx/+EPwjv3XrVubMmUNbW1ufZcbjxo1jwYIFJ8zOeyJiDDx35Ofnk5eXR0RExICXqwkEAlitVkaMGMGMGTPEyolhaLiMDcPlPIei2tpadu3ahV6vR6VSoV63jumvvQbAy6GhrE1LQ65QEBkZic/nIzc3F6/XS0xMDLNnz0alUmG1WiktLcXj8aBQKBjX0MAfSksJCQTYERLCr6Ki0JtMTJ8+HafTyRdffEF8fDzjx49HpVLR1NREa2srCoUCuVxOQkICv//970+5hKNw9hHZy4VBodVqycrKIj4+Ppisoquri/DwcLwGA5W33ELt9deT8PbbjPjwQ4y5uUy+7TZqfvYzqhYvRmOx4HQ6qayspKGhgfj4eFJSUvrUbheE4erDDz+ko6ODm266KfjY5Zdfzk9/+lMSEhKoqKjgscceY/bs2eTm5qJSqWhsbESpVB63rzcyMpLGxsbvfC9Ro/bc1NHRQVlZGTqd7ozUh+3NaF5fX095eTkpKSkD/p6CIAgny+12U1BQgEQiQaVS4f7Pfzj/738H4K2ICF6yWJgzcyYej4fS0lKcTicGg4G2tjZcLheNjY34/X4qKiqIjIxk1KhR+Hw+Dspk/LS5mQ86OpjZ1cVTdXX8t1KJWq1m7969qFQqMjIysNvtHDhwgPb2djo6OpBKpcjlcgoLCwFYvHixmPEWjiOCbuGkGQwGpk6dyogRIygoKKC5uZnQ0FA0Gg3e0FDK7ryTumuuYdSLL2LesYOEdeuI2LaNoocegsxMVCoVDoeD0tJS6urqGDVqFMnJySKTqDCsvf7661x++eV96tH2LhkHyMzMZPLkySQkJPDJJ59w7bXXfudr/VC5nJUrV570LLhwdvD7/RQWFuJwOIIrHc4EhUKBWq2mqKgIi8UilpkLgnDWKC8vp729HbPZTPvu3VzywgvIAgE+Cg3l+ZgYQnU6QkJCkEqlmM1m2trasFqtHD58GJlMRnNzM4FAgLi4OGJiYigqKqKpqYmWlha8Oh336nT8rb6eaxwOGmpr+fjAATo6OtBqtXR1dVFcXIxKpUKpVJKZmUlcXBwOh4Pm5masVitvvPGGWGouHEdkLxdOiUQiITY2lp/85CekpKTQ09NDe3t7MNOtMzqavD/8gUNPPokzIgJtXR0T7rmH5L/9DZnHg1arDV44Hjx4kO3bt1NbWysy5QrDUlVVFVu2bOG222773nbR0dEkJCRQWloK9C2X823fLqlzIsuXL8dmswWPmpqaH38SwoCqr6+nrq5uwJKnfZ/e+rQFBQUiO68gCGcFu91OaWkpGo0GeXc3M1euROfxUGAw8ExqKm6PB7lcTk9PT3DMNJvNxMTEYDAYUCgU1NfXY7VaUavVHDx4EKVSicfjITw8HLPZzMGYGJ7PygLgzs5O0ouL8fv9BAIBCgsLMZlMKBQKoqKiGDduHNHR0ZjNZlQqFTKZDKfTyccffyzGTaEPEXQLp0WtVjNhwgSmTJkS3Bfj/VYdxNbzzmPPG2/QcNllSAIB4t9/n0m3346uvByJRIJer8dsNtPZ2cmuXbvIzs7GbrcP4hkJwpm3Zs0aLBYLV1555fe2a21tpaamJliz9nTL5ahUKkJDQ/scwtnL4/FQVFQUXEJ5pkkkEsLDw6mrqxPl6ARBGHSBQIDS0lJ6enrQh4SQtGIFkTYbLRoNvx05ksiEBDweDz09PVRUVABHxtHu7m7cbjfJycm0tbUFx9OSkhJUKhUdHR20tbVhMplQq9VkZGSwXqfj30crODxRXc0IpxOXy4XNZsNoNNLT00N8fDxer5fy8nK++eYbamtr2bt3L/v37+eDDz5gy5Ytg/Z/JZx9RNAtnDaJREJ8fDyzZs0iKiqK1tZWnE5n8HlvSAjFDz7Ioaeewh0ejq6qiol33knUZ58BR8qUmUwm9Ho9lZWVfPXVV6LeoTBs+P1+1qxZw4033tgn6UpXVxf3338/O3fupLKyki+//JKrrroKs9nMNddcA/Qtl/P555+zb98+Fi1aJMrlDDGVlZW0trYSFhY2aH1QKpVIpVKKior6jO+CIAhnWmtrK1VVVej1emL//W/id+/GI5Hw5/PPx67TkZCQQFRUFHBkJVl2djYNDQ24XC68Xi/Nzc2Eh4czYcKEYOZyvV5PaWkpoaGhpKamolKpMBgMjBkzhhfj4zmo16P3+Xi2shJfVxdOp5O2tjYcDgednZ3k5+ezZ88efD7fkeo+SiUymYzu7m7++7//mw0bNgzy/5pwthBBt/CjGQwGZsyYwahRo7Db7cfNWLfOmkXOmjW0TZmCzOVi9NNPk7ZqFdKjCZ1UKhUWiwW3201ubi7Z2dl0dXUNxqkIwhmzZcsWqqurueWWW/o8LpPJOHToEFdffTWpqanceOONpKamsnPnzj7JB59//nkWLFjADTfcwKxZs9BqtXz88cci0/QQ0Zv/Qq1WD/r3NCwsjPb2dsrKyga1H4IgDA9+v5/KykoOHTpEZWUlfr8fv99PUVERHo+HiJoakl96CYBVJhPVRwPtkpIS0tPT0el06PV62tvbKSoqIjs7O7ii8uGHH+bll19m0qRJyOVyOjo6MBgMhIWFoTyaNK26upro6GgmTZ/OuquvxqZSkenz8buWFqRSaXBmvHeLpdFoRKFQEBERwdixYxk3bhxjx45Fr9fzwgsvBOt6C8ObKBkmSkX0G7/fT2lpKQUFBQDH70H0+0l45x0S16xBEgjQNXIk+Y8/jiM2Ntikd5+qwWAgMzOTESNGiPJiwhk3XMaG4XKe56L8/HwOHTqExWI5IxnLf4jdbicQCPCTn/xkUGfehTNjuIwNw+U8zyWFhYVs2LCB2tpavF4vcrmc2NhYJk2aRFtbGwatlsl33EF4bS2btFoey8ggNi6OqKgoDh06RHh4OFqtltbWVpqbm3G5XCiVSqZNm8Y999xDRkYGcOTG90MPPYTH4yE0NJSQkBBCQkIwm80UFBRgNpsZMWIEKpUKfXY2j27fjhR4KDGRD4/u3Y6OjsbtdiOXyzGbzZjNZkpLS3E4HMjlclQqFfX19cycOZOXX375rBjLhZMzEGOD+O4L/UYqlZKamsrkyZNRKBS0trb2TZAmlVK1eDEHnnkGd3g4IWVlTLrjDkw7dgSbKJVKLBYLPT097N69m4MHD+LxeAbhbARBEAaH3W6nvLz8jJUIOxkhISE4HA5KSkpE4ktBEAZEYWEhb7zxBna7nfPOO48FCxZw3nnnYbPZeO2116irqyN5/XrCa2tpk8l4OiWFadOn09HRQXNzM8nJyXR3d1NWVobVaqW9vZ3U1FT+9Kc/8fLLLwcDboDZs2eTmZkZzEcUERGB1WqlubmZpKQkbDYbOTk5fPbZZ7xRVcU/U1MB+O/mZiKlUtLS0oIz3h6PB41GQ15eHjqdjrFjxzJnzhymTZtGfHw8OTk5bN26dVD+T4Wzx9nx11wYMiQSCXFxcUydOhWdTkdzc/Nxe7Q7Jk1iz6uv0pGVhbynh6xHHiHhrbfgaLveGrEajYaioiJ27NiBzWYbjNMRBEE448rLy+np6SEkJGSwuxIkkUgwGAzU1NTQ1NQ02N0RBGGI8fv9bNiwAY1Gw0UXXURERERwyfb48eNRq9W07N5NwptvAvCXhATcej1arZZx48bR3d1NdXU1Pp8vmGl89OjRPPfcc8ydO/e4G5hSqZRFixYFyyE6nU4mT56My+WioqICp9OJz+ejq6uLUaNGYX7hBbqSk9F2d/NkRweJiYlER0cHt1VWVFQQHh5OZmYmRqMRlUpFSEgIY8eOJTIyks8++0zkLBrmRNAtDAiLxcL06dMJCws7YeDtNps58Nxz1C1YAEDSmjVkPP44sp6eYButVovJZKKxsZFvvvmGmpoaMcMiCMKQZrPZqKysJCQk5KzbWqNWq/H7/RQXF+Pz+Qa7O4IgDCHV1dXU1taSlZXVZ+zzeDy0trZiNpmY9+mnyD0edmq1/MdoDCZ5DA0NZfr06UyfPp3JkyczZcoUoqKiyMzMJDEx8Tvfc/bs2cyaNYuQkBDq6+spKysjMTGR8ePHM27cOHQ6HWFhYfziF79AptFQ9OCD+KVSftLQwAVtbcydO5fExETcbjd+v5+0tDQ0Gg1SqRSJREJPTw9SqZTExETa29uprq4+A/+TwtlKBN3CgAkPD2fq1KmEh4fT0tJyXOAdkMspvfdeiu+/H79CQcRXXzHhnntQtrQE28jlciwWC06nk5ycHAoKCvqUJhMEQRhKysvLcTgcaLXawe7KCYWFhWG1WqmrqxvsrgiCMITY7Xa8Xu9xOSMOHTrExo0b0W3YwLSODlwSCb+Pjsbr8xEREUFTUxO5ubk0NzcTEhKCQqGgpqaG1tZWLrvssu/doiOVSrnlllvIyMhg1KhRSKVSqqurKS8vJy8vj0AgwE9/+lNCQkLw+/10paZS/YtfAHD+//4vRpWKiy66CJfLRWdnJ2q1GrfbTSAQoK6ujoaGBtra2oiMjESlUonSuMNcvwfdXq+XRx99lKSkJDQaDcnJyfz+97/vE3AFAgEef/xxYmJi0Gg0XHjhhcdl9nO5XCxZsgSz2YxOp2P+/PnH1Qltb29n8eLFGAwGDAYDixcvpqOjo79PSfgRwsLCmDZtGmFhYbS0tJxwprrhyivZ//zzwX3eE+++G+237gb2LjdXqVTk5eWRnZ1Nd3f3mTwNQRCEAWez2aiurkav1591s9y9FAoFUqmU4uJikW9DEIR+o9frkcvltLe309HRQVNTE3v37mXz5s3ovV7uKS8HYOOUKRT7/XR3d+Pz+Zg4cSJOp5O9e/eyceNGtm/fTn19PRdccAGzZ8/+wfdNT0/n1ltvJSMjg9jYWEJDQwkNDWXWrFn89a9/5e677yYsLIy2tjYCgQDVixdjN5sxdndjfO019Ho9U6ZMwW63U1BQQElJCd988w179+6loKCA/Px88vLysNvtfSqQCMOP/IebnJqnn36av/3tb7z55ptkZGSwZ88ebr75ZgwGA/feey8Aq1at4rnnnmPt2rWkpqby1FNPcfHFF1NcXBz8gVy6dCkff/wx7733HiaTiWXLljFv3jxyc3OD5VMWLlxIbW0tnx2t+3z77bezePFiPv744/4+LeFHMBgMTJkyhezsbJqbm4mIiDjugrIzI4O9L77I2AcfRFtby4QlSzj01FN0ZmUF2+h0OpRKJTU1NXR1dTF27NhgPUZBEIRzXXl5OU6nE4vFMthd+V5hYWHBermjRo0a7O4IgjAExMfHo1Qq+eCDD0hMTMTn87F582Z0Oh13Njdj9HioCw3lL0olI0eOpK2tjcOHDwOQlZVFZ2cnDQ0NtLa2Mn78eG677baTTkSZnp5OWloa1dXVweA4Pj4++PUTJkxg165dwYzWVUuWkPm733HxgQN8Gh2NW6lEqVRSUVGBTCYjKiqKxMREwsPDUSgU7Nu3j8bGRjFhNMz1+0z3zp07ufrqq7nyyitJTEzk+uuv55JLLmHPnj3AkVnuF154gUceeYRrr72WzMxM3nzzTXp6eli3bh1w5G7/66+/zrPPPsvcuXOZMGECb7/9NocOHWLLli3AkQyHn332GX//+9+ZMWMGM2bM4LXXXmPDhg0UFxf392kJP1J4eDiTJ08mJCTk+KzmRzljYtj34ot0pqej6Oxk3P33Y9q5s0+b3qQanZ2d7Nq1i5KSEpGYQhCEc17vLPfZuJf7WDKZDKVSSWlpKU6nc7C7IwjCEFBcXExrayuNjY2Ulpby1Vdf0d7ezsSQEC4vKwPg1TFjaOvuZsSIEYwZMwa1Wk1RUREbN27km2++oba2Fr/fz8KFC0lPTz+l9+/de52VlUViYmKfgN1isZCRkYHb7cbpdNJy/vm0T5iA0ufjgZYW5s2bxw033EAgECAqKopZs2aRkpKCVCqltraWyMhIxowZw6effiquWYexfg+6zzvvPD7//HNKSkoAOHDgAF9//TVXXHEFABUVFTQ2NnLJJZcEv0alUnHBBRew42jpqNzcXDweT582MTExZGZmBtvs3LkTg8HAtGnTgm2mT5+OwWAIthHOLiaTiUmTJqFUKr9zG4DHYGD/c8/RMmMGMrebjMceI+KLL/q0kUqlmEwmpFIpBw4cYP/+/WKZoyAI57TKykqcTudZu5f7WKGhoXR2dlJRUTHYXREE4RzXm7k8NjaWSy+9lNraWqxWK6GhodxWVIQ8EOBLnY4dISHIZDJCQkIwGAxMnDiRK664ggsuuICsrCxuu+02Jk+eTGRkZL/3MSkpiaSkJDo6OvAHAhy++24CUinxu3czsbOTtLQ0TCYTiYmJlJaWsn79erZs2UJJSQl1dXW0t7dz4MABkUxtGOv3oPvBBx/kF7/4BaNHj0ahUDBhwgSWLl3KL44mHmhsbAQ47hciMjIy+FxjYyNKpZLw8PDvbXOiJXgWiyXY5li9iQ6+fQhnVmRkJBMmTAD4zoQSfrWa/N//nqY5c5D6fIx56imiPv20TxuJREJoaCh6vZ7S0lJ2794tlu0IgnBOstvtVFVVodPpzvpZ7l5SqRSNRkNZWZkYewVB+FF6M5ePGTOG0tJSYmNjsVgszPb5GF9Tg1ciYaXZTE9PD2q1GqVSicFgQKvV4vV6CQ0NZfz48VgsFhQKxYDsnZZKpWRmZmI2m2lra6M7OZn6q64CYNTq1XiOJsDs3f+dkJDAFVdcwS9+8QsuuOAC1Go1paWlHDhwoN/7Jpwb+j3ofv/993n77bdZt24de/fu5c033+RPf/oTbx6tq9fr2AuLQCDwgxcbx7Y5Ufvve52VK1cGk64ZDAbi4uJO9rSEfhQbG0tGRgYulwuHw3HCNgG5nMLly6m/8kokfj+jV61ixPr1x7VTq9UYjUbq6urYuXMnbW1tA919QRCEflVZWUlPTw86nW6wu3JK9Ho9XV1dlB9NcCQIgnA67HY7ra2tbN++naKiImQyGQqZjLtragD4MCYGf0oKcrkcu91OWVkZgUAApVIZ3Ms9cuRI8vPziYuLIz4+fkD6qVarycrKQiaT0d3dTcXNN+PR6wkpLydz1y6USiU5OTmEhYXxk5/8hOjoaBQKBUajkbFjxxIREUF2drZYYj5M9XvQ/dvf/paHHnqIn//852RlZbF48WJ+85vfsHLlSoBg4qtjZ6OtVmtw9jsqKgq32017e/v3tmlqajru/Zubm79zWcny5cux2WzBo+boL7NwZkkkElJSUkhJSaGzsxO3233ihjIZJcuWUXP99QCk/OUvxB/d9/9tvfu829ra2LlzpyhlIwjCOaO7u5vKyspzapa7l0QiISQkhIqKCrFyTBCE05adnc3evXupqqoKbiGc3dZGanc3dqmUVywW0tPTyczMRKPRkJ+fz/bt26moqMDtduPz+cjOzsbhcHDllVeedAK102GxWEhNTaWrqwunTkflzTcDMO5//5cwoKWlhZiYmOOqNjU3N5Oeno7dbhdLzIepfv+p7C0E/20ymSz4w5eUlERUVBSbN28OPu92u9m2bRszZ84EYNKkSSgUij5tGhoayMvLC7aZMWMGNpuN7OzsYJvdu3djs9mCbY6lUqmCpQB6D2FwSCQSMjIyiI+Pp62tDZ/P910NKbvzTioXLwYg+bXXiHv33eOaSaVSIiIicLlcZGdnU1xcLO4kCoJw1quqqqKnp4eQkJDB7spp0el0OBwOyo4mOhIEQTgV+fn5vP322yiVSmQyGSqVCp1Kxa+OToytNZlo5UjgqlAomDJlCmPHjsXv92O1WqmsrKSoqAiJRMItt9xyygnUTpVEIiE1NZXIyEja29upu+oqupKSUHZ28qujidxsNhutra34fL4jM+IVFbS0tGA0Gmlvb8dmsw1oH4WzU7+XDLvqqqv4wx/+QHx8PBkZGezbt4/nnnuOW265BTjyw7p06VJWrFgRnO1csWIFWq2WhQsXAkdKTN16660sW7YMk8mE0Wjk/vvvJysri7lz5wJH0vtfdtll/OpXv+KVV14BjpQMmzdvHmlpaf19WsIAkMvljB8/HofDQUtLywlLiQEgkVB5yy34lUqSX3+dka++il+lou7aa49pdqSet91u5+DBg/T09JCVlYVc3u8/5oIgCD+aw+GgsrISjUZzzs1y9+qd7a6uriYpKYmwsLDB7pIgCOcIv9/P22+/jd/v55JLLiEvL4+Ojg6Stm8nrqeHdrmcN0JDcbtcwJGVjX6/n4yMDC666CIOHz5MZ2cngUCAO++8k+Tk5DPSb4VCQWZmJt988w1dTieH77qL8fffz+ScHCafdx5Op5OKigqampqw2WyUl5cjlUopLS3Fbrfz/vvvo1QqB/wGgXB26feZ7tWrV3P99ddz5513kp6ezv33388dd9zBk08+GWzzwAMPsHTpUu68804mT55MXV0dmzZt6pP44Pnnn2fBggXccMMNzJo1C61Wy8cffxys0Q3wzjvvkJWVxSWXXMIll1zC2LFj+cc//tHfpyQMII1Gw4QJEwgJCTluO8GxqhctCs54p6xeTfQnn5ywnV6vJyQkhJKSEnJycr5z37ggCMJgqqmpwW63n7Oz3L20Wi1Op5PDhw+fsBykIAjCiVRXV1NdXY3BYCA1NZUJEyZgDgnh2rw8AP5n5EhcSiVWq5V9+/Zht9vRaDSEhobS0tKCTqfDYDCQmZlJYmLiGe272WwmJSWF7u5uWsePp2XmTKQ+H3dVViKVSklISKCnp4f9+/cjl8sZMWIEkZGRJCcn093dzRtvvEFhYeEZ7bMwuCSBYfwXsrfIvc1mE0vNB1ltbS3Z2dlHlhV9XzKhQICRf/sbcf/zPwQkEoqWL6fp4otP2NTj8dDa2kpkZCSTJk0S32PhpA2XsWG4nOfZyO12s3XrVpxO55CYHXY4HDidTn7yk59gMpkGuzvCjzRcxobhcp5nG7/fT3V1Nbm5ubz77rtIJBKmTJmCVCpl4vbtzP74Y6wqFQsnT6bd4aC+vh6lUklqairJycno9XqkUilutxuFQnFGlpWfiMfj4auvvqKtrY04h4MpN9+M1Odj5UUXsSc8nPz8fJKTk5k2bRo+nw+Xy4VEIkEqldLT00NsbCz33XffgO5BF07PQIwN4rssnBVGjBjB6NGj6e7u/u7EanBkj/evf03d/PlIAgFG//GPRGzbdsKmvQnWrFYrO3bsOGHiPUEQhMFQW1tLZ2fnkLnQV6vVuN1uMdstnJSVK1cyZcoU9Ho9FouFBQsWUFxc3KdNIBDg8ccfJyYmBo1Gw4UXXkh+fn6fNi6XiyVLlmA2m9HpdMyfP5/a2tozeSrCKSosLOTZZ5/lueee4+2336asrAyr1cr+/fuR9fQw/YsvANg/fz7jp09HoVAwadIk3n33XaZMmRLckuh0OomNjR20gBuOXGeOGTMGqVRKm9lM3TXXAPDrkhJqKiqQSCQkJibi8XiQyWTodDp0Oh3d3d0oFIrgTL8wPIjNrsJZQSKRkJaWhs1mo6qqCovF8t13/iQSSu+9F6nbTfRnn5H+5JP4lUpaZ8w4rqlMJsNisdDa2squXbvIzMwkOTn5nN0/KQjCuc/r9VJWVoZcLh8yMxwSiQSDwUBdXR3Nzc1YLJbB7pJwFtu2bRt33XUXU6ZMwev18sgjj3DJJZdQUFAQXO22atUqnnvuOdauXUtqaipPPfUUF198McXFxcHtiEuXLuXjjz/mvffew2QysWzZMubNm0dubm6f7YjC2aGwsJA33niDrq4uuru7kUqlOBwOfD4fbW1tzNu3D21XF21mMztSUynctw+3283tt9/OzJkzmT59OtXV1djtdvR6PfHx8YM+hkZGRpKYmEhpaSmVixcTtWkT4XV1LAoN5QOLBYvFgs/no7CwELvdTiAQwOfz4Xa7MRgM2O32Qe2/cOYMjb/2wpAgk8kYN24cRqORtra2758tkUopvv9+mmbPRurzkfG73xG+Z88Jm0okkuByx3379nHw4EG8Xu9AnIIgCMIPqquro6OjA4PBMNhd6VdqtRqv1ytmu4Uf9Nlnn3HTTTeRkZHBuHHjWLNmTXC5MRyZ5X7hhRd45JFHuPbaa8nMzOTNN9+kp6eHdUdLh9psNl5//XWeffZZ5s6dy4QJE3j77bc5dOgQW7ZsGczTE07A7/ezYcMGurq6sNlsuFwu2tvb8Xq9tLW1EerxcFVJCQB/MZv5dPNm6uvrueaaa7j00kuBI5VqEhMTycrKIjExcdADbvi/SSO9Xk9bIEDlTTcBcOPhw0QoldTX15OTk4NSqWTKlCnMnj2badOmodVqqa6uFqswh5HB/2kVhG/RarWMHz8ehUJBV1fX9zeWyShavpzm889H6vGQ+eijGPbvP2HT3lkYrVZLUVGRSLAmCMKg8Pl8wUy2Q3EmzmAw0NDQIC4khVPSW0LJaDQCUFFRQWNjI5dcckmwjUql4oILLmDHjh0A5Obm4vF4+rSJiYkhMzMz2OZYLpeLzs7OPodwZlRXV1NTU0N3dzc+n4+mpiY6OjoYN24cc+bM4W6HA73fT4FSyTqPB4vFwqJFi/h//+//oVKpBrv730un05GamorT6aT68suxxcRg8HhYWFHBvn37MBgMjBs3jrCwMORyOSEhIYwYMYKEhAT27t0rStwOEyLoFs46FouF0aNH43A4vn9/NxCQyyl49FFap01D5nIxdvlyQg8d+s72Wq2W8PBwqqqq2LlzJx0dHf3ce0H4YY8//jgSiaTPERUVFXxe7GUcuhobG2lpaRkye7mPpVKp8Pv9lJaWigtJ4aQEAgHuu+8+zjvvPDIzM4EjvydwZOnut0VGRgafa2xsRKlUEh4e/p1tjrVy5UoMBkPwiIuL6+/TEb6D3W6nvb2dnp4eHA4HPT09wYzl4yIiuL6+HoD/nTCB6BEjCAsLY/LkyefM9ygxMZHIyEja7HYq7r4bgKvKyzF3dKDVaunq6sLn89HT00NlZSU+n4+LL76Yuro6sa97mBBBt3BWSklJISEhgfb29h+8cAsoleQ/8QRtkyYhczoZ+9BD6AsKvrO9UqkkIiKC5uZmduzYQf3RgV4QzqSMjAwaGhqCx6Fv3Szq3cv44osvkpOTQ1RUFBdffHGfvV9Lly5l/fr1vPfee3z99dd0dXUxb948fD7fYJyOcBL8fj/l5eVIJBIUCsVgd2fAhIWF0dTUJMZW4aTcfffdHDx4kHffffe4547NvxIIBH4wJ8v3tVm+fDk2my141NTUnH7HhVOi1+vx+/10dHTQ2dmJVqslMTGRQCDAT7ZvR+H1UhUbS8uUKURHR9Pc3IxOpzsrlpCfDLlcTnp6OjKZjIbx46nLzEQRCPDb5makUinV1dUUFRWxd+9e6uvrGTlyJMnJyXi9XrGve5g4N36ShWFHKpWSlZVFeHg4bW1tP9jer1KR99RTtI8fj7ynh3EPPID+mEyo39abYM3hcJCdnU1xcbGYlRHOKLlcTlRUVPCIiIgAxF7GocxqtdLU1DRkZ7l79d5QKC0tFTeBhO+1ZMkSPvroI7744gtiY2ODj/eu/Dl2xtpqtQZnv6OionC73bS3t39nm2OpVCpCQ0P7HMKZER8fT3x8PB0dHTidTuRyORqNhrDWViYc3cu/8YILUKpUqNVqFAoFSqVykHt9aiwWCwkJCdhsNmp/8xv8UimzbTZG1dbS3t5OXl4ezc3N+P1+Dhw4wLp16+js7AwmBhSGNhF0C2ctrVbL2LFjkclkP7y/G/Cr1eStWEFHVhby7m7G/va3hBw+/J3texOsyWQyDh48yP79+39wObsg9JfS0lJiYmJISkri5z//OeXl5cDA7WUUBlcgEKC8vJxAIHDOXUiejrCwMJqbm8WWB+GEAoEAd999N//617/YunUrSUlJfZ5PSkoiKiqKzZs3Bx9zu91s27aNmTNnAjBp0iQUCkWfNg0NDeTl5QXbCGcPqVTKokWLUCgUwURqnZ2d/OSLL5D5/ZQkJ1MeGxvM7h0eHn7O3RT5dlK1RpOJ+nnzAPjZ7t10d3YSHx/P5Zdfzvz585k6dSrd3d00NjbS3d09yD0XzgQRdAtntcjISNLS0ujp6cHj8fxge59Gw6E//hFbRgYKu51xy5ahOxrMfBe9Xo9er6e0tFTs8xbOiGnTpvHWW2+xceNGXnvtNRobG5k5cyatra0DtpcRRBKhwdTS0kJjY+OwmdGQy+XI5XJKSkpOauwWhpe77rqLt99+m3Xr1h0JUBobaWxsDCY4lUgkLF26lBUrVrB+/Xry8vK46aab0Gq1LFy4EDiStO/WW29l2bJlfP755+zbt49FixaRlZXF3LlzB/P0hO+QkZHBgw8+iMfjoampCVdODlkHDwKw8fzz8fv9OJ1OOjs7yczMJD4+fpB7fOpCQkKCSdXK/t//w6XRkGyzcYXVypgxY1AqlcFzTEtLIyMjg08//VSsthwGRNAtnNUkEgmpqanExMT8cBmxo3xaLQf/+Ec6R49G0dnJuGXL0FZWfu/XqNVqTCYTjY2NfPPNN1RXV4uSN8KAufzyy7nuuuuCF4effPIJAG+++WawTX/vZQSRRGiwBAIBKioq8Hq9qNXqwe7OGWMwGGhvb6eqqmqwuyKcZV5++WVsNhsXXngh0dHRweP9998PtnnggQdYunQpd955J5MnT6auro5Nmzb1uXH1/PPPs2DBAm644QZmzZqFVqvl448/HpKVAYaCwsJCSktLSU1NpbOzk2v27EEK7ElKoiwsDKvVSmlpKeHh4Vx11VXnzH7uYyUmJmKxWGgOBCi47joAbjp8GFttLcXFxezfv5/29nZGjBjB9OnTqampEcnUhoFz86dZGFbkcjljx45Fr9ef9Cy0LySEg6tWYU9JQdnRwbhly9D8wIAml8uxWCy43W5ycnI4dOiQmKERzgidTkdWVhalpaUDtpcRRBKhwdLe3k59ff2wmeXuJZPJUCqVHD58GKfTOdjdEc4igUDghMdNR2scw5Ebj48//jgNDQ04nU62bdsWzG7eS61Ws3r1alpbW+np6eHjjz8WNxPPUoWFhbzxxhvY7Xbmz5/P7+bMYY7DgRd40OPh888/59ChQyQkJPDggw+Snp4+2F0+bQqFgtGjRyORSMieOpWGkBAMDgdXFxRQW1tLTU0N9fX1bN++na1bt2K1WkUytWFABN3COSE0NJSMjAx8Pt9JX7x59XoOPPMMXcnJqNraGL9sGZq6uu/9GolEQnh4OBqNhsLCQnbt2hWsHyoIA8XlclFYWEh0dPSA7mUUSYTOvN693C6Xa1jNcvcKDQ3FZrNRUVEx2F0RBGGQ+P1+Pv74Y/x+P6mpqTh6eliwezcAeVOnosrKIioqirvuuou//OUv53TA3SsqKoq4uDjcwNvjxgEwY9cuUpVKJk2axAUXXMC0adPweDxUVlbS1NQ0uB0WBpwIuoVzRnx8PMnJyXR0dJx0RlyvwcCBZ5+lOzERVUsL4+67D3VDww9+nVarxWQyUV9fzzfffENlZaVYbi70m/vvv59t27ZRUVHB7t27uf766+ns7OTGG28UexmHGJvNRm1tLXq9/ge3BwxFUqkUjUZDWVnZSSXEFARh6Nm6dSubNm0KVoxRbt5MdFkZXoWCkp//nNmzZ6PVahk1ahQajWawu9svepOqxcXFUTBqFHsMBpR+P7+urCQ8PByPxxPc5hUfH8/evXvFvu4hTgTdwjlDIpGQkZFBREQEra2tJx0Ee8LC2P/ss3THx6O2Whl3332oTuKOYu9yc5fLxZ49e8jNzQ0meRGEH6O2tpZf/OIXpKWlce2116JUKtm1axcJCQmA2Ms4lPTOcg+VC8nTodfr6e7uprS0dLC7IgjCGZafn88rr7xCT08PcXFxxMXE8NO9ewH4IiuLeokEhUKBQqEgJCRkkHvbvwwGA6mpqYyIjeWZqCj8QNr+/cRWVWG32zl8+DA+n48LL7yQuro6sa97iBNBt3BOUalUjB07FpVKdUqzJh6jkQPPPktPbCyaxkbG33cfqubmH/y63uXmISEhlJWV8dVXX1FTUyNmvYUf5b333qO+vh63201dXR0ffPABY8aMCT4v9jIODb375kNCQoblLHcviURCSEgIVVVVtLW1DXZ3BEE4Q/Lz83nooYdoa2tDKpVSU1ND/NdfY7FacWo0bJ8xg9raWjo7OwkLC8NoNA52l/vdyJEjiYuLoy0ujt1H/47P/J//oamhAZfLRUZGBiNHjsTr9Yp93UOcCLqFc05ERARpaWk4HI5TSnTmNps58NxzOGJi0NTXM+6++1C2tp7U16rVaiIiIrDb7ezevZvs7GxRbkkQhO9VXl6O0+lEq9UOdlcGnVarxeVyUVxcLG5aCsIwUFhYyJ///Gc6Ozu54IILiI6Opr2xkYu//hqAXT/5CZqYGOx2O2VlZaSmpp6TJcJ+iEqlIjMzE51OR+6CBbjVahKam1nQ3U1SUhIymYyOjg7kcvmwS7Y53IigWzgnpaSkEBsbe9JlxHq5IiLY/+yzOCMj0dbWMu6++1Cc5MyLVCrFZDKh1+uprKxk+/btFBUV4Xa7T/c0BEEYomw2G9XV1cN+lruXRCIhLCyMuro6Gk4ir4YgCOcuv9/Phg0bkEgkWCwWoqOjSUlJYVZ+PkabDZtWy5YxY+ju7ubw4cO43e5zukTYD5k2bRqxsbHk1tZy4MorAZi1YQM6oK2tjb179wb3dgtD19D86RaGPJlMRlZW1imVEevliopi//PP47RY0FVXM37ZMhSn8BoqlQqLxYLf7+fAgQNs27aNqqqqk07uJgjC0CdmuY+nUqkAKC4uxuv1DnJvBEEYKNXV1dTW1jJ27FikUiltbW2ESiTceLRM5euxsXy+cyfbt2+ns7OTm2++eUhkLP8ucrmcX/7yl9jtdt7Q67GFh6Pr6CDhf/6HjRs3UlJSwmWXXTZkbzoIRwzId7euro5FixZhMpnQarWMHz+e3Nzc4POBQIDHH3+cmJgYNBoNF154Ifn5+X1ew+VysWTJEsxmMzqdjvnz51NbW9unTXt7O4sXL8ZgMGAwGFi8ePEpB2DCuUuv15OZmXlKZcR6OaOjOfDcc7jMZnSVlYz/zW9QnsQe714SiYTQ0FDMZjN2u53s7Gy2b99OTU2NCL4FYZjr6OgQs9zfISwsjObmZqqqqga7K4IgDBC73Y7X62XUqFFIJBK2bt3K6E8/Re9w0BQaysHJk4mMjCQsLIx58+YxZ86cwe7ygJsxYwaLFi2iy+tl9dEZ7ZnffENPSQkNDQ28+uqrx8VCwtDS70F3e3s7s2bNQqFQ8Omnn1JQUMCzzz5LWFhYsM2qVat47rnnePHFF8nJySEqKoqLL764TwKBpUuXsn79et577z2+/vprurq6mDdvXp+AZuHChezfv5/PPvuMzz77jP3797N48eL+PiXhLBYXF0dycjI2m+2Ug13HiBHs/1bgPXHJEjRH78KeLJlMhtFoJDw8nNbWVnbt2sW2bduorKw8pf3mgiAMDb11ucUs94nJ5XKUSiUlJSX09PQMdncEQRgAer0euVxOfn4+VqsVf00Nlx48CMAXc+YQkMtpaGjA7/dzww03DJsZ3ksvvZRZs2axIzqafKMRTSDA8o4O1Go1u3fv5u6772bDhg2D3U1hgPT7T/nTTz9NXFwca9asYerUqSQmJjJnzhxGjhwJHLkgeeGFF3jkkUe49tpryczM5M0336Snp4d169YBR/bCvf766zz77LPMnTuXCRMm8Pbbb3Po0CG2bNkCHEnQ8Nlnn/H3v/+dGTNmMGPGDF577TU2bNhAcXFxf5+WcJaSSCSMGTMGk8l0yvu7ARxxcexbvZqe2FjUTU1MWLIE/Wn8/MjlcsxmM+Hh4bS3t5Odnc3WrVvFhaUgDDO9s9zDtS73yQgNDcVms4kSYoIwRMXHx6NQKPjHP/6BVqvlCZcLjc9Hnl7Pa+3tlJaW0tXVRUpKCmlpaYPd3TNGpVJRVVWFSq3m1fR0/MBFDQ3cPno0c+bMITQ0lD//+c9ixnuI6veg+6OPPmLy5Mn89Kc/xWKxMGHCBF577bXg8xUVFTQ2NnLJJZcEH1OpVFxwwQXs2LEDgNzcXDweT582MTExZGZmBtvs3LkTg8HAtGnTgm2mT5+OwWAItjmWy+Wis7OzzyGc+9RqNWPHjkWhUNDd3X3KX++MimLfX/6CPTUVpc3GuN/8BuOuXafVF7lcjslkwmQy4XA42LdvH59//jn79u2jpaUFv99/Wq8rCMLZLxAIUFpaOuzrcv8QqVSKXq+noqJClBAThCGouLiYqqoquru7mer3M7O8HD/w4UUXERoWRmxsLIsXLyYQCAyr2tTV1dV0dXURCARojo/n0IwZAMz9978xGQxMnjwZlUrFunXrxPXiENTvQXd5eTkvv/wyKSkpbNy4kV//+tfcc889vPXWWwA0NjYCEBkZ2efrIiMjg881NjaiVCoJDw//3jYWi+W497dYLME2x1q5cmVw/7fBYBA1bYcQi8VCWloa3d3dp7Ws2xMezv7nn6d94kTkDgdZDz9M3LvvwmmWtpHJZISFhWGxWJBIJJSUlLBt2za2b99OWVnZad0cEATh7NbS0kJdXR2hoaFilvsHaLVa3G43RUVF4uJSEIaQ3szlYWFhxMbE8P/27AFgR2oq1ZGR6HQ6LBYL48aNG3a1qe12Ox0dHUilUpKTk/n6sstwaLVENDQwauNG7HY7JpOJmpqaYXUzYrjo96Db7/czceJEVqxYwYQJE7jjjjv41a9+xcsvv9yn3bEXJIFA4AcvUo5tc6L23/c6y5cvx2azBY+aU9y/K5zdUlJSGDFixGktMwfwabUc/OMfqZ83D0kgwMhXXyX9D39A6nKddp8kEgkhISFERkai1+tpbW1lz549fP7552RnZ1NbWytKjgnCEBAIBCgpKcHj8YhZ7pPQW0Ksvr6eurq6we6OIAj9pDdzeUJCApc3NZHY3IxTpWLX/PnEx8eTkpKCSqWirq5u2NWm1uv1+P1+vF4vZrOZcpuNNSkpAMzdvp3yr7+mtLSU1tbWYXUzYrjo96A7OjqaMWPG9HksPT09eMcmKioK4LjZaKvVGpz9joqKwu12097e/r1tmpqajnv/5ubm42bRe6lUKkJDQ/scwtAhl8sZO3bsaZUR6xVQKCi57z5K7r0Xv0xG5OefM2HJEtT19T+6f0qlEpPJhMViQSaTUVlZyc6dO9m8eTO5ubnU1taechZ2QRDODg0NDTQ0NGAwGAa7K+cMpVKJRCKhsLAQ14+4uSkIwtnDbrdjtVrprKnh1rIyADZPn06bQkEgECA0NBSpVMqhQ4eGXW3q+Ph44uPjsdls1NbWcujQIbanpFATHY3O5+PRpiYMBgO1tbXiZuQQ1O9B96xZs45LZFZSUkJCQgIASUlJREVFsXnz5uDzbrebbdu2MXPmTAAmTZqEQqHo06ahoYG8vLxgmxkzZmCz2cjOzg622b17NzabLdhGGH5CQ0PJzMzE7/fjcDhO70UkEuoXLODgn/6EJzQUfWkpk2+/nYht2/qljxKJJLi8ymg04vf7KSsrY8eOHWzevJmdO3dSVlZGW1ubKD8mCOcAr9dLSUkJ8H+1qIWT05t88vDhw4PdFUEQ+kFjYyMlJSXM2bEDo8dDjVbLOrOZzs5O2traaGpqoqioCJfLxZVXXjlsMpfDkXwWixYtQiqVsmXLFoxGIxljx/LJggX4pFLGl5dznURCdHQ0X3zxhdh6M8T0+0/6b37zG3bt2sWKFSs4fPgw69at49VXX+Wuu+4CjgQcS5cuZcWKFaxfv568vDxuuukmtFotCxcuBMBgMHDrrbeybNmyYBKqRYsWkZWVxdy5c4Ejs+eXXXYZv/rVr9i1axe7du3iV7/6FfPmzRtWmRCF4/2YMmLf1jF+PHteew1bZiby7m4yHn+clOefR9qPy8FlMhl6vR6LxYLZbEYqlVJXV8eePXv48ssv2bRpEzk5OZSVldHc3CxmgwThLFRTU4PVau1TGlM4OVKpFJ1Ox+HDh0VSNUE4x/n9frZv306iy8Wcoxm4N19xBQ6vl8LCQvbs2cPGjRsBWLJkCenp6YPZ3UGRkZHBokWLcLvdyGQyWltbKVGr+WLKFAB+um0bM9PTKS0tJS8vb5B7K/QneX+/4JQpU1i/fj3Lly/n97//PUlJSbzwwgv88pe/DLZ54IEHcDgc3HnnnbS3tzNt2jQ2bdrUZ1/H888/j1wu54YbbsDhcDBnzhzWrl2LTCYLtnnnnXe45557glnO58+fz4svvtjfpyScY3rLiHV0dNDc3ExERMRpJzVyWSzsf/55EtesIWHdOkZ89BGhBQUU/Pd/4+jnRHy9F586nY5AIIDH48HpdFJZWUl5eTkymQyVSoVer8doNKLX6wkJCUGn06HRaETiJkEYBE6nk5KSEhQKBXJ5v/9JHRZ0Oh1Wq5X8/HxmzpzZ5++8IAjnjk2bNrF50yZebmpCHgiQY7GwLyqKcUYjbW1twezdS5YsISMjY7C7O2imTp3KxIkTiY+Pp6uri56eHj7MzGRsaSmWtjZ+vmsXOWYz+/fvJyMjQ4yJQ4QkcDoZp4aIzs5ODAYDNptN7O8egtrb2/nmm2/wer39MgMVnp1N+sqVKDs68KlUlN9+O3ULFsAZWhrl9XpxuVy43e5ghnapVIpSqUSlUmEwGAgNDUWj0aDRaFCr1Wg0muC+SeHkDZexYbic50DKz8/n0KFDWCyWYbVMsr95PB7a29uZNGkSI0eOHOzuDHvDZWwYLud5JhQWFvLYY48xNjeX/66sxCOX81+zZlHo8eDz+TCZTMTGxtLZ2cnDDz9MVlbWYHd50FRWVvL8888za9YslEolzc3NlJeXM7KpiVvWrkUaCPDMjBloFi7ksssuY9SoUYPd5WFnIMYGcVteGLLCw8PJzMxkz549OByOH51RuH3qVPa89hrpK1cSvncvKatXE7F9OyX33UfPGUgEIpfLkcvl6HS64GM+nw+3243L5aK2trbP/h+5XI5CoUChUKDVaoMz4iqVCqVS2efonaUTQYMgnLyOjg7KysrQ6XRn3e+OxOdD2daGsqUFeVcXPrUan06HMzIS37fGkLOFQqFApVJRWFhIRESECIAE4Rzi9/v55z//ib6ri9/U1gLw9SWXkD57NiarlaamJsxmM5MmTWLXrl3DKmP5icTHxxMbG0teXh7Jycnk5uZSV1dHrstFaFISN5SXc8fevXx9220UFRVhNpvF9qUhQATdwpCWkJBAe3t7vy3/dJvNHHjmGWI++oiRr7xC2IEDTL71Vmp/+lOqFi/Gd4ZLBclksuDM9rf1lqTwer243W4cDgdNTU19SqlJJBJkMhlSqRSZTIZMJgte+H47MO8N9mUyWfDfY4/e15BKpcFDIpGIGXZhyAoEAhQVFeFwOLBYLIPdHfD5MBw6hGnXLkILCtAXFyP7jvwTzogIukaNomPiRNonTaI7MRHOgt/V0NDQ4DLzadOmnXU3MgRBOLEtW7bw4YcfsrqhAb3XS4lez4eJiSgbGwkLCyMmJob6+nr27Nkz7DKWn4hUKmXevHk888wzbNu2jeTkZGbOnElTUxMf6HRMaGoipbubzNWr2fnggxw6dIgZM2aILUznOPHdE4Y0iURCRkYGdrudhoYGLBbLjw8EpVLqFyygbdo0Rq1ejXnnTuLffRfLli2U//rXWC+6aNAvYHuXnSuVyu9s4/f78fl8+Hy+4Mcej4eurq7gY8cKBALBYPrbgfW3P/72Y8cG9ScKznu/ViaTHfca33UAx3187GPHPi6VSomMjBR7o4R+UVdXR21tLWFhYYN6c0nZ3Ezc//4vli1bUB2TiMwvk+E2mfCGhCBzOpF1d6O02VA3N6Nubsa8cycAPXFxNF5yCU2XXIJrEG8gSCQSwsPDqampwWKxiGXmgnAOKCws5Nlnn2VmQwOzGhvxSaWsSkujubaWiIiI4HVGfn4+FouF2267TdxQA9LS0jCZTHR3dyOTydi8eXOwbOyqzEz+mp1N/P792LOzyZ8+ndLS0mGZeG4oEUG3MOQplUrGjx9Pd3c3bW1tmEymfnldZ3Q0eStWYNqxg1EvvoimoYExTz5J7D//Sfkdd9Axfny/vM9A6Q14FQrFKX1dIBAgEAjg9/tP+HHv4fV68Xg8xz3ee/S+1rH/DkQAEwgEUKlUzJw58+yYlRTOaS6Xi4KCAiQSyaCVCFM2N5P45ptEbdyI1OsFwBMSQuusWbSPH0/nmDE4YmOPyzkh7+pCW1lJaEEBxj17MBw4gLamhuTXXydx7Vqsc+dS/Ytf0HO0zOeZ1pujorCwEJPJJJZUDlHbt2/nmWeeITc3l4aGBtavX8+CBQuCzwcCAZ544gleffXVYMLdv/71r32Sb7lcLu6//37efffdYMLdl156idjY2EE4o+Gpd1m5o76ex1taANh1wQXox42jvriY4uJivF5v8Mb70qVLReB4VHV1NW63m2nTprFjxw4SEhJISUlBpVLR0tLC252d3FJYyKi//pWG0aMpLi7GaDQSGRk52F0XTpMIuoVhITQ0lPHjx7N7927sdnu/7idqnTmT9kmTiHv/feLee4/QoiLG/+Y3tE6fTsXNN9OVmtpv73U2+PZM9rnC7/fT2to62N0Qhoji4mLa2toG5QaO1OUi7n/+h/h165AdnRXpGDuWmp/9jLYpUwj8wE00b0gInZmZdGZmUnvDDci6u4n46iuiPvuMsAMHiNq4kchNm2i44goqbrsNzyAEvb3LzMWSyqGru7ubcePGcfPNN3Pdddcd9/yqVat47rnnWLt2LampqTz11FNcfPHFFBcXB/9+L126lI8//pj33nsPk8nEsmXLmDdvHrm5uWJF0xng9/v5+uuv2bZtGw9arZi9Xur0er656CIiZDJMJhN2u53GxkYqKyuZNWsWs2fPHuxunzXsdjsej4fi4mLMZjPTpk1DIpFQU1NDQUEBe6KiGFtVxeSeHhJ+9zv+89vfotVqOe+889BqtYPdfeE0nDtXzYLwI0VHR5Oeno7T6Qwu4ekvfpWKqv/3/9j99tvUXX01AakU065dTL7jDrIeeohQUWtR+JaVK1cyZcqUYI32BQsWUFxc3KfNTTfddNyy+unTp/dp43K5WLJkCWazGZ1Ox/z586k9msRGGBi9WWb1ev0Zv/Fk3LmTKTffTNIbbyBzOrFlZLDvL39h/5//TOvMmT8YcJ+IT6ej8bLL2P/CC+S+9BIts2YhCQSI+eQTpi1aRMz69XCCrSYDSSKRYDKZqK+vp7i4mGFcZGXIuvzyy3nqqae49tprj3suEAjwwgsv8Mgjj3DttdeSmZnJm2++SU9PD+vWrQPAZrPx+uuv8+yzzzJ37lwmTJjA22+/zaFDh9iyZcuZPp1hp3dJ+fPPP09CURFXWq34gZWjRrHn0CHa29uD29w6Ojro7OwUeRqOodfrcTgcNDY2kpqaikQiob6+nt27d6NUKhmZmspbs2fTI5OR0tjIiDfeIC8vj0OHDuHz+Qa7+8JpED/9wrCSkpLCyJEjsdlswbJb/cljNFK6dCnZa9bQNHfukeB7924mLlnC+HvvxbxtGxIxWA5727Zt46677mLXrl1s3rwZr9fLJZdcQnd3d592l112GQ0NDcHjP//5T5/nly5dyvr163nvvff4+uuv6erqYt68eeIP8gDxeDzk5eXhdrvP6EyDqrGRjMceY+zDD6NpaMBlNlPw6KPsW70aWz+W3bGnp5P31FPs+8tfsKekIO/uJvUvf2H8b36D5gzfzJHL5YSEhFBSUkJDQ8MZfW9hcFVUVNDY2Mgll1wSfEylUnHBBRewY8cOAHJzc/F4PH3axMTEkJmZGWwjDIz8/Hz+/Oc/U1FRQbrJxDNWKwBb09NpT0/HarWya9cuvvzyS7Kzs2ltbSU5OZlx48YNcs/PLvHx8YSHh9PR0YFer8fv9/PNN9/gdrsJBALs3buXr+vqWHF0u8S1+fk4PvyQiooKSktLB7n3wukQa7aEYUUqlZKVlUVPTw91dXVEREQMyJ1XR3w8hY88QuVNNxH37rtEbdxI2MGDhB08iDMigoarrqLhiitw99P+cuHc8tlnn/X5fM2aNVgsFnJzc/nJT34SfFylUhEVFXXC1+id6fnHP/7B3LlzAXj77beJi4tjy5YtXHrppQN3AsNUaWkpVqsVk8l0RpKnSbxeYv/5TxLfeguZ04lfJqP2+uupuvHGAa2UYMvKIvfll49UaXj1VcIOHmTyrbdSceut1F53HZyhpbs6nQ6n08nBgwfR6/XDvszQcNHY2Ahw3N7VyMhIqqqqgm2USiXh4eHHten9+hNxuVy4XK7g552dnf3V7WEhPz+fhx56CID42Fiu/+QTTF4vpUolr6emkpyYSFxcHD09PbhcLiQSCW1tbUyePHnYZyw/llQq5YorriA7O5uCggK8Xi9VVVWkpKTQ1NREbGwscXFxdAYCfPn551xYUMBdO3bw1uTJFKpUhIaGEhMTM9inIZwCMdMtDDsKhYKJEydiMploaWkZ0KWLjhEjKLn/fnavW0fVokW4w8JQNzeT9MYbzLjhBrIeeoiIL75A+h2lfYThwWazAWA0Gvs8/uWXX2KxWEhNTeVXv/oV1qMzCiBmes40q9VKSUkJOp3ujOwxVtfVMWHJEka++ioyp5OOsWPJfe01yn/96zNTmlAmo/6aa8hZs4a2SZOQud2Mevllxv32tyiPJkw6E4xGIzabjQMHDgzI6iTh7HXsja2TSbT5Q21WrlyJwWAIHnFxcf3S1+GgsLCQP//5z3R2dpKVlcW88nImNjbikkp5KDGRvLIyDh48SFdXF2FhYTgcDoqKitDr9Vx11VViafkJzJ49mxkzZlBXV0d2djYymYyuri4iIyOZOHEiBoOBQCDAu1OmUBkRQZjPx5Vr1+Lv6eHAgQPBawfh3CB+A4RhSavVMnnyZPR6Pa2trQO+Z9AVEUHFrbey8/33KXz4YWwZGUj8fky7d5Px+98z89prGb1iBeavvkLaz/vNhbNbIBDgvvvu47zzziMzMzP4+OWXX84777zD1q1befbZZ8nJyWH27NnBWZrTmelxuVx0dnb2OYQf5nK5OHToEB6PB51ON+DvZ9myhcm3305oUREevZ7Chx5i/wsv0J2UNODvfSxnVBQHn3mG4mXL8KnVhO/bx5Rbb8V0tNzYQOvd311XV0deXp7Y3z0M9K7uOXYcs1qtwdnvqKgo3G437e3t39nmRJYvX47NZgseNTU1/dz7ocnv97Nhw4ZgeU9VQQFzj+6dfzMrC+eoUQQCAfLy8vjss89Yv349+fn59PT08Itf/EJkLP8OUqmUW265BYPBgNfrRalU4nQ6SU5OpqGhgd27d1NQUEBxZSVLY2PpkMkY2d7OuNdfp9NmY+/evf2eo0gYOGJ5uTBshYWFMXHiRHbv3k1HR8dxwctACCiVNF18MU0XX4ympoaoTZuI3LQJtdVK1ObNRG3ejE+tpn3CBDomTqR9woQjF9riDvGQdffdd3Pw4EG+/vrrPo//7Gc/C36cmZnJ5MmTSUhI4JNPPjlh8qFe3zfTs3LlSp544on+6fgwEQgEyM/Pp7m5mYiIiAFdVi5zOBj1l78QfXT7QUdWFoWPPIJrsEvESCQ0zJtHx9ixjHnySfSHD5P18MPUXncdZbffTkCpHNC3l8vlhIaGUlZWhl6vZ9SoUQP6fsLgSkpKIioqis2bNzNhwgQA3G4327Zt4+mnnwZg0qRJKBQKNm/ezA033ABAQ0MDeXl5rFq16jtfW6VSDVqZv3NZdXU1+fn52O122isr+VVLCwq/n89DQtgzZQpjwsJIT0+nu7ubqqoqNBoN5513HqWlpaLE1Q9IT09n3rx5lJWV0dXVhd1ux2azUVJSQkREBElJSbhcLqqrq1nh8/HHgwcZ9cUXNEdEsOe881AqlUybNk1UeTgHiO+QMKxFRkYyYcIE9uzZg81mw2AwnLH3dsTFUXHrrVTcfDOh+flEbN9OxFdfoW5qwrxzJ+ajM0lug4GO8eOxZWZiHzOGrlGj8A/wRa5wZixZsoSPPvqI7du3/2Bt2ejoaBISEoIJVL490/PtG0ZWq5WZM2ee8DWWL1/OfffdF/y8s7NTLK/8AVVVVZSXl2MwGAa0DFHI4cOM+f3v0dbUEJBKqVq8mKrFiwmcRaWPHPHx7P3rXxn56qvEfvABsR98gOHAAQoeewzHAO/X1Gg0wUR2Go2GESNGDOj7CQOrq6uLw4cPBz+vqKhg//79GI1G4uPjWbp0KStWrCAlJYWUlBRWrFiBVqtl4cKFABgMBm699VaWLVuGyWTCaDRy//33k5WVFcxxIfQPv9/P5s2bycvLQ6dWs7qlhRi7HatSyRPx8UwKCSEkJASn04lOp2P69On4fD4aGhqQy+UiF8NJGDduHJmZmcjlcjZv3szBgweJjY0lOjo6uGTf4/FQ5PGg0mh40uFg2v/8D9tqa/lbdjaNjY1cc801Ygn/WU4E3cKwFxcXh8fjYd++ff1ew/ukSKV0ZmXRmZVF2Z13EnL4MOG5uYTt20fYwYMobTYs27Zh2bYNAL9cTtfIkdjT0+lMT6dr5Eh64uIGfLZJ6D+BQIAlS5awfv16vvzyS5JOYtlwa2srNTU1REdHA6c30yNmeU5Ne3s7eXl5yOVyNAO1jzoQYMS//sXIV15B6vEcyUz+yCPYxo8fmPf7kQJKJYfvvpv2SZNIe/pp9IcPM/mOOyi9914aL70UBnAlQGhoKG1tbezbtw+VSoXZbB6w9xIG1p49e7jooouCn/feDLzxxhtZu3YtDzzwAA6HgzvvvJP29namTZvGpk2b+vx9fv7555HL5dxwww04HA7mzJnD2rVrRY3uflRYWMhHH33EBx98QEdHB0u7ujjPbscplXJPfDwBo5Gqqiq0Wi1utxu3241er0ehULBx40bGjh0rEqidhPj4+CNJ0zo7SUxMpKKiAplMRm5uLmazmbCwMAoLC+no6ODT9HSmW61cWVvL0uxsVoSG8s4776BWq7niiivOSJJP4fRIAsN4g1RnZycGgwGbzUZoaOhgd0cYRIFAgJKSEg4dOoRarSYkJGSwuwSAxONBX1RE2IEDhBYUEFpYiLKj47h2AamUnthYupOS6ElMpDsxEUdsLI7oaHxnYA/q2c7v99Pa2soFF1yAxWL5wfYDPTbceeedrFu3jn//+9+kpaUFHzcYDGg0Grq6unj88ce57rrriI6OprKykocffpjq6moKCwuDF57/9V//xYYNG1i7dm1wpqe1tZXc3NyTuvAUY+B3czqd7Nixg5aWlgFbVq6w2Uh7+ungqpaWmTMpeuABvGdwxc2PoWxpIX3FCsL37QOgafZsSu67b0DHnEAgQEtLC3q9nmnTpp2RbUHD0XAZG4bLeZ6OwsJC3njjDZxOJwcOHOD8sjL+UF8PwJ+mTGFtTw/JycnU19djMpmIj48nNDSUsLAwampqOHjwIMuXL+fqq68e5DM5N/T+f1dVVVFcXExoaChms5nIyEhycnJoamoiLS2NKVOm4He5WPz++2Q1NGBXKnlyzhysFguPPvqo2H7TTwZibBAz3YLAkWQ9qampwUQgwFkReAcUiuAs+JEHAqgbG9EXFhJaWEhoURG6igrk3d3oqqvRVVfD0RnxXp7QUBzR0TiPHi6zGbfR2OfwaTQDOkMl9PXyyy8DcOGFF/Z5fM2aNdx0003IZDIOHTrEW2+9RUdHB9HR0Vx00UW8//77YqbnDPD5fBw4cACr1TpgAXfYvn2kr1iBqqUFv0JB2X/9F3ULFpxTv4dus5kDzzxD/LvvkrRmDZFbtxJaVETBo49iH6DESRKJBLPZTHNzMzk5OUybNu2MbgsShOGgN3GaWq3G6XSSUFPD4w0NAHw4diylEyYQlp9PVFQUoaGhwdrRPp8Ps9mMXq8nJSVF1OY+Benp6dxyyy289dZbFBQU0NnZyahRoygsLKSnpweTycT48ePp7u6muLiY/YmJPNfVRabdzoNbtnDf5Mls3boVlUolto2dpUTQLQhHSSQS0tLSgomT4OwIvPuQSILBc/Ps2UceCwRQtrSgq6hAV1kZPNQNDSg7OlB0dqLo7CS0uPg7X9anVuMOD8djMOANCTly6PV4Q0LwHP3Xp9PhU6vxqVT4NZojHx89/EcfP1P1e891P7TASKPRsHHjxh98HbVazerVq1m9enV/dW3YCwQCFBQUUFVVhdFo7PcbGBKvl4S33iLh7beRBAJ0x8dT8NhjdJ+rsxMyGdWLFtExfjxjnnoKTX09E5YsoeLWW6n52c8GJAnktwPv7Oxspk6dKgJvQehH1dXVwfwJrV9+yd+rq1EEAnxhNPKX8HBiHQ7cbjfV1dWMHj2amJgYurq6kMvlTJ8+ncLCQgwGg1haforS09N58sknaW5upqCggOjoaMrKytBqtWi1WhwOBwUFBZhMJkaMHs2bY8Zw1//+L4k2G3/MzublhAT2REQglUpF3ouzkAi6BeFbJBIJo0ePRiKRkJ+fj9/vP/uXnEkkuCMicEdE0D51ap+nZD09qBsaUDc0oDn6r7Ktrc8hdziQOZ1ojrb5MXxK5ZEAXK3Gr1LhVygIyOXf/a9c3ufzgFxOQCo9cshk0PuxVNrn42M/RyY78eNSKQHAL5GgstuRjB8PJ7G8XBi+ysvLKS4uJiQkBGU/50nQVFeTvnIloUVFADRccQWld9+N/0zU3R5gnZmZ7Pn730n905+wbNvGyFdfJXzvXoqWL8d9TP35/iCVSomIiKC5uZndu3czdepUwsLC+v19BGE42rBhAzk5OVwQH89L5eUY/H6KjEb+dfXVeA8fpqOjg/j4eJqamigsLMRisRAdHU1SUhJFRUU4nU4WLlwoEnudBrlczs9//nMef/xxampq8Hq9qFQqpFJpMOCOioqiuLiYtrY2vgoP5x89PaR4PNz5z3/yVEsL+/fv57zzziMlJYX4+HjxfThLiD3dYi+PcAKBQIDy8nIOHjwIHCkvNlSTU8gcDhRHA3CF3Y689+juPvJ5Vxdyux1ZTw8ypxOZw4HU5Try8dHjXNG2ZQvGOXN+sN1wGRuGy3merNraWvbs2YNUKu3f/w+/nxH//jfJr7yCzOXCExJC6W9+g7V3tcpQEggQ/cknjHrxRWQuF+7wcAofeui4G4L9xe/309LSQmhoKJMnTxbJ1frJcBkbhvJ5+v1+qqurgwlifyj46m2fm5vLY489hsXj4b3GRqK6uqgzGrkjLQ1FZCQ6nY6GhgZ6enro6uqiubmZuLg4Ro8ejdFoJC4ujiuvvFLU5v4R/H4/Dz74IIWFhTQ2NiKXywkEAjidTiZMmEBlZSVKpZKuri60Wi3Kjg5W5+cz0umkSSplYVQUnpEjSUlJIS0tjauuukp8P07RQIwNAx50r1y5kocffph7772XF154ATgS0DzxxBO8+uqrwayUf/3rX8nIyAh+ncvl4v777+fdd98N7lV86aWX+pTVaW9v55577uGjjz4CYP78+axevfqk73YP5cFW+PECgQA1NTXs378ft9uNyWQasoH3j+L3HwnCjwbi0qMz51KXC6nPh8TjQer1nvS/+P1Ijh7f+7HPhyQQ+L/Hfb4jzwUCfT7uPbxuN5I338Q0ffoPntJwGRuGy3mejMbGRnJycvB4PBj7cWZW2dzM6FWrMO7ZA0Db5MkUP/AAroiIfnuPs5G2spIxTz5JSHk5ANU/+xkVt95KQKHo9/fqTa6m0WiYMGGCWFbZD4bL2DBUzzM/P5933nmH2tpaJBIJEokEo9HIFVdcwezZs48Lvnvb5+XlsWvXLpLVat63WklwuahXqfjbokW0qdWUlJTgdDpxOp1IJBIsFgsymYz77ruP8PDwkwruhZNTWFjI3//+d3Jzc+nq6kKj0dDW1obBYMBiseB0OvF6vbhcLpRKJdLWVlYXFjLa7aZdpeKJadMIjB+PVCpFKpVy+eWXExkZKb5HJ+mcS6SWk5PDq6++ytixY/s8vmrVKp577jnWrl1LamoqTz31FBdffDHFxcXBJEFLly7l448/5r333sNkMrFs2TLmzZvXJyvvwoULqa2t5bPPPgPg9ttvZ/HixXz88ccDeVrCMCGRSIiPj0elUrFv3z6sVitms1kkqTqWVIpfo8Gv0eAZ7L58h2D28uTkwe6KcBayWq3k5ubicrkwmUz99rqWzz8n5YUXUHR14VMqKb/jjiPJ0obBxU5PYiJ7X3qJkS+/zIh//5v4998/stz8oYfo7uffw9493u3t7eTk5NDT08OoUaPETVJhWNqwYQN//vOfUavV6HQ6rFYrbrcbv99PdnY2Gzdu5JZbbgnOfPa293g81NfXM0Ii4b1vBdy3JCUhb2xk7NixTJo0ierqatrb25k5cyYulwuDwcB5550ngrh+lp6ezm233YZEImHLli00Njbi9/tRKBSoVCoaGxuRyWRoNBq8Xi+twJMXXsiqffsY0dzMH7/5hr/4fNRPnkxOTg779+8nNTUVp9NJeHj4d96AEQbOgM10d3V1MXHiRF566SWeeuopxo8fzwsvvEAgECAmJoalS5fy4IMPAkdmtSMjI3n66ae54447sNlsRERE8I9//IOf/exnANTX1xMXF8d//vMfLr30UgoLCxkzZgy7du1i2rRpAOzatYsZM2ZQVFTUpwzPdxmqdziF/mez2di7dy9NTU2Eh4eLWsfnmLOtZNjZYric5/dpampiz549OByOflvNIu/sJPWFF7B88QUAnWlpFD38MD3DNKmQ+euvSVu1CoXdjl8up/qXv6Tql78ckFnvzs5OXC4XI0eOJDMzs9/35Q8Xw2VsGGrnmZ+fz5IlSwgPDyc9PZ39+/cTGhpKZGQkLpeL1tZWuru7SUtL47bbbsPv97NkyRIMBgNer5dAXh6v1dYS7fXSptfz7FVX8WVlJVarlaioKKKiolAqlUgkEiIjI5FKpX0CeKH/+f1+tm7dyj/+8Q8+//xz9Ho9WVlZHD58+MjScqXySMK71laSkpIIA+7ato3Mhgb8wJ+iovhi3DikMlmwnnpHRwc+n48ZM2aI7993GIixYcBub9x1111ceeWVzJ07t8/jFRUVNDY2cskllwQfU6lUXHDBBezYsQOA3NxcPB5PnzYxMTFkZmYG2+zcuRODwRAMuAGmT5+OwWAItjmWy+Wis7OzzyEIJ8NgMDBjxgySk5Ox2WzY7fYfzEAtCMLZraGhgZycnH4NuMOzs5ly661YvviCgFRK5Y03su/FF4dtwA3Qct555KxZQ/N55yH1ekl8800m/frX6L+nosLpCg0NRa/XU1pays6dO+no6Oj39xCEs5Hf7+ftt9/G5/Mxffp0Dh8+jNFoJD4+noqKCgoKCmhoaKCjo4O9e/fy+uuv849//AOfz0dycjLxFRWsq6kh2uulWqPh4ZkzkY0cyUUXXcSMGTPwer1UVlZy8OBBqquriYyMFAHbGSCVSpk7dy5r1qxhxYoVqNVqZDIZSqUSj8eD3+9HJpPR2dlJaGgohoQE/nbVVXwUHY0UeKCxkSWHDtFUWUlXVxcjR47k2muvZcqUKVRXV/P6669TWFg42Kc5LAzI8vL33nuPvXv3kpOTc9xzjY2NAERGRvZ5PDIykqqqqmAbpVJJeHj4cW16v76xsfGEM1YWiyXY5lgrV67kiSeeOPUTEgSOlGeaPHkyBoOBwsJCWltbMRqNYmmOIJxjvp2vwePx9EvALXU4GPnKK4z4978B6ImLo3D58gGrV32ucZtM5P/+90R8+SUpf/kLIeXlTLzzTmpuuIHKm27C34+rh9RqNXK5nKamJr7++msyMjJITEwUy82FIa26uprq6moMBgM+nw+73U5iYiL79u0jPDycqVOnIpPJqKmpoa2tjf/85z/ExMSgUqnIys9nYUEBykCA/LAwfjd+PC1OJ9a8POLi4khOTsZgMJCTk4NMJuPRRx9l7ty54vrnDJJKpSxatIhDhw5RVVWFVCqlpaUFqVRKe3s7SqUSnU5HV1cXecXF7EtMJM/t5qHWVq6oryfdbueD6dNpViiwWq3ExMSgVCrxer188sknpKWlie/nAOv3oLumpoZ7772XTZs2oVarv7PdsX/8AoHAD/5BPLbNidp/3+ssX76c++67L/h5Z2enKCAvnBKpVEpaWhrh4eEcOHAAq9VKWFjY9/6sC4Jw9vD7/ZSUlFBQUBBMLvRjg7GwfftIfe45tLW1ANRecw3lt9+OX4wLfUkkNF90ER0TJzJq9WoiP/+c+Pfew/zVVxxesoS2b61c+7HkcjkRERHYbDZyc3NpaWkhIyMDrVbbb+8hCGcTu90eTJpWUVGB0+mksrKS8PBwxo0bR2NjYzB3hU6nw+VyUV5czAq/n5/X1wPwhcnEu5dfTmttLUqlkpaWFpqbm4EjyYu7urp47LHH+qxEFc6c3uX8r7/+OhqNhubmZlpaWjCbzYSFhVFZWUl3dzdGo5Hy8nLetliQjx/Pbdu3k2S3c89bb/HRxRezJS6OsrIyPB4PWVlZVFVVsWPHDgwGg0i0NoD6PejOzc3FarUyadKk4GM+n4/t27fz4osvUnx0OVljYyPR0dHBNlarNTj7HRUVhdvtpr29vc9st9VqZebMmcE2TU1Nx71/c3PzcbPovVQqldiLK/QLi8XC+eefT35+PhUVFXR3dxMeHi4GKUE4i7ndbvLy8igrK0OtVgcTd54uRVsbI195hahNmwBwmc0UPfAA7VOm9Ed3hyyPwUDho49inT2b1OefR1tXx9iHHqJl5kwO33UXzpiYfnkfiURCWFgYLpeLsrIy2tvbGTNmDCNGjBCz3sKQ09DQQHFxcfD62W63o1KpSEtLo6CggNzcXIxGI4mJiXg8HmQ1NTzd1MRkz5EUqOtiYlhlNJLU1cWYMWMoLy/H6/Xi8/nw+XwEAgGuvfZabr755kE+0+EtPT2dW2+9lQ0bNtDW1saOHTuQy+VMnTqVwsJCXC4X8fHx2O12DAYD+yIiuGXiRP5ktTKqooLrP/2UMJ2O30VE0CCRsG/fPlwuFzU1Nej1evx+P/Hx8SxatKhPVSnhx+v3CGHOnDkcOnSI/fv3B4/Jkyfzy1/+kv3795OcnExUVBSbN28Ofo3b7Wbbtm3BgHrSpEkoFIo+bRoaGsjLywu2mTFjBjabjezs7GCb3bt3Y7PZgm0EYSCp1WomTpzI9OnT0ev1NDc3093dLfZ6C8JZyGazsXPnTkpLS9Hr9T8q4Ja6XMS//TbTFi0iatMmAhIJdVdfTc6aNSLgPgWtM2eS/eabVP/sZ/hlMsw7djD1pptIfuUV5P2Yc0WlUmGxWLDb7ezatStYgkcQhgK/38/rr7/OAw88QF1dHWq1Gp/PR09PDw6Hg87OTnbt2kV0dDQzZswgwmxmyoEDfFRZyWSPh06ZjPtHjeLVlBR8QGlpKZWVlYwYMYKkpCQSExMJDw9n+vTp/OpXvxKTC2eB9PR0li1bxurVq1myZAlerxe3201UVBRer5fy8nI0Gg1hYWG0trbSplTy1Hnn8WJsLB6JhLnd3XxWU8ONHg8EAoSHh1NeXo7VaqWpqYnNmzdz2223BUsyC/1jwOt0A1x44YXB7OUATz/9NCtXrmTNmjWkpKSwYsUKvvzyyz4lw/7rv/6LDRs2sHbtWoxGI/fffz+tra19SoZdfvnl1NfX88orrwBHSoYlJCScdMmwoZa1Uhg8DoeDkpISKioqcLvdhIWFiay5ZxGRvfzEhsN5BgIBqqqqyM/Pp6urC5PJhFx+mou8/H4sn39O8t//jtpqBY5kJi+95x7sY8b0Y6+HH21VFaNWr8aYmwuAV6ej+uc/p/a66/BrNP32Pk6nk46ODkJDQ0lNTSUxMfH0fx6GsOEwNsC5f575+fm88MILbNy4EY1Gw4gRI/D7/ahUKhoaGmhvb0ev1yOVSrnwwgsJsdm4Yv16ftLdDcC+kBCeSkmhIzwcr9eLzWajubkZj8eDSqXCZDJhNpuZOHEiN998s0iadhby+/088MADlJWVYTAYOHDgAH6/H61WS1paGhUVFXR0dAQTrk1Rq/lNfj5jjt543Gcw8GxcHJVHM9jr9Xp6enpobm7G5/Px7LPPsmDBgsE9yUFwztXp/i4PPPAADoeDO++8k/b2dqZNm8amTZv6zDw8//zzyOVybrjhBhwOB3PmzGHt2rV9aiS/88473HPPPcG9JfPnz+fFF1884+cjCBqNhrFjxzJixAiKiopoaGgILm0UF3SCMDi6urooLCykqqoKmUyGxWI5vWXFgQDG3btJfPNNQouKAHBaLJTfdhvWOXOGRd3tgdaTkMDBZ57BtGsXSX//OyHl5SS//jqx//oXdddcQ93VV+PthwsftVpNZGQknZ2d7N27l+rqalJTU4mJiREzeMI5w+/388Ybb/C3v/2N9vZ2VCoVRqORcePG4XQ6KS8vx2Qy0dzcjN1uZ0REBLN27eKq/fsJ8flwSSSsjoqi9rrrMLlctB8+jEQiQavVBq9bjEYjN910E+effz6JiYni9+MsJZVKufXWW3n99dfx+/0YjUY6OzsJDw/HbrczZswY9u3bR01NDSaTiQKZjEcuuohra2q4/sABJthsvGWz8Z+ICN5ITqbF5UKtVhMVFUVzczO//e1vkUqlzJ8/f7BP9Zx3Rma6z1bn+h1O4ezk9/upq6ujtLSU1tZWpFIpBoNBBN+DSMx0n9hQPU+v10tVVRXFxcXY7XbCwsJOL5+Hz0fE9u0kvPMOIWVlR15bq6V64UJqr7++XzNuC9/i92PZupWkNWvQHE3w5FOrabj8cmp/+lOc38oH82N4vd5gSTGLxcKoUaOIiooSwQVDd2w41rl4noWFhTz99NNs3LiR2NhYnE5n8Cb/T37yE+RyeTB7eWlJCdF79/JYRwcJLhcA+Todv4uPpyE8nNmzZyORSHC73TidThQKBR0dHSgUCnp6eli2bBlZWVmDfMbCySgsLGTDhg3s2LGDvLw80tLS6OzsJDY2Fo1Gw86dO5FIJISEhJCYmEhpaSmmzk4e7OhgbmsrAA6plE+SkzkwezZ2jYaGhgZKSkqQSCT88Y9//M6M9X6/n+rq6mBJXb1ej8FgOKcTsg2ZmW5BGMqkUilxcXFER0dTW1tLWVkZbW1tSCQSQkNDxbJzQRggfr+fxsZGSkpKsFqtKJXK05rdVnR0EPXpp8Rs2BAM+rwaDfXz51Nzww14jMaB6L7QSyrFOncuzRdeSMSXXxL3/vvoDx8mdv16Rvz73zSffz718+fTMWEC/IiEaHK5HLPZjNvtpqmpCavVSkREBElJSURHR6NQKPrxpAThx/H7/WzdupUXX3yRPXv2YDQaSU9Pp6SkBL/fj8fjoaenB71ejwQYa7Vy98GDjDqadLhFJuPDqVN5xenEB+jlcrq7u9HpdCiVSpRKJRqNBoVCQVNTE36//0cnmxTOnPT0dNLS0rjuuut48skn6ejoICUlhYqKCux2Oy6XC6VSGZyEiI6OxiqT8aDBwJTYWO6qqCCrs5PrDx9mXnk5H5rN/FWjoUuhwOfz8eijj7J//36uuuoq0tPT8fv9VFZWsmnTJrZt20ZraysdHR3IZDK0Wi1xcXFkZGQwb948sS3hKDHTfY7d4RTOPV6vl/r6eioqKmhpacHn8xESEoJGoxEZdM8QMdN9YkPlPP1+P1arlcOHD9PU1EQgEDjlrR0Sn4+wffuI+uwzIrZvR3o0o69Hr6f2uuuou+aaflne3F8CgQB+vz+YWdjn8+H3+wkEAsclc+wtIySVSoOHTCZDJpMFnzurBQKE791L3PvvY8zJCT7cExtL/VVXYZ07F3c/3Ahxu910dnbi9/sxGAwkJCQQExNzJIg52/+P+tlQGRt+yNl+nr0ziPv27WPz5s189dVX2Gw2FAoFERERTJo0iby8PCQSCR0dHYxMSuIalYoLvv6auLo6ANwSCW8ZjbwUFsaUOXMoKCgILj8ODw8nIyMDtVqN2+3G7/fj9/s5dOgQY8eO5cknnzxnZyqHs8LCQl5//XUCgQCJiYkAbNy4kdLSUiQSCREREcyaNYvdu3dTX19PSEgIOq2WaxUKLt2zh3S7HQCvRML+pCQ+HjGC//T0oFKr0el0TJs2jdLSUvbs2RPMlRIIBIiNjSU5ORmv10tjYyMymYyIiAiWLl16zmVCFzPdgnAOksvlxMfHExsbS3NzM1VVVTQ0NGC321EqlYSEhIgZFUE4DV6vl4aGBsrLy2lubsbv959aEkO/H0N+PpatW4nYtg1le3vwqc60NOrnz8d60UX9msjrVPQG1m63G4/Hg9frxev1Bp/rDZx7D6VSiVwuDwbTR06xb2Du8/nweDx9ygD1kkqlyOXy4KFQKJBKpYMfcEoktE+aRPukSejKy4n56CMiN29GW1vLqJdfZuQrr9AxfjzWiy6i+fzz8RoMp/U2SqUSs9kcXJp74MABiouLsVgsxMbGYrFYRNlRYcD0zhyWlJQEH9u2bRu7du2ioqICrVZLZ2cner0ejUaDUqlEoVCgVqvRulxc3drKtYWFJLjdALhlMj4fOZLn5XLKnE40ajU9PT2MGDGC2tpaVCoVbrcbuVxOXFwcfr8fr9dLdXU1TqeThQsXioD7HPXtsmKHDx/G6/USHh6O0WiktrYWhUKBUqkkMzMzmABYoVDwH42GbbNnk1ZTw6LqajJbWphcXs7k8nJ+KZPxtkrFv5RKVmdno9Vq8fv9jB49GolEgsFgwGg0kpubS1tbG1KplEAggM/nIy8vj1dfffWEWxV6byz1Lks/l5ek/xAx030W3+EUhi673U5DQwNVVVV0dnbi9XpRqVTodDrkcvngX+QOMWKm+8TOxfMMBAJ9fn9sNtspbd2QORyE7d2LMTsb065dwSzkAJ7QUKwXXkjjFVdgT0sbyNM4Tu/yULfbjdvtxufzAUcC4d4LpNDQ0OAFt1qtRq1WB5eFKpXKHwyQey+qe8vLuN1uXC5X8Oju7qarqwuHwxEM8v1+f59+9B6DPU7JHA4sn39O9CefBJPbAQSkUmyZmbRNm0br9Ol0JyWd9hL0QCCAw+EIloLUarVERUURFRWF2WxGrVb31+mcdc7FseF0nA3n6ff72bJlC6+++iqHDx9GKpVis9lwOBzo9frgMuH/396dh0dVnv0D/84+mWQy2TcSQoAAgbBI0BBQ0IooikJ9q7RaXlxq5XVFbK3UtoCvlWpb6oJYV3BB4dcqVt8iGssuixrDFgIECJCEJJN1JpnMPs/vjzDHTDYSyGSSyfdzXeeazJlnzjx3JnNn7vOc85zGxkY0NTXBYDA0f/blclztduO6qipMOHEC2vOfVbNcjg/1erxlMKBaoUB6ejpuuukmfP7551AqlUhLS0NxcTFOnDgBg8Eg7ZiTyWRQqVQICQnB4sWLMXv27ID8PqjntC5oLRYLli5dim+++QaXX3454uLiUFZWhj179kCv1yM2NhYZGRk4efIk0tLS4M7Lw+zSUtzS0IDQ8+WiB8A3ISH4t16PnVFRGJqTg5MnT2LIkCE4cuQIbDabNPLtdDphsVhQX18PtVqNn/3sZ0hLS4MQAnK5HDabDQcPHkRDQwOsVivUajVSU1P7xDXC/ZEbWHQPgH8q1He53W7U1NTAaDTi3LlzaGhogMvlglKplL5YB+sev97Eort9/SVOIYR0CZOysjJUV1fDarVCq9UiLCys88PIhYDuzBlEffMNor75BhEHD0qHjgPNE6NVX3kljNdei7qJEyF6YcJDt9stFb0Oh0MabfYWzwaDAREREQgNDZWW3swFbrcbVqsVVqsVTU1NaGpqQkNDA+rr62G32+FwOKQRd4VCIe0UUKlUPqPsvUV77hzitm1D7Nat0J844fOYLT4etZMmwTRuHOrHjYM9IeGiXsPj8UjXPRZCICQkBDExMYiLi0NUVBQMBkNQ5er+khsulb/jbFn0hIaGAoB0HrX3HO1//vOfKCwshEajQWxsLCwWC4xGI5KSkmA0GqHX6zF58mQUFhZCZrPhCpsNV5vNuLq6GpEtctnJsDBsiI7GOgDVVitGjBiBu+++G/PmzUNoaCgKCgrw8ssvQ6PRYOzYsXC73fjiiy9QUlICp9OJwYMHIzMzE3feeWfACx7yH5fLhQceeAClpaVITU2FRqPB2bNnsWPHDsTFxSErKwvFxcUICQmB8fxO6TCPB/OVSuScOoXxZrO0LQ+A03Fx+I9Oh7y4OOyz2RATFweHwwG1Wg2Hw4GmpiacO3cOTU1NUrHt/Z8tk8kQFxcHhUIBrVYLl8sFp9MJnU6H3/zmNxg3bhyOHj2KyspK6bD40NBQNDU1QS6XY/jw4ZDL5bBYLD0+Ss6iu4cNlH8q1D+43W7U1dWhtrYWFRUV0hdcj8cjHUKm0Wh8LptHXcOiu319OU632436+nrU1taisrIStbW1sNlskMvlUhHaXnEnt9mgP3YMhoIChBcUwHD4MFQtviQAgDUxEbVXXIHa7GzUTZzot1nIhRA+o8rO81+QZTKZNGlRZGQkDAYDwsLCms+rCw3ts59xIQTsdjuamppgsVhgsVhgMplgMplgs9mkc0KFENLh6d6CvLcOU9dUVCB6715E792LiPx8KM4fautli4uDaexYmDMy0DhiBBqHDYNbp+vWa3g8HmmnhNvthkqlQmhoKGJjY6UCPDw8vM++j13Rl3NDT+pOnO3N0KzX6+HxeHDi/M4e77XfAeCrr77CP/7xD9TW1sJsNqOurk46OqW0tBQWi0U6h9pgMCAlJQVutxtGo1HKcw21tcjRanF9aChSjx/HBJMJmvMj2gBQr1Jha0wMcuPi8K1Sidq6OtjtdixatAiPPvpom1PXvDNcl5aWwuVyQaFQICwsDNnZ2Rg/fnxQH9pLP2h5zvfQoUMRFxeH3NxcbN68GRkZGVKx7c3ZWq0WGRkZOHDgAGKbmjDLZMJ19fXIaGry2a5ZocChiAgcjopCXlgYzkRGorKmRjpaSAgBrVaL6OholJSUSAW3RqOBy+WSdrBXV1fDbDYjKipK+h4sl8ul0yH0er30/ygyMhLDhg2DXq+HQqHAsGHDMGjQIMTHx2PkyJEXfbk7Ft09bKD8U6H+x3tYY319Perq6qQE5E0+wA+jYn3hUM++jkV3+/pSnN5JrMxmM2pra1FVVSUd5uw98qPl5INyhwMhZ88i9PRpadGdPo2Q8nLIWnwpBQCPSoX68eObDzm+4gpYU1Iuadbr1rznrTmdTmnxHh7uPdc6NDQUUVFRCA8PlwrsYJlMUQgBm80mFeIti3G73S79PryTubU8RF2lUvntdyC32RCRn4+IAwcQcfAgwo4fh/z8+yL1XSaDddAgNA4fjqbUVDSlpKApORnW5GS4z49MXih2p9MJm80Gm80GIYR0iK53oiq9Xt/nd6i01pdygz91NU5vseo9z987Ime32yGEkGb59v7svZKCwWBAU1OTVBzU1dWhsbFRmsvF4/FAqVQ2X9ZQrcZgmQwxZWUYY7FgQmMjMi0WaFt9Ta9UqbAzLAzfJCfjG70eNrcbFosFZrMZYWFhWLFiRafXVB5I59BSx9rbAXPo0CGEhISgsrJS+vuQyWQIDQ3FqFGjcODAASnnaTQaDAJwrc2GsWfO4LL6eukQdC+bXI6jWi2OhoTgSEgIjup0ECNHorK+HvX19YiKioJKpZLOKXe5XKiurkZlZaX0/da7Q7Ourg4ulwtRUVGoqqqC2WzGoEGDoNVqYTQa0djYCMf5naw6nU4qzkeNGoXp06dDp9MhLi6uy4U4i+4eNlD+qVD/592jZzab0dDQIBUmTU1N0vmfLQ/b8X6hbT2p0kAVzEX36tWr8ec//xnl5eUYM2YMXnjhBVx11VVdem4g4vQepusdLW1oaEBtbS0aGhqkw5blcjk0ajUMNhvCqqsRUlkJbUXFD0t5OULOnWtTXHvZY2JgGjMG5jFjYBozBo3p6RCXOFmhd1Iz77nOLc95bllMajQaGAwGafQ6NDQUYWFhUKvVA+5z6N156H2vm5qapB0rNptN+h16eX+HLSdz68kRcrnVivAjR2A4fBj648cRVlQEbVVVh+3tUVGwJifDFh8Pe1wcbHFxsLdYXKGhbXbeeL+Qes+T9+4k9f5t6PV66dSBkJAQ6HQ66TJNfenvgznwB4WFhXj77bdRUlKC48ePQ6vVwmQyob6+HlqtFnFxcWhqaoLJZJJGrxUKBVJTU6FWq6XzsM1mMyorK2EIDUVWXBwiqqsR39iINJsNoxwOpFutCG/xefAyKZU4HhOD/PBwHElNhX3oUBw4eBBGo9FnIsS4uLgOJ6siak9753yvWbMGp0+fxoEDBxASEgKlUgmtVotRo0bhxIkT0kz53sO9vd9BK0pLMRFAjtOJbKsVExoboWtx+oP0mjIZytRqnNZocE6vR4lOh3Ph4TirVMIcGooTxcU+R0ilpaWhqalJuqRjXV0dKioqMGLECAwdOhT79+9HfX29NIrecjLMqqoq2Gw2KBQK6PV66HQ6REREICcnB/fcc0+nlzLj7OVEA5RMJpMmTvIWjUIIOBwOaWTJ+8XWbDbDYrFIEyO5W4zsyGQyaabjlpcN8v7cLy4fRJINGzZg0aJFWL16NaZOnYrXXnsNs2bNwpEjRzB48OCA9Kll0eEd/bM2NMBeXY2m8nI4qqsBsxkwm6FqbITWZEJSYyNCGhqgbWiApr4e6vp6qGtrfc69bo9Tr4dlyBA0DRkCS4vFGRnZrZFsb0Htcrl8ZvluOZEYAJ+dWhEREdIIpk6nk5ZgGb3uCTKZTPq9xMTESOu9uct7iLa3MG9sbJSuJ2u1Wtv9/beesb07lz7zhISgPisL9VlZ0jpVfT3CiooQdvIkdCUlCCktha6kBOq6Omhqa6Gpre14eyoVnAYDHBERcEZEwGkwwBkR8cN9vR7u0FC4dDpYVSpYVSrU1daivKwMOD/K4t3J4J1IMywsTMr1Go3GZ6K8vlaY9wX+zoEejwf/93//h4aGBpwoKsJQtRq1Gg2sajWio6MRFxeHuro6NDU1QafTITI0FDqbDYNkMqQ1NSHBYoHBYkFMZSUizGYMdjiQXF4OZVFRu6/nlstxRqtFoU6H7zQanEpMRLnBALvTCbVaDUtjI+IqKjBu3DhUVlaiqqoKMTEx/fayTBRYcrlcOh3C695778Wnn36K06dPo66uDmq1Gk6nE7W1tdDpdBBCQK1Wo76+Hk6nEzExMZDJZLC5XPhaCHyrViM+JQVjR49G7TffYFRTE0ZZLM23Viv0bjdS7Hak2O3N3wVacAGoVCpRqdGgQq1GlU4HZUgICmtqUKdSwVJXB6vZjNioKIwbNw6FhYVwOp0IDQ2FTCZDTEwMXC4XQkJC0NjYiNDQUERGRmLw4MFITU2FTqeD0WhEQUEB/vrXv+Lxxx/v1WuIc6S7n+zJJeoOt9stFTze4sd7650MyDsK0/oav17ekfPW1/Ztfb1f7/2+XLAH60h3dnY2Jk6ciFdffVVal5GRgblz52LFihUXfH634nQ6gRMngLIyeEpK4Dh7Fs76enhMJngaGiDOL7BYIG9qgrLForLbLyo+IZfDHhsLW3w8bAkJPkvT4MHN12Y+/zfnPV/Me45ky59bLt6/9dZaFnTew9l1Op10/njLJSQkpN8cJtzfeM+D9+Yvb+7ynkvuLdBb7yBpL3d5dzK2zFOt81bL3NUyfykaG6ErLUVIaSm0RiM0RiM0VVXQGI3QGo1t5gnoLpdO17yEhMCtVsOlVsOtVMKlUsGtUsGtVsOtVkNoNPBoNBAaDaDVQqbTQaHVQqnVQqHVQqHRQK7RQK5WNy/nf1Zote2uk40cCXRhln/mwGanT5/GypUrUVpaCmtxMT7fvx9WhQKVKhUccjncCgU0DgfC3G6EezzSDOIX4pTLUapWozQkBOU6HfZ7PDgZFobkmTNxuKgIHo8HZ86cQXR0tDTJlPcUHJPJBKB5p9aECRMwZcoU3HTTTb1aPFBw807y98orr+DkyZNwnt/pExMTA4vFAo1Gg7q6OtTU1MDtdkuTpnn/D8fExCAnJwcFBQXSeplMBq1Gg8lDhsBVUICkhgbE19cj3eNBmsOBeLsdyi6WpB4AlpAQ1AiBBrkcjQpF845NtRru0FDUC4EKqxUWpRLhiYmIHzoUVoUCQqfDufh4VJ0/hW3SpEn41a9+1e6h5hzpJqIuUSgU0qzHHfEeKutdvBM9tbzv/bLbciKoloVL6+Kms6Lbm3TbWwB0+nNntxda533tYONwOJCXl4cnn3zSZ/3MmTOxe/fudp/jfT+9zN0pHMrLgdGjAQByANrzS3e41Wq4QkLgDA2Vbm0REbAbDM1LeDhs5xd7RASaIiPhUSikf+RAi/fV7QZaHRrccgdQ651F3pFD7+IdOWx5q1arodFopOtTU+/zXrZIpVJJ58m21t4Eda3zV8tDvFvnLu/P3tzlvW2Tv6KigKgon789bxulwwFtQwPUJlPzERpms+9iMkHl3enU1ASl1QplU5N0Trl3h1Rvazp6FLpevhyev1xMDuyuhoYG6TzsIW433DIZQtxuDGk1N0BLbgC1KhVq1Go4Y2NR1NiISoUCdSEhKNVqUa7TIe3KK3G4sLDtIbNHjiAtLQ1FRUUwGAwwGo2IiIhAQ0MDAMDpdCIkJAQajQZ33303brnlFp6TTT1OLpdjxowZGDRoEN566y1s374d5eXl0iR/QgiEhYUhISEBkZGRiI6Oxo9+9COkpaVh3bp1+PLLL3Hs2DFp8jPv/+UmqxWn7XY0JSXhiMuFkydPQiaTIT4+HmNHj8a5779HnM2GOJsNCQ4HBnk8GKLVQl5TgwiHA1EuFwxuN+QA9FYr2v8P0UpJCfDNN9Ld55cuhU6ng8FgwLFjx3D27Nk2o/3+wqKbaICSy+VSAdJV3i+t3mv9thxparm0LMxbFujttWvdpvWXYe8XXu+td5Sy9foL/RwSEhJUX0yqq6vhdrsRHx/vsz4+Ph4VFRXtPmfFihVYvnz5xb1gYiJEZCQa9XpYIyNhi4pqHqXTan+41WrhPr+4zh9W6woNhTMkBO7QUIjzh8e2Pjqi9REUGrkcOoUCMS1Of/Ce39u6mG59qoR3pNp7y3kNgk/LwryzHYsttXcKgffw9Y5yV3tHSXTUpsnjQWOrHNY6jwmPB3KHAwqLBSqrFYrzhbfC4YDcbm9+zOG44K3M7Ybc7YasxSJv5+fW6+QeD9xBdITGxeTA7u549E6K5vF4UGgwYObUqbg2LQ2l330H2GxQCQGbWg1naCgGjx2LXYcPw6pSwQ3AarXimmuuwffff4+qqipERERArVbDZDJBXlqK4cOHo66uDpWVlYiKioJer8fRo0fR0NAAjUYDh8OBkJAQVFdXQy6Xw2AwYPjw4bysF/WajIwMPP/88zh9+nSbS3fp9Xpp/pKWO35mzJiBt99+G6+99hpUKpU0t4f3O9mxY8cQExMDq9WK6OhoFJ8/h7vRakWdTgdTWBjyzn8uZTIZhg4disbGRpSWlkIIgWiDAbFyOeIBoK4OWocDercbOqcTUUolhkREwHLuXPPRJwDi9XqonU6oHQ4onU54NBoo7Xbps+jdodUbWHQTUZd5i53WlyHxF+nLaidLy3ad/SyTyTocOevPWheT3iMK2rNkyRIsXrxYum82m5GSktK1F1KpgJoayJuaoBMCoe0cqeC9bf1ze0c1EPWmlvNZBMLF5Kz2diK291hH9z2t7nsvDxVsupMDu7vjcfDgwRg8eDBKSkqg1WpRW1sLU2IizqSlobi4WNqhq9VqYYiKgiImBpbKSkRHR6O2thaHDx/G8OHDUV5ejrq6OiQlJUGpVOL48eNwOBwYNWoUjh07hlOnTkk5sqysDHFxcRg2bBjCw8MRFRWFiRMnYuzYsW0KHCJ/k8vlGDp0KIYOHdrl9r/4xS+Qk5ODdevWoaCgAMXFxaitrZVm+zcajVCr1RBCQKPRwGg04syZMwB+uDJPfX09gOYiPTY2FnK5HLW1tc2X0U1KQrXLBZNKBc/5vO6dAX1SVhaOhITA4XBAq9UiOztbmoVdCIEQQDpSyju5ZW9h0U1EfVZfPk880GJiYqBQKNqM6BiNxjYjP17dPbKhNe+lQ4ioe5jLet7F5MDu7niUy+X4+c9/jn379kkjdgcOHMCQIUNQWVmJ8vJy6aiJM2fOYMiQIaipqYHRaITBYMCZM2dgs9kQFRWF0tJSnDlzBnFxcXA6nThy5Ajkcrl0asPIkSNx22234ZprroFcLofFYuElvajfGjNmDJ555hnp2vYmkwlmsxlVVVXSvBveEfP8/Hx8+OGHUCqV0jnUQghUVlairq4ORqMRCoVCmpvI6XQiPj4eMplMOlpFJpPB6XTi9OnTCAkJkSYXPn36NMaOHSvtePTObWQymTBp0qRenXSWRTcRUT+kVquRlZWF3Nxc/PjHP5bW5+bmYs6cOQHsGRGR/11MDryYHY9jxozB4sWL8eKLLyI0NBQnTpxAY2MjIiMjUV9fj9raWmi1WhQUFGDo0KEYMWIEioqKYDQa4XK5cPz4cYSFhSEqKgpOpxNGoxGhoaHS5EzDhw/HfffdhxkzZrC4pqDS3uzo7Zk2bRpmzJghjYxXVFRAqVQiJSUFOp0OUVFRGD9+PCZMmIDq6mp89tlnOHHihHT0jtlslq6ccvjwYcTExMDhcMDj8eD48eNwuVxITU2FSqVCVVUVamtrkZSUhJtvvrlXP3MDuuj2Ho7VrcmEiCjoeXNCX5+AbfHixZg/fz4mTZqEnJwcvP766zh79iwWLlzYpeczBxJRe5gDfU2bNg2xsbH4f//v/+HIkSMoLS1FQ0MDYmNjkZycjJqaGlgsFhw+fBhqtRpKpRKRkZFITU3FNddcg5EjRyI8PBxhYWHweDw4deoUgOaCOzU1FXK5HI2NjZf2yyDqx1JSUvDEE0+gpKQEZrMZjY2NCAsLQ3h4OFJSUnyK4zlz5uDMmTM4ceIEAEiHvp88eRIHDhzAkSNHpMkJ6+rq8O2336KgoABqtRoRERHIzs7Gz3/+cwwaNKjDz75fcqAYwEpKSgQALly4cGl3KSkpCXSauqBXXnlFpKamCrVaLSZOnCi2b9/e5ecyB3LhwqWzhTmQCxcuA3npyRw4oK/T7fF4cO7cOekE+854z/spKSnp09es7CmMN7gx3s4JIdDQ0ICkpKSgPtyPObBjjDe4Md7OMQe2xb+Z4MZ4g1tfyIED+vByuVyO5OTkbj0nPDx8QPxxejHe4MZ4O2YwGPzcm8BjDrwwxhvcGG/HmAPbx7+Z4MZ4g1sgc2Dw7r4kIiIiIiIiCjAW3URERERERER+wqK7izQaDZYuXXpJ17jtTxhvcGO81F0D7XfIeIMb46XuGmi/Q8Yb3Bhv7xvQE6kRERERERER+RNHuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRERERERERH7CorsLVq9ejbS0NGi1WmRlZWHnzp2B7lKPWLZsGWQymc+SkJAgPS6EwLJly5CUlISQkBBcffXVKCgoCGCPu2fHjh24+eabkZSUBJlMhk8++cTn8a7EZ7fb8fDDDyMmJgahoaG45ZZbUFpa2otRdN2F4r3rrrvavN+TJ0/2adOf4l2xYgUuv/xy6PV6xMXFYe7cuTh27JhPm2B7jwOFOZA5sD98PpgDmQP9hTmQObA/fD6YA/t2DmTRfQEbNmzAokWL8NRTTyE/Px9XXXUVZs2ahbNnzwa6az1izJgxKC8vl5ZDhw5Jjz3//PNYuXIlVq1ahW+//RYJCQm47rrr0NDQEMAed53FYsH48eOxatWqdh/vSnyLFi3Cxo0bsX79euzatQuNjY2YPXs23G53b4XRZReKFwBuuOEGn/d706ZNPo/3p3i3b9+OBx98EHv37kVubi5cLhdmzpwJi8UitQm29zgQmAOZA/vL54M5kDnQH5gDmQP7y+eDObCP50BBnbriiivEwoULfdaNGjVKPPnkkwHqUc9ZunSpGD9+fLuPeTwekZCQIP70pz9J62w2mzAYDOLvf/97L/Ww5wAQGzdulO53Jb76+nqhUqnE+vXrpTZlZWVCLpeLzZs391rfL0breIUQYsGCBWLOnDkdPqc/xyuEEEajUQAQ27dvF0IE/3vcW5gDmQP74+eDOTD43+PewhzIHNgfPx/MgX3vPeZIdyccDgfy8vIwc+ZMn/UzZ87E7t27A9SrnlVUVISkpCSkpaXhpz/9KU6dOgUAKC4uRkVFhU/sGo0G06dPD4rYuxJfXl4enE6nT5ukpCRkZmb229/Btm3bEBcXhxEjRuC+++6D0WiUHuvv8ZpMJgBAVFQUgIH7Hvck5kDmwGD7fDAHBv973JOYA5kDg+3zwRwYuPeYRXcnqqur4Xa7ER8f77M+Pj4eFRUVAepVz8nOzsa7776LL774Am+88QYqKiowZcoU1NTUSPEFa+xdia+iogJqtRqRkZEdtulPZs2ahXXr1mHLli3461//im+//RY/+tGPYLfbAfTveIUQWLx4Ma688kpkZmYCGJjvcU9jDmQODKbPB3MgpPvB+h73NOZA5sBg+nwwB0K6H4j3WNmjWwtSMpnM574Qos26/mjWrFnSz2PHjkVOTg6GDRuGd955R5pYIVhj97qY+Prr72DevHnSz5mZmZg0aRJSU1Px73//G7feemuHz+sP8T700EM4ePAgdu3a1eaxgfQe+0uw5gHmwIH1+WAObBbM77G/BGseYA4cWJ8P5sBmgXqPOdLdiZiYGCgUijZ7OoxGY5u9JsEgNDQUY8eORVFRkTR7ZbDG3pX4EhIS4HA4UFdX12Gb/iwxMRGpqakoKioC0H/jffjhh/Hpp59i69atSE5OltbzPb50zIHMgcH8+WAO7L8x9xbmQObAYP58MAf2bswsujuhVquRlZWF3Nxcn/W5ubmYMmVKgHrlP3a7HYWFhUhMTERaWhoSEhJ8Ync4HNi+fXtQxN6V+LKysqBSqXzalJeX4/Dhw0HxO6ipqUFJSQkSExMB9L94hRB46KGH8PHHH2PLli1IS0vzeZzv8aVjDmQODObPB3Ng/4u5tzEHMgcG8+eDObCXY+7RadmC0Pr164VKpRJvvfWWOHLkiFi0aJEIDQ0Vp0+fDnTXLtnjjz8utm3bJk6dOiX27t0rZs+eLfR6vRTbn/70J2EwGMTHH38sDh06JH72s5+JxMREYTabA9zzrmloaBD5+fkiPz9fABArV64U+fn54syZM0KIrsW3cOFCkZycLL766ivx/fffix/96Edi/PjxwuVyBSqsDnUWb0NDg3j88cfF7t27RXFxsdi6davIyckRgwYN6rfx/s///I8wGAxi27Ztory8XFqampqkNsH2HgcCcyBzYH/5fDAHMgf6A3Mgc2B/+XwwB/btHMiiuwteeeUVkZqaKtRqtZg4caI0FX1/N2/ePJGYmChUKpVISkoSt956qygoKJAe93g8YunSpSIhIUFoNBoxbdo0cejQoQD2uHu2bt0qALRZFixYIIToWnxWq1U89NBDIioqSoSEhIjZs2eLs2fPBiCaC+ss3qamJjFz5kwRGxsrVCqVGDx4sFiwYEGbWPpTvO3FCkCsWbNGahNs73GgMAcyB/aHzwdzIHOgvzAHMgf2h88Hc2DfzoGy850mIiIiIiIioh7Gc7qJiIiIiIiI/IRFNxEREREREZGfsOgmIiIiIiIi8hMW3URERERERER+wqKbiIiIiIiIyE9YdBMRERERERH5CYtuIiIiIiIiIj9h0U1ERERERETkJyy6aUBZtmwZJkyYEOhuEBH1OuY/IhrImAMpkGRCCBHoThD1BJlM1unjCxYswKpVq2C32xEdHd1LvSIi8j/mPyIayJgDqa9j0U1Bo6KiQvp5w4YN+MMf/oBjx45J60JCQmAwGALRNSIiv2L+I6KBjDmQ+joeXk5BIyEhQVoMBgNkMlmbda0PLbrrrrswd+5cPPvss4iPj0dERASWL18Ol8uFX//614iKikJycjLefvttn9cqKyvDvHnzEBkZiejoaMyZMwenT5/u3YCJiM5j/iOigYw5kPo6Ft004G3ZsgXnzp3Djh07sHLlSixbtgyzZ89GZGQk9u3bh4ULF2LhwoUoKSkBADQ1NeGaa65BWFgYduzYgV27diEsLAw33HADHA5HgKMhIuo65j8iGsiYA6m3sOimAS8qKgovvfQSRo4ciXvuuQcjR45EU1MTfvvb3yI9PR1LliyBWq3G119/DQBYv3495HI53nzzTYwdOxYZGRlYs2YNzp49i23btgU2GCKibmD+I6KBjDmQeosy0B0gCrQxY8ZALv9h/1N8fDwyMzOl+wqFAtHR0TAajQCAvLw8nDhxAnq93mc7NpsNJ0+e7J1OExH1AOY/IhrImAOpt7DopgFPpVL53JfJZO2u83g8AACPx4OsrCysW7euzbZiY2P911Eioh7G/EdEAxlzIPUWFt1E3TRx4kRs2LABcXFxCA8PD3R3iIh6DfMfEQ1kzIF0sXhON1E33XnnnYiJicGcOXOwc+dOFBcXY/v27Xj00UdRWloa6O4REfkN8x8RDWTMgXSxWHQTdZNOp8OOHTswePBg3HrrrcjIyMA999wDq9XKvZ5EFNSY/4hoIGMOpIslE0KIQHeCiIiIiIiIKBhxpJuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTUREREREROQnLLqJiIiIiIiI/IRFNxEREREREZGfsOgmIiIiIiIi8hMW3URERERERER+wqKbiIiIiIiIyE9YdBMRERERERH5CYtuIiIiIiIiIj9h0U1ERERERETkJyy6iYiIiIiIiPyERTcRERERERGRn7DoJiIiIiIiIvITFt1EREREREREfsKimwastWvXQiaTSYtSqURiYiJ++tOfoqioKNDdIyIiIiKiIKAMdAeIAm3NmjUYNWoUbDYbvv76a/zxj3/E1q1bcfToUURGRga6e0RERERE1I+x6KYBLzMzE5MmTQIAXH311XC73Vi6dCk++eQT3H333QHuHRERERER9Wc8vJyoFW8BXllZGeCeEBERERFRf8eim6iV4uJiAMCIESMC3BMiIiIiIurveHg5DXhutxsul0s6p/uZZ57BtGnTcMsttwS6a0RERERE1M+x6KYBb/LkyT73MzIy8K9//QtKJT8eRERERER0aXh4OQ147777Lr799lts2bIF999/PwoLC/Gzn/0s0N0iIiIiIqIgwKE8GvAyMjKkydOuueYauN1uvPnmm/jnP/+Jn/zkJwHuHRERERER9Wcc6SZq5fnnn0dkZCT+8Ic/wOPxBLo7RERERETUj7HoJmolMjISS5YsQWFhIT744INAd4eIiIiIiPoxFt1E7Xj44YcxePBgPP3003C73YHuDhERERER9VMyIYQIdCeIiIiIiIiIghFHuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRER+tmPHDtx8881ISkqCTCbDJ598csHnbN++HVlZWdBqtRg6dCj+/ve/t2nz0UcfYfTo0dBoNBg9ejQ2btzoh94TEV0a5kAiGuhYdBMR+ZnFYsH48eOxatWqLrUvLi7GjTfeiKuuugr5+fn47W9/i0ceeQQfffSR1GbPnj2YN28e5s+fjwMHDmD+/Pm4/fbbsW/fPn+FQUR0UZgDiWig4+zlRES9SCaTYePGjZg7d26HbX7zm9/g008/RWFhobRu4cKFOHDgAPbs2QMAmDdvHsxmMz7//HOpzQ033IDIyEh8+OGHfus/EdGlYA4k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+/btIj09XfziF78IVAg+uhvPmjVrhFKpFKtXrxYnT54Uu3btEpMmTRJXXHFFoEJo40L/H/tbbugIcyBzYCAwB/btHBio/MeiuwteeeUVkZqaKtRqtZg4caJ0SaL+znvNYpVKJZKSksStt94qCgoKpMc9Ho9YunSpSEhIEBqNRkybNk0cOnQogD3unq1btwoAbZYFCxYIIboWn9VqFQ899JCIiooSISEhYvbs2eLs2bMBiObCOou3qalJzJw5U8TGxgqVSiUGDx4sFixY0CaW/hRve7ECEGvWrJHaBNt7fDE6y18LFiwQ06dP92m/bds2cdlllwm1Wi2GDBkiXn311V7ucee6E8/06dM7zQF9RXffo5b64hdOIbofU2FhoZgxY4YICQkRycnJYvHixT470AKtu/G89NJLYvTo0SIkJEQkJiaKO++8U5SWlvZyrzt2of+P/TE3dIQ5kDkwEJgD+24ODFT+kwnRD8f5iYiIiIiIiPoBntNNRERERERE5CcsuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRERERERERH7CopuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTQPKsmXLMGHChEB3g4iIiIiIBgiZEEIEuhNEPUEmk3X6+IIFC7Bq1SrY7XZER0f3Uq+IiIiIiGggY9FNQaOiokL6ecOGDfjDH/6AY8eOSetCQkJgMBgC0TUiIiIiIhqgeHg5BY2EhARpMRgMkMlkbda1Prz8rrvuwty5c/Hss88iPj4eERERWL58OVwuF379618jKioKycnJePvtt31eq6ysDPPmzUNkZCSio6MxZ84cnD59uncDJiIiIiKiPo9FNw14W7Zswblz57Bjxw6sXLkSy5Ytw+zZsxEZGYl9+/Zh4cKFWLhwIUpKSgAATU1NuOaaaxAWFoYdO3Zg165dCAsLww033ACHwxHgaIiIiIiIqC9h0U0DXlRUFF566SWMHDkS99xzD0aOHImmpib89re/RXp6OpYsWQK1Wo2vv/4aALB+/XrI5XK8+eabGDt2LDIyMrBmzRqcPXsW27ZtC2wwRERERETUpygD3QGiQBszZgzk8h/2P8XHxyMzM1O6r1AoEB0dDaPRCADIy8vDiRMnoNfrfbZjs9lw8uTJ3uk0ERERERH1Cyy6acBTqVQ+92UyWbvrPB4PAMDj8SArKwvr1q1rs63Y2Fj/dZSIiIiIiPodFt1E3TRx4kRs2LABcXFxCA8PD3R3iIiIiIioD+M53UTddOeddyImJgZz5szBzp07UVxcjO3bt+PRRx9FaWlpoLtHRERERER9CItuom7S6XTYsWMHBg8ejFtvvRUZGRm45557YLVaOfJNREREREQ+ZEIIEehOEBEREREREQUjjnQTERERERER+QmLbiIiIiIiIiI/YdFNRERERERE5CcsuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRERERERERH7CopuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTUREREREROQnLLqJiIiIiIiI/OT/A0Evmh/XOHQYAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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u+OT97gVdM+bNw/x8fEICQlBYmIitm3b1mD9LVu2IDExESEhIejcuTMWLFjgVmP1avt2YNEisRwaKl6skuc984ycefjhB+D228X1hkldPN7NKykJWLBAnjCqshL47DMxO52ZKQbNkrg44PnnxS7kjz1Wv+utn5+4TOILLwBr1gDDhsm/y88XL4YGDRKDcwbf5uPq94QenTsnnlsA4Npr5RtSWujZU97/xo3yjOpEEjXOzZmZmejRoweCg4PRo0cPrF27tsn7VUt1NTBhgtyTavRooEULTZpiCNJcLoA4P9K5c9q1xVe5HHSvXr0a06ZNw8yZM5Gbm4uBAwdi2LBhKKjbL/E3x48fx/DhwzFw4EDk5ubi2WefxZNPPonMzMwmN14Ptm8HRo6ULyInTABattSyRebVogWQkSGvnfr998D11wNvvCFmv8nzeLybX+/ewOrV4oSFrVvb/i40VFxB4J13gH//W5xfITCw8fe85hqxe/nSpeIxKtm2DUhJEZcue+MNcZkXBuDG5+r3hF7997/y36NymR0tBAXJsw4XFQFffqlte0hf1Dg379y5E6NGjcKYMWPw3XffYcyYMXjggQfw7bffur1ftVy4ADz0kNhDCxCHdSqDSqqvXz95ZveffxZjF+WNdVKfRRBcu+Tp168fbrzxRsyfP9+6rXv37hg5ciTS7Sz6+re//Q3r169HvmImkEmTJuG7777Dzp07ndpneXk5IiIisGRJGZo3D3eluU0mCOKjpka8m3b5svhHeuSIuN7dL7/Iddu0Ad57T8z4kHpOngSefrr+9muuETN3nTuLmbvwcHFW5cBAsaugn584K6zFom77Ll8uxyOPRKCsrAzh4d79e/U0LY93oAwffBDOm1heJAjiybisTDx+OnRo+veZIABffy33BrKnc2dxDGvHjmL39ZYtxVnRg4PtH79qH8OuMNPx7i5Xvyfq0vocX1MDlJQATz0lb09L035uli1bgHnz5Ocvvyz29goM1Ncx4Gv0cMyrcW4eNWoUysvL8YU0QRGAu+66C61atcLK32bfauqxDjh/vAuCOGyzpkac6LO8HDh9Gti7Vw62Jc8+Kw5jooYVFdl+zwFir9GbbwbatwfCwsQbfv7++jvXasWTx3uAK5UrKyuRk5ODZ555xmZ7SkoKduzYYfc1O3fuREpKis22oUOHYvHixaiqqkKgnbRJRUUFKhRT6Zb9lsZ85JFyV5rrdaWl4vI7pI3Tp8WH9sS/UxfvZ+mO1sc7UI7HH2/av4GM4dgx8WFM5jje3eXO94QRzvFOxg9eNXOm1i0gkbbHvFrn5p07d2L69On16mRkZLi9X8A7x/srr3jsrXzO5s3igxzx3PHuUtBdUlKCmpoaREVF2WyPiopCUVGR3dcUFRXZrV9dXY2SkhLE2FkIMz09HS+++KKdd+voSnOJNFVaWvpbxtaYeLwTOc/ox7u73Pme4DFPZqDVMa/WudlRHek93dkvwOOdzMETx7tLQbfEUqe/gSAI9bY1Vt/edklaWhpSU1Otz8+fP4+4uDgUFBTo/qKmvLwcHTt2xKlTp3Tf1ZBtVUdZWRliY2PRuu4AWYPi8e6Ykf4u2VZ1mO14d5cr3xM85r2DbVWHXo55Nc7Nzrynq/vl8e4dbKs6PHm8uxR0t23bFv7+/vXuaBUXF9e78yWJjo62Wz8gIABtpBmx6ggODkawnWlDIyIidP+fIwkPD2dbVWCktvoZfHA/j3fnGenvkm1Vh9GPd3e58z3BY9672FZ1aHXMq3VudlRHek939gvwePc2tlUdnjjeXXqHoKAgJCYmIisry2Z7VlYWBgwYYPc1ycnJ9epv2rQJSUlJdsd3EpE+8Hgnosa48z1BRO5T69zsqI70njzWiZpIcNGqVauEwMBAYfHixcLBgweFadOmCaGhocKJEycEQRCEZ555RhgzZoy1/rFjx4TmzZsL06dPFw4ePCgsXrxYCAwMFP7zn/84vc+ysjIBgFBWVuZqc72ObVUH26oNHu8NY1vVwbYaS2PfE40x0mfItqqDbXWNGufm//3vf4K/v7/w6quvCvn5+cKrr74qBAQECLt27XJ6v87Qw+fnLLZVHb7aVpeDbkEQhPfff1+Ii4sTgoKChBtvvFHYsmWL9Xfjxo0TBg0aZFM/Oztb6Nu3rxAUFCR06tRJmD9/vkv7u3r1qvDCCy8IV69edae5XsW2qoNt1Q6Pd8fYVnWwrcbT0PdEY4z0GbKt6mBbXafGufnf//63kJCQIAQGBgrdunUTMjMzXdqvM/Ty+TmDbVWHr7bV5XW6iYiIiIiIiMg5vjnzCxEREREREZEXMOgmIiIiIiIiUgmDbiIiIiIiIiKVMOgmIiIiIiIiUokmQfe8efMQHx+PkJAQJCYmYtu2bQ3W37JlCxITExESEoLOnTtjwYIF9epkZmaiR48eCA4ORo8ePbB27Vqvt3XNmjW488470a5dO4SHhyM5ORkbN260qbN06VJYLJZ6j6tXr3q1rdnZ2Xbb8eOPP9rU08PnOn78eLtt7dmzp7WOWp/r1q1bMWLECLRv3x4WiwXr1q1r9DVa/r0ahRrfAWpR47hSg1p/q2pwta1afa7p6em46aabEBYWhsjISIwcORKHDh1q9HVa/r3qAc/xPMfzHO/b53hHXP1u0MqsWbPq/a1FR0dr3SwAjf/NCoKAWbNmoX379mjWrBkGDx6MAwcO6LKt9o79/v37e72dzpzrPfK5Nnn+cxdJa/wtWrRIOHjwoPDUU08JoaGhwsmTJ+3Wl9YWfOqpp4SDBw8KixYtqre24I4dOwR/f3/hlVdeEfLz84VXXnml3tqC3mjrU089Jbz22mvC7t27hZ9++klIS0sTAgMDhX379lnrLFmyRAgPDxcKCwttHk3lals3b94sABAOHTpk047q6mprHb18rufPn7dp46lTp4TWrVsLL7zwgrWOWp/rhg0bhJkzZwqZmZkCAGHt2rUN1tfy79Uo1PgO0EtbnTmu1KLG36pe2qrV5zp06FBhyZIlwg8//CDk5eUJd999txAbGytcvHjR4Wu0/Fz1gOd4nuN5jvftc7wjrv5daOmFF14QevbsafO3VlxcrHWzBEFo/G/21VdfFcLCwoTMzExh//79wqhRo4SYmBihvLxcd20dN26ccNddd9l8zqWlpV5vpzPnek98rl4Pum+++WZh0qRJNtu6desmPPPMM3brP/3000K3bt1stj3++ONC//79rc8feOAB4a677rKpM3ToUGH06NFebas9PXr0EF588UXr8yVLlggRERFNapc9rrZVOiGfO3fO4Xvq9XNdu3atYLFYhBMnTli3qfW5KjlzQtby79Uo1PgOUIsax5U3eOpv1RtcCbq1/lyLi4sFAA2uS6uXz1UrPMfzHM9zvG+f4x3xxPHmLS+88ILQp08frZvRqLp/s7W1tUJ0dLTw6quvWrddvXpViIiIEBYsWKBBC2WOgu57771Xk/Y0pO653lOfq1e7l1dWViInJwcpKSk221NSUrBjxw67r9m5c2e9+kOHDsXevXtRVVXVYB1H76lWW+uqra3FhQsX0Lp1a5vtFy9eRFxcHDp06IB77rkHubm5brezqW3t27cvYmJiMGTIEGzevNnmd3r9XBcvXow77rgDcXFxNts9/bm6Q6u/V6NQ6ztAL22VNHRc6YVWn2tTaP25lpWVAUC973QlI36unsJzvIjneJ7jffUc74gn/i687fDhw2jfvj3i4+MxevRoHDt2TOsmNer48eMoKiqy+ZyDg4MxaNAg3X7O2dnZiIyMRNeuXfHYY4+huLhY6ybVO9d76nP1atBdUlKCmpoaREVF2WyPiopCUVGR3dcUFRXZrV9dXY2SkpIG6zh6T7XaWtebb76JS5cu4YEHHrBu69atG5YuXYr169dj5cqVCAkJwS233ILDhw97ta0xMTFYuHAhMjMzsWbNGiQkJGDIkCHYunWrtY4eP9fCwkJ88cUXmDhxos12NT5Xd2j192oUan0H6KWtzhxXeqHV5+oOPXyugiAgNTUVt956K3r16uWwnpE+V0/jOZ7neJ7jffsc74gnjjdv6tevH5YtW4aNGzdi0aJFKCoqwoABA1BaWqp10xokfZZG+ZyHDRuGf/3rX/jmm2/w5ptvYs+ePfjd736HiooKzdpk71zvqc81wHPNdJ7FYrF5LghCvW2N1a+73dX3dJa777ty5UrMmjULn376KSIjI63b+/fvbzNJwC233IIbb7wR7777LubOneu1tiYkJCAhIcH6PDk5GadOncKcOXNw2223ufWearVVaenSpWjZsiVGjhxps13Nz9VVWv69GoUa3wFqUeO40gstP1dX6OFznTp1Kr7//nts37690bpG+VzVwnM8z/E8x/v2Od4Ro3wuw4YNs5Z79+6N5ORkXHvttfjoo4+QmpqqYcucY5TPedSoUdZyr169kJSUhLi4OHz++ef4wx/+oEmbGjrXN/Vz9Wqmu23btvD39693V6C4uLje3QNJdHS03foBAQFo06ZNg3UcvadabZWsXr0aEyZMwCeffII77rijwbp+fn646aabmnS3tiltVerfv79NO/T2uQqCgA8//BBjxoxBUFBQg3U98bm6Q6u/V6NQ6ztAL221p+5xpRdafa6e4s3P9YknnsD69euxefNmdOjQocG6Rv9cm4Ln+Pp4jnf+fXmONy9P/Q1rJTQ0FL1799bluVxJmmHdqJ9zTEwM4uLiNPucHZ3rPfW5ejXoDgoKQmJiIrKysmy2Z2VlYcCAAXZfk5ycXK/+pk2bkJSUhMDAwAbrOHpPtdoKiHe/x48fjxUrVuDuu+9udD+CICAvLw8xMTFeb2tdubm5Nu3Q0+cKiMt0HDlyBBMmTGh0P574XN2h1d+rUaj1HaCXttpT97jSC60+V0/xxucqCAKmTp2KNWvW4JtvvkF8fHyjrzH659oUPMfXx3O8823lOd68PPU3rJWKigrk5+fr8lyuFB8fj+joaJvPubKyElu2bDHE51xaWopTp055/XNu7Fzvsc/VpencPEBaMmDx4sXCwYMHhWnTpgmhoaHWWSqfeeYZYcyYMdb60vIM06dPFw4ePCgsXry43vIM//vf/wR/f3/h1VdfFfLz84VXX33Vo8teONvWFStWCAEBAcL7779vM/39+fPnrXVmzZolfPnll8LRo0eF3Nxc4ZFHHhECAgKEb7/91qttffvtt4W1a9cKP/30k/DDDz8IzzzzjABAyMzMtNbRy+cq+dOf/iT069fP7nuq9bleuHBByM3NFXJzcwUAwltvvSXk5uZal7jQ09+rUajxHaCXtjpzXKlFjb9VvbRVq8/1L3/5ixARESFkZ2fbfKdfvnzZWkdPn6se8BzPczzP8b59jneksb8LPfnrX/8qZGdnC8eOHRN27dol3HPPPUJYWJgu2trY3+yrr74qRERECGvWrBH2798vPPjgg5otGdZQWy9cuCD89a9/FXbs2CEcP35c2Lx5s5CcnCxcc801Xm+rM+d6T3yuXg+6BUEQ3n//fSEuLk4ICgoSbrzxRpvlV8aNGycMGjTIpn52drbQt29fISgoSOjUqZMwf/78eu/573//W0hISBACAwOFbt26eexizJW2Dho0SABQ7zFu3DhrnWnTpgmxsbFCUFCQ0K5dOyElJUXYsWOH19v62muvCddee60QEhIitGrVSrj11luFzz//vN576uFzFQRxHc9mzZoJCxcutPt+an2u0rIrjv5P9fb3ahRqfAfooa3OHldqUOtvVQ9t1epztddGAMKSJUusdfT0ueoFz/E8x/Mc79vneEca+rvQE2kN5sDAQKF9+/bCH/7wB+HAgQNaN0sQhMb/Zmtra4UXXnhBiI6OFoKDg4XbbrtN2L9/v+7aevnyZSElJUVo166dEBgYKMTGxgrjxo0TCgoKvN5OZ871nvhcLb/tjIiIiIiIiIg8zKtjuomIiIiIiIh8CYNuIiIiIiIiIpUw6CYiIiIiIiJSCYNuIiIiIiIiIpUw6CYiIiIiIiJSCYNuIiIiIiIiIpUw6CYiIiIiIiJSCYNuIiIiIiIiIpUw6DaBwYMHY9q0aVo3g4g0cuLECVgsFuTl5Tn9mqVLl6Jly5aqtYmIiIiIRAy6iRffREREREQGNX78eIwcOVLrZlADGHQTERERERERqYRBt0lUV1dj6tSpaNmyJdq0aYPnnnsOgiAAACorK/H000/jmmuuQWhoKPr164fs7GwAQHZ2Nh555BGUlZXBYrHAYrFg1qxZAIDly5cjKSkJYWFhiI6OxkMPPYTi4mKN/oVEvu3LL7/Erbfeaj3G77nnHhw9etRu3ezsbFgsFnz++efo06cPQkJC0K9fP+zfv79e3Y0bN6J79+5o0aIF7rrrLhQWFlp/t2fPHtx5551o27YtIiIiMGjQIOzbt0+1fyORL7lw4QIefvhhhIaGIiYmBm+//bbNcLHGzsHScb5x40b07dsXzZo1w+9+9zsUFxfjiy++QPfu3REeHo4HH3wQly9ftr5u8ODBeOKJJzBt2jS0atUKUVFRWLhwIS5duoRHHnkEYWFhuPbaa/HFF19YX1NTU4MJEyYgPj4ezZo1Q0JCAt555x2vfVZEREbHoNskPvroIwQEBODbb7/F3Llz8fbbb+Of//wnAOCRRx7B//73P6xatQrff/89/vjHP+Kuu+7C4cOHMWDAAGRkZCA8PByFhYUoLCzEjBkzAIjB+ksvvYTvvvsO69atw/HjxzF+/HgN/5VEvuvSpUtITU3Fnj178PXXX8PPzw//7//9P9TW1jp8zf/93/9hzpw52LNnDyIjI/H73/8eVVVV1t9fvnwZc+bMwccff4ytW7eioKDAevwDYlAwbtw4bNu2Dbt27UKXLl0wfPhwXLhwQdV/K5EvSE1Nxf/+9z+sX78eWVlZ2LZtm81NLWfPwbNmzcJ7772HHTt24NSpU3jggQeQkZGBFStW4PPPP0dWVhbeffddm9d89NFHaNu2LXbv3o0nnngCf/nLX/DHP/4RAwYMwL59+zB06FCMGTPGGqzX1taiQ4cO+OSTT3Dw4EH8/e9/x7PPPotPPvlE1c+IiMg0BDK8QYMGCd27dxdqa2ut2/72t78J3bt3F44cOSJYLBbh9OnTNq8ZMmSIkJaWJgiCICxZskSIiIhodD+7d+8WAAgXLlzwaPuJyHXFxcUCAGH//v3C8ePHBQBCbm6uIAiCsHnzZgGAsGrVKmv90tJSoVmzZsLq1asFQRCPewDCkSNHrHXef/99ISoqyuE+q6urhbCwMOGzzz5T5x9F5CPKy8uFwMBA4d///rd12/nz54XmzZsLTz31lN3X1D0HS8f5V199Za2Tnp4uABCOHj1q3fb4448LQ4cOtT4fNGiQcOutt1qfV1dXC6GhocKYMWOs2woLCwUAws6dOx3+GyZPnizcd999zv+jiUg148aNE+69916tm0ENYKbbJPr37w+LxWJ9npycjMOHD2Pv3r0QBAFdu3ZFixYtrI8tW7Y47Joqyc3Nxb333ou4uDiEhYVh8ODBAICCggI1/ylEZMfRo0fx0EMPoXPnzggPD0d8fDyAho/H5ORka7l169ZISEhAfn6+dVvz5s1x7bXXWp/HxMTYdF8tLi7GpEmT0LVrV0RERCAiIgIXL17kdwBREx07dgxVVVW4+eabrdsiIiKQkJBgfe7sOfj666+3lqOiotC8eXN07tzZZlvdoWHK1/j7+6NNmzbo3bu3zWsA2LxuwYIFSEpKQrt27dCiRQssWrSI3wVERE4K0LoBpD5/f3/k5OTA39/fZnuLFi0cvubSpUtISUlBSkoKli9fjnbt2qGgoABDhw5FZWWl2k0mojpGjBiBjh07YtGiRWjfvj1qa2vRq1cvl49H5c25wMDAer8TfpsLAhBnQz179iwyMjIQFxeH4OBgJCcn8zuAqImk40x5PCq3u3IOVh7HFovF7nFddxiKvTp13weA9XWffPIJpk+fjjfffBPJyckICwvDG2+8gW+//dblfzsRkS9i0G0Su3btqve8S5cu6Nu3L2pqalBcXIyBAwfafW1QUBBqampstv34448oKSnBq6++io4dOwIA9u7dq07jiahBpaWlyM/PxwcffGA9jrdv397o63bt2oXY2FgAwLlz5/DTTz+hW7duTu9327ZtmDdvHoYPHw4AOHXqFEpKStz4FxCR0rXXXovAwEDs3r3beo4tLy/H4cOHMWjQIN2dg7dt24YBAwZg8uTJ1m2N9ZYjIiIZu5ebxKlTp5CamopDhw5h5cqVePfdd/HUU0+ha9euePjhhzF27FisWbMGx48fx549e/Daa69hw4YNAIBOnTrh4sWL+Prrr1FSUoLLly8jNjYWQUFBePfdd3Hs2DGsX78eL730ksb/SiLf1KpVK7Rp0wYLFy7EkSNH8M033yA1NbXR182ePRtff/01fvjhB4wfPx5t27Z1aR3P6667Dh9//DHy8/Px7bff4uGHH0azZs2a8C8hIgAICwvDuHHj8H//93/YvHkzDhw4gEcffRR+fn6wWCy6Owdfd9112Lt3LzZu3IiffvoJzz//PPbs2aNZe4iIjIZBt0mMHTsWV65cwc0334wpU6bgiSeewJ///GcAwJIlSzB27Fj89a9/RUJCAn7/+9/j22+/td49HzBgACZNmoRRo0ahXbt2eP3119GuXTssXboU//73v9GjRw+8+uqrmDNnjpb/RCKf5efnh1WrViEnJwe9evXC9OnT8cYbbzT6uldffRVPPfUUEhMTUVhYiPXr1yMoKMjp/X744Yc4d+4c+vbtizFjxuDJJ59EZGRkU/4pRPSbt956C8nJybjnnntwxx134JZbbkH37t0REhKiu3PwpEmT8Ic//AGjRo1Cv379UFpaapP1JiKihlkE5QA+IiIyvOzsbNx+++04d+4cWrZsqXVziMgJly5dwjXXXIM333wTEyZM0Lo5RETkQRzTTURERORlubm5+PHHH3HzzTejrKwMs2fPBgDce++9GreMiIg8jUE3ERERkQbmzJmDQ4cOISgoCImJidi2bRvatm2rdbOIiMjD2L2ciIiIiIiISCWcSI2IiIiIiIhIJQy6iYiIiIiIiFTCoJuIiIiIiIhIJQy6iYiI/n/7dSwAAAAAMMjfehT7yiIAgIl0AwAAwES6AQAAYCLdAAAAMJFuAAAAmASLllb1Q8WH4wAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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ePBg3HrrrcjIyMA999wDq9XKvZ5EFNSY/4hoIGMOpIslE0KIQHeCiIiIiIiIKBhxpJuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTUREREREROQnLLqJiIiIiIiI/IRFNxEREREREZGfsOgmIiIiIiIi8hMW3URERERERER+wqKbiIiIiIiIyE9YdBMRERERERH5CYtuIiIiIiIiIj9h0U1ERERERETkJyy6iYiIiIiIiPyERTcRERERERGRn7DoJiIiIiIiIvITFt1EREREREREfsKimwastWvXQiaTSYtSqURiYiJ++tOfoqioKNDdIyIiIiKiIKAMdAeIAm3NmjUYNWoUbDYbvv76a/zxj3/E1q1bcfToUURGRga6e0RERERE1I+x6KYBLzMzE5MmTQIAXH311XC73Vi6dCk++eQT3H333QHuHRERERER9Wc8vJyoFW8BXllZGeCeEBERERFRf8eim6iV4uJiAMCIESMC3BMiIiIiIurveHg5DXhutxsul0s6p/uZZ57BtGnTcMsttwS6a0RERERE1M+x6KYBb/LkyT73MzIy8K9//QtKJT8eRERERER0aXh4OQ147777Lr799lts2bIF999/PwoLC/Gzn/0s0N0iIiIiIqIgwKE8GvAyMjKkydOuueYauN1uvPnmm/jnP/+Jn/zkJwHuHRERERER9Wcc6SZq5fnnn0dkZCT+8Ic/wOPxBLo7RERERETUj7HoJmolMjISS5YsQWFhIT744INAd4eIiIiIiPoxFt1E7Xj44YcxePBgPP3003C73YHuDhERERER9VMyIYQIdCeIiIiIiIiIghFHuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRER+tmPHDtx8881ISkqCTCbDJ598csHnbN++HVlZWdBqtRg6dCj+/ve/t2nz0UcfYfTo0dBoNBg9ejQ2btzoh94TEV0a5kAiGuhYdBMR+ZnFYsH48eOxatWqLrUvLi7GjTfeiKuuugr5+fn47W9/i0ceeQQfffSR1GbPnj2YN28e5s+fjwMHDmD+/Pm4/fbbsW/fPn+FQUR0UZgDiWig4+zlRES9SCaTYePGjZg7d26HbX7zm9/g008/RWFhobRu4cKFOHDgAPbs2QMAmDdvHsxmMz7//HOpzQ033IDIyEh8+OGHfus/EdGlYA4k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+/btIj09XfziF78IVAg+uhvPmjVrhFKpFKtXrxYnT54Uu3btEpMmTRJXXHFFoEJo40L/H/tbbugIcyBzYCAwB/btHBio/MeiuwteeeUVkZqaKtRqtZg4caJ0SaL+znvNYpVKJZKSksStt94qCgoKpMc9Ho9YunSpSEhIEBqNRkybNk0cOnQogD3unq1btwoAbZYFCxYIIboWn9VqFQ899JCIiooSISEhYvbs2eLs2bMBiObCOou3qalJzJw5U8TGxgqVSiUGDx4sFixY0CaW/hRve7ECEGvWrJHaBNt7fDE6y18LFiwQ06dP92m/bds2cdlllwm1Wi2GDBkiXn311V7ucee6E8/06dM7zQF9RXffo5b64hdOIbofU2FhoZgxY4YICQkRycnJYvHixT470AKtu/G89NJLYvTo0SIkJEQkJiaKO++8U5SWlvZyrzt2of+P/TE3dIQ5kDkwEJgD+24ODFT+kwnRD8f5iYiIiIiIiPoBntNNRERERERE5CcsuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRERERERERH7CopuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTQPKsmXLMGHChEB3g4iIiIiIBgiZEEIEuhNEPUEmk3X6+IIFC7Bq1SrY7XZER0f3Uq+IiIiIiGggY9FNQaOiokL6ecOGDfjDH/6AY8eOSetCQkJgMBgC0TUiIiIiIhqgeHg5BY2EhARpMRgMkMlkbda1Prz8rrvuwty5c/Hss88iPj4eERERWL58OVwuF379618jKioKycnJePvtt31eq6ysDPPmzUNkZCSio6MxZ84cnD59uncDJiIiIiKiPo9FNw14W7Zswblz57Bjxw6sXLkSy5Ytw+zZsxEZGYl9+/Zh4cKFWLhwIUpKSgAATU1NuOaaaxAWFoYdO3Zg165dCAsLww033ACHwxHgaIiIiIiIqC9h0U0DXlRUFF566SWMHDkS99xzD0aOHImmpib89re/RXp6OpYsWQK1Wo2vv/4aALB+/XrI5XK8+eabGDt2LDIyMrBmzRqcPXsW27ZtC2wwRERERETUpygD3QGiQBszZgzk8h/2P8XHxyMzM1O6r1AoEB0dDaPRCADIy8vDiRMnoNfrfbZjs9lw8uTJ3uk0ERERERH1Cyy6acBTqVQ+92UyWbvrPB4PAMDj8SArKwvr1q1rs63Y2Fj/dZSIiIiIiPodFt1E3TRx4kRs2LABcXFxCA8PD3R3iIiIiIioD+M53UTddOeddyImJgZz5szBzp07UVxcjO3bt+PRRx9FaWlpoLtHRERERER9CItuom7S6XTYsWMHBg8ejFtvvRUZGRm45557YLVaOfJNREREREQ+ZEIIEehOEBEREREREQUjjnQTERERERER+QmLbiIiIiIiIiI/YdFNRERERERE5CcsuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRERERERERH7CopuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTUREREREROQnLLqJiIiIiIiI/OT/A0Evmh/XOHQYAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "abcSEIR3.get_posterior_sample(N=250, tol=np.inf, G=8, q=0.25, progress=True)\n", + "\n", + "abcSEIR3.plot_posterior_histograms();\n", + "abcSEIR3.plot_pointwise_predictions();" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "b22e6715", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "beta=0.439 (0.318, 0.673)\n", + "alpha=0.281 (0.129, 0.922)\n", + "gamma=0.295 (0.237, 0.375)\n", + "I0=6.472 (3.714, 9.692)\n" + ] + } + ], + "source": [ + "print(f'beta={np.median(abcSEIR3.res[:,0]):.3f} ({np.quantile(abcSEIR3.res[:,0], 0.025):.3f}, {np.quantile(abcSEIR3.res[:,0], 0.975):.3f})')\n", + "print(f'alpha={np.median(abcSEIR3.res[:,1]):.3f} ({np.quantile(abcSEIR3.res[:,1], 0.025):.3f}, {np.quantile(abcSEIR3.res[:,1], 0.975):.3f})')\n", + "print(f'gamma={np.median(abcSEIR3.res[:,2]):.3f} ({np.quantile(abcSEIR3.res[:,2], 0.025):.3f}, {np.quantile(abcSEIR3.res[:,2], 0.975):.3f})')\n", + "print(f'I0={np.median(abcSEIR3.res[:,3]):.3f} ({np.quantile(abcSEIR3.res[:,3], 0.025):.3f}, {np.quantile(abcSEIR3.res[:,3], 0.975):.3f})')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/notebooks/paramfit/params_via_optimization.ipynb b/docs/notebooks/paramfit/params_via_optimization.ipynb new file mode 100644 index 00000000..9aea1023 --- /dev/null +++ b/docs/notebooks/paramfit/params_via_optimization.ipynb @@ -0,0 +1,294 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parameter Estimation: Optimization\n", + "\n", + "In the previous section, we've seen how to use Markov Chain Monte Carlo methods to estimate the posterior probability distribution of parameters.\n", + "These methods have generally replaced older techniques which use algorithms to infer the most likely parameter values, with confidence intervals provided after making assumptions about the local likelihood landscape.\n", + "PyGOM has the capability to estimate parameters in this way in addition to ABC.\n", + "Although perhaps outdated, including these methods could still be practical if trying to reproduce work from older publications, for example.\n", + "\n", + "## Example: SEIR model (with I and R known)\n", + "\n", + "We now solve the same problem as in the previous section,this time via optimization of the cost fucntion.\n", + "As a reminder: We have an SEIR model where time series of $I$ and $R$ are known and we wish to estimate $\\beta$, $\\alpha$ and $\\gamma$ with true values 0.35, 0.5 and 0.25 respectively.\n", + "The total population, $N=10,000$ and the initial number infected, $i_0=5$, are both known.\n", + "\n", + "We start by loading the data again" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "efea520f", + "metadata": {}, + "outputs": [], + "source": [ + "# Import data\n", + "import numpy as np\n", + "\n", + "out = np.loadtxt('seir_epi_data.txt')\n", + "t=out[:,0]\n", + "sol_i_r=out[:,1:3]" + ] + }, + { + "cell_type": "markdown", + "id": "2a5c30e7", + "metadata": {}, + "source": [ + "The syntax for setting up the solver is similar to the approach via ABC.\n", + "We first form our candidate SEIR model.\n", + "Again, we must specify some values for $\\beta$, $\\alpha$ and $\\gamma$, even if we don't know them.\n", + "Here we put zeros, but anything else would be acceptable." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "857371e4", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import common_models\n", + "\n", + "n_pop=1e4\n", + "paramEval=[('beta', 0), ('alpha', 0), ('gamma', 0), ('N', n_pop)]\n", + "ode_SEIR = common_models.SEIR_N_stochastic(param=paramEval)" + ] + }, + { + "cell_type": "markdown", + "id": "80c83797", + "metadata": {}, + "source": [ + "We provide an initial guess in `theta` and pass all relevant info, including initial conditions `x0`, to build an object of class `PoissonLoss`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "88ad9325", + "metadata": {}, + "outputs": [], + "source": [ + "theta = [0.4, 0.3, 0.3] # initial guess\n", + "\n", + "i0=5\n", + "x0=[n_pop-i0, 0, i0, 0] # initial conditions\n", + "\n", + "from pygom import PoissonLoss\n", + "\n", + "objSEIR = PoissonLoss(theta, ode_SEIR,\n", + " t0=t[0], x0=x0,\n", + " t=t[1:], y=sol_i_r[1:,:],\n", + " target_param=['beta', 'alpha', 'gamma'],\n", + " state_name= ['I', 'R'])" + ] + }, + { + "cell_type": "markdown", + "id": "cabcb9ba", + "metadata": {}, + "source": [ + "```{note}\n", + "It is a good idea to check that value of $R_0$ corresponding to the initial guess is greater than 1.\n", + "For instance, here $\\frac{\\beta}{\\gamma}=\\frac{0.4}{0.3}=1.33$.\n", + "This is important because if $R_0<1$ then the resulting model output will be an exponential decay - essentially, a failed epidemic which will differ substantially from the data.\n", + "If the optimization algorithm proceeds by attempting new sets of parameters in the neighbourhood of the initial ones, these are also likely to result in similarly bad model fits and the algorithm may not find a way out.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "140a5020", + "metadata": {}, + "source": [ + "## Gradient calculations\n", + "\n", + "How the parameter optimizer will navigate parameter space will depend on the gradient of the cost function with respect to the parameters.\n", + "PyGOM can calculate the gradient in two different ways, which are explained in more detail in {doc}`.gradient`\n", + "First, let's compare the outputs of the two methods when evaluated at the initial condition, `theta`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "de043dc5", + "metadata": {}, + "outputs": [], + "source": [ + "print(objSEIR.sensitivity())\n", + "print(objSEIR.adjoint())" + ] + }, + { + "cell_type": "markdown", + "id": "c47c6356", + "metadata": {}, + "source": [ + "Also, let's compare the times each method takes:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c74c5449", + "metadata": {}, + "outputs": [], + "source": [ + "%timeit objSEIR.sensitivity()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20856aa8", + "metadata": {}, + "outputs": [], + "source": [ + "%timeit objSEIR.adjoint()" + ] + }, + { + "cell_type": "markdown", + "id": "3a86770d", + "metadata": {}, + "source": [ + "```{note}\n", + "Note how we ran the two gradient functions once before timing it, that is because we only find the properties (Jacobian, gradient) of the ODEs during runtime.\n", + "\n", + "The amount of time taken for both method is dependent on the number of observations as well as the number of states.\n", + "The effect on the adjoint method as the number of observations differs can be quite evident.\n", + "This is because the adjoint method is under a discretization which loops in Python where as the forward sensitivity equations are solved via an integration.\n", + "As the number of observation gets larger, the affect of the Python loop becomes more obvious.\n", + "\n", + "The difference in gradient is larger when there are less observations.\n", + "This is because the adjoint method use interpolations on the output of the ode between each consecutive time points.\n", + "Given solutions over the same length of time, fewer discretizations leads to a less accurate interpolation.\n", + "Note that the interpolation is currently performed using a univariate spline, due to the limitation of Python packages.\n", + "Ideally, one would prefer to use an (adaptive) Hermite or Chebyshev interpolation.\n", + "\n", + "#TODO refs\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "543ec840", + "metadata": {}, + "source": [ + "## Optimized result\n", + "\n", + "We now employ optimization procedures which should progress from the initial guess (if the initial guess is sensible enough) to the parameter set which minimises our cost function.\n", + "It is particularly important to set the boundaries for the parameters here, since we know that they are required to be positive." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ff093f77", + "metadata": {}, + "outputs": [], + "source": [ + "boxBounds = [(0.0,2.0), (0.0,2.0), (0.0,2.0)]" + ] + }, + { + "cell_type": "markdown", + "id": "7590328f", + "metadata": {}, + "source": [ + "Now we use the *SLSQP* optimization routine of `scipy.optimize` with gradient obtained by forward sensitivity.\n", + "\n", + "We could, of course, use other methods available in `scipy.optimize.minimize`, such as *L-BFGS-B* and *TNC*.\n", + "We can also use methods that accepts the exact Hessian such as *trust-ncg* but that should not be necessary most of the time." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "83eca0ba", + "metadata": {}, + "outputs": [], + "source": [ + "from scipy.optimize import minimize\n", + "\n", + "res = minimize(fun=objSEIR.cost,\n", + " jac=objSEIR.sensitivity,\n", + " x0=theta, \n", + " bounds=boxBounds,\n", + " method='SLSQP')\n", + "\n", + "print(res)" + ] + }, + { + "cell_type": "markdown", + "id": "912700fc", + "metadata": {}, + "source": [ + "We see that parameter values in agreement with the underlying model are recovered and there is visual agreement with data when plotted below" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c826a9db", + "metadata": {}, + "outputs": [], + "source": [ + "pars=res.x\n", + "\n", + "ode_est = common_models.SEIR_N_stochastic([('beta', pars[0]), ('alpha', pars[1]), ('gamma', pars[2]), ('N', n_pop)])\n", + "ode_est.initial_values = (x0, t[0])\n", + "solution = ode_est.integrate(t[1::])\n", + "\n", + "import matplotlib.pyplot as plt\n", + "f, axarr = plt.subplots(1,2, layout='constrained', figsize=(10, 2.5))\n", + "\n", + "axarr[0].plot(t, sol_i_r[:,0], color='C0')\n", + "axarr[0].plot(t, solution[:,2], color='C1')\n", + "axarr[1].plot(t, sol_i_r[:,1], color='C0')\n", + "axarr[1].plot(t, solution[:,3], color='C1');" + ] + }, + { + "cell_type": "markdown", + "id": "f79d99fc", + "metadata": {}, + "source": [ + "The problem is only partially solved, however, since we must now do more work to estimate CI's." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 23b4403cfe81f5a605872e16577ea1e48acd53db Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 21:53:40 +0100 Subject: [PATCH 011/123] Generate synthetic epi data for doc examples --- .../paramfit/generate_synth_data.ipynb | 108 ++++++++++ docs/notebooks/paramfit/seir_epi_data.txt | 201 ++++++++++++++++++ 2 files changed, 309 insertions(+) create mode 100644 docs/notebooks/paramfit/generate_synth_data.ipynb create mode 100644 docs/notebooks/paramfit/seir_epi_data.txt diff --git a/docs/notebooks/paramfit/generate_synth_data.ipynb b/docs/notebooks/paramfit/generate_synth_data.ipynb new file mode 100644 index 00000000..7faef9e8 --- /dev/null +++ b/docs/notebooks/paramfit/generate_synth_data.ipynb @@ -0,0 +1,108 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 44, + "id": "14b112be", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "##########################################\n", + "# Code to generate synthetic epidemic data\n", + "# for notebook parameter fitting example\n", + "##########################################\n", + "\n", + "import numpy as np\n", + "from pygom import common_models\n", + "\n", + "# Initial conditions and total population\n", + "i0=5 # initial number of infected individuals\n", + "n_pop=1e4 # total population size\n", + "x0 = [n_pop-i0, 0, i0, 0] # [s0, e0, i0, r0]\n", + "# x0 = [n_pop-i0, i0, 0] # [s0, i0, r0]\n", + "\n", + "# Params\n", + "paramEval=[('beta', 0.35), ('alpha', 0.5), ('gamma', 0.25), ('N', n_pop)]\n", + "# paramEval=[('beta', 0.35), ('gamma', 0.25), ('N', n_pop)]\n", + "\n", + "# Time range and increments\n", + "tmax=200 # maximum time over which to run solver\n", + "dt=1 # timestep\n", + "n_timestep=int(tmax/dt)+1 # number of time points\n", + "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated\n", + "\n", + "initEval=(x0, t[0])\n", + "\n", + "# Set up pygom object\n", + "ode = common_models.SEIR_N_stochastic(param=paramEval, init=initEval)\n", + "# ode = common_models.SIR_N_stochastic(param=paramEval, init=initEval)\n", + "\n", + "# Simulate\n", + "np.random.seed(123)\n", + "sol, simT = ode.solve_stochast(t, iteration=1, full_output=True)\n", + "\n", + "# Process output\n", + "sol_inf=sol[0][:,2] # infecteds\n", + "sol_rec=sol[0][:,3] # infecteds\n", + "\n", + "# Strip down data to just points where infecteds are non zero\n", + "epi=sol_inf>0 # time points where infecteds are non zero\n", + "sol_inf=sol_inf[epi]\n", + "sol_rec=sol_rec[epi]\n", + "t=t[epi]\n", + "\n", + "# save result\n", + "out = np.vstack((t, sol_inf, sol_rec))\n", + "out=np.transpose(out)\n", + "np.savetxt('seir_epi_data.txt', out, fmt='%f')\n", + "\n", + "\n", + "import matplotlib.pyplot as plt\n", + "f, axarr = plt.subplots(layout='constrained')\n", + "axarr.scatter(t, sol_inf)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/notebooks/paramfit/seir_epi_data.txt b/docs/notebooks/paramfit/seir_epi_data.txt new file mode 100644 index 00000000..31ba102b --- /dev/null +++ b/docs/notebooks/paramfit/seir_epi_data.txt @@ -0,0 +1,201 @@ +0.000000 5.000000 0.000000 +1.000000 4.000000 1.000000 +2.000000 3.000000 2.000000 +3.000000 4.000000 2.000000 +4.000000 3.000000 4.000000 +5.000000 5.000000 4.000000 +6.000000 4.000000 6.000000 +7.000000 3.000000 7.000000 +8.000000 3.000000 8.000000 +9.000000 2.000000 9.000000 +10.000000 4.000000 9.000000 +11.000000 5.000000 9.000000 +12.000000 7.000000 9.000000 +13.000000 5.000000 13.000000 +14.000000 9.000000 14.000000 +15.000000 5.000000 19.000000 +16.000000 6.000000 21.000000 +17.000000 8.000000 24.000000 +18.000000 8.000000 27.000000 +19.000000 12.000000 28.000000 +20.000000 12.000000 31.000000 +21.000000 13.000000 32.000000 +22.000000 13.000000 36.000000 +23.000000 12.000000 40.000000 +24.000000 13.000000 44.000000 +25.000000 17.000000 47.000000 +26.000000 15.000000 53.000000 +27.000000 16.000000 55.000000 +28.000000 20.000000 59.000000 +29.000000 21.000000 66.000000 +30.000000 25.000000 71.000000 +31.000000 26.000000 80.000000 +32.000000 29.000000 84.000000 +33.000000 34.000000 91.000000 +34.000000 37.000000 99.000000 +35.000000 39.000000 110.000000 +36.000000 39.000000 117.000000 +37.000000 53.000000 124.000000 +38.000000 57.000000 131.000000 +39.000000 53.000000 146.000000 +40.000000 48.000000 160.000000 +41.000000 40.000000 174.000000 +42.000000 41.000000 182.000000 +43.000000 34.000000 201.000000 +44.000000 39.000000 203.000000 +45.000000 37.000000 213.000000 +46.000000 40.000000 225.000000 +47.000000 53.000000 233.000000 +48.000000 56.000000 245.000000 +49.000000 58.000000 261.000000 +50.000000 58.000000 279.000000 +51.000000 62.000000 289.000000 +52.000000 66.000000 302.000000 +53.000000 76.000000 314.000000 +54.000000 73.000000 336.000000 +55.000000 82.000000 352.000000 +56.000000 91.000000 383.000000 +57.000000 85.000000 405.000000 +58.000000 96.000000 425.000000 +59.000000 85.000000 460.000000 +60.000000 95.000000 473.000000 +61.000000 109.000000 494.000000 +62.000000 110.000000 513.000000 +63.000000 119.000000 534.000000 +64.000000 128.000000 562.000000 +65.000000 139.000000 590.000000 +66.000000 157.000000 629.000000 +67.000000 146.000000 672.000000 +68.000000 163.000000 709.000000 +69.000000 174.000000 756.000000 +70.000000 202.000000 808.000000 +71.000000 198.000000 863.000000 +72.000000 193.000000 915.000000 +73.000000 195.000000 933.000000 +74.000000 215.000000 974.000000 +75.000000 218.000000 1031.000000 +76.000000 231.000000 1089.000000 +77.000000 250.000000 1149.000000 +78.000000 228.000000 1226.000000 +79.000000 231.000000 1302.000000 +80.000000 238.000000 1365.000000 +81.000000 227.000000 1403.000000 +82.000000 225.000000 1476.000000 +83.000000 239.000000 1547.000000 +84.000000 238.000000 1619.000000 +85.000000 252.000000 1686.000000 +86.000000 253.000000 1721.000000 +87.000000 259.000000 1793.000000 +88.000000 269.000000 1872.000000 +89.000000 272.000000 1946.000000 +90.000000 279.000000 1978.000000 +91.000000 274.000000 2060.000000 +92.000000 278.000000 2133.000000 +93.000000 293.000000 2205.000000 +94.000000 296.000000 2242.000000 +95.000000 293.000000 2326.000000 +96.000000 291.000000 2414.000000 +97.000000 280.000000 2470.000000 +98.000000 283.000000 2539.000000 +99.000000 271.000000 2631.000000 +100.000000 265.000000 2713.000000 +101.000000 257.000000 2802.000000 +102.000000 262.000000 2834.000000 +103.000000 268.000000 2918.000000 +104.000000 270.000000 2988.000000 +105.000000 279.000000 3023.000000 +106.000000 290.000000 3100.000000 +107.000000 285.000000 3168.000000 +108.000000 280.000000 3221.000000 +109.000000 274.000000 3289.000000 +110.000000 276.000000 3382.000000 +111.000000 268.000000 3472.000000 +112.000000 256.000000 3522.000000 +113.000000 267.000000 3579.000000 +114.000000 257.000000 3659.000000 +115.000000 255.000000 3699.000000 +116.000000 248.000000 3782.000000 +117.000000 235.000000 3829.000000 +118.000000 225.000000 3904.000000 +119.000000 208.000000 3973.000000 +120.000000 210.000000 4006.000000 +121.000000 196.000000 4072.000000 +122.000000 183.000000 4126.000000 +123.000000 170.000000 4158.000000 +124.000000 147.000000 4222.000000 +125.000000 142.000000 4244.000000 +126.000000 130.000000 4297.000000 +127.000000 113.000000 4344.000000 +128.000000 105.000000 4365.000000 +129.000000 94.000000 4400.000000 +130.000000 101.000000 4427.000000 +131.000000 95.000000 4445.000000 +132.000000 84.000000 4478.000000 +133.000000 79.000000 4500.000000 +134.000000 75.000000 4532.000000 +135.000000 75.000000 4544.000000 +136.000000 77.000000 4568.000000 +137.000000 70.000000 4589.000000 +138.000000 64.000000 4601.000000 +139.000000 64.000000 4620.000000 +140.000000 59.000000 4632.000000 +141.000000 56.000000 4650.000000 +142.000000 51.000000 4666.000000 +143.000000 59.000000 4672.000000 +144.000000 49.000000 4689.000000 +145.000000 42.000000 4705.000000 +146.000000 48.000000 4708.000000 +147.000000 53.000000 4712.000000 +148.000000 52.000000 4729.000000 +149.000000 38.000000 4751.000000 +150.000000 38.000000 4761.000000 +151.000000 35.000000 4777.000000 +152.000000 31.000000 4785.000000 +153.000000 38.000000 4788.000000 +154.000000 37.000000 4804.000000 +155.000000 33.000000 4810.000000 +156.000000 30.000000 4819.000000 +157.000000 24.000000 4829.000000 +158.000000 22.000000 4835.000000 +159.000000 18.000000 4842.000000 +160.000000 17.000000 4851.000000 +161.000000 16.000000 4852.000000 +162.000000 18.000000 4854.000000 +163.000000 17.000000 4856.000000 +164.000000 20.000000 4859.000000 +165.000000 20.000000 4863.000000 +166.000000 21.000000 4866.000000 +167.000000 24.000000 4869.000000 +168.000000 24.000000 4877.000000 +169.000000 18.000000 4886.000000 +170.000000 16.000000 4890.000000 +171.000000 15.000000 4892.000000 +172.000000 12.000000 4896.000000 +173.000000 12.000000 4899.000000 +174.000000 12.000000 4903.000000 +175.000000 11.000000 4905.000000 +176.000000 12.000000 4906.000000 +177.000000 11.000000 4910.000000 +178.000000 11.000000 4912.000000 +179.000000 13.000000 4917.000000 +180.000000 11.000000 4922.000000 +181.000000 9.000000 4926.000000 +182.000000 6.000000 4929.000000 +183.000000 6.000000 4929.000000 +184.000000 9.000000 4930.000000 +185.000000 9.000000 4932.000000 +186.000000 7.000000 4934.000000 +187.000000 7.000000 4936.000000 +188.000000 7.000000 4937.000000 +189.000000 7.000000 4941.000000 +190.000000 5.000000 4944.000000 +191.000000 5.000000 4944.000000 +192.000000 7.000000 4944.000000 +193.000000 6.000000 4945.000000 +194.000000 6.000000 4946.000000 +195.000000 6.000000 4946.000000 +196.000000 4.000000 4948.000000 +197.000000 3.000000 4949.000000 +198.000000 2.000000 4951.000000 +199.000000 2.000000 4951.000000 +200.000000 3.000000 4951.000000 From faa0a404c1b2ca94b50fe2a26820bcd15a243624 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 21:55:14 +0100 Subject: [PATCH 012/123] Pygom analytical features edits --- docs/notebooks/extract_info.ipynb | 273 ++++++++++++ docs/notebooks/insights.ipynb | 43 ++ docs/notebooks/unroll/unrollSimple.ipynb | 509 +++++++++++++++++++++-- 3 files changed, 784 insertions(+), 41 deletions(-) create mode 100644 docs/notebooks/extract_info.ipynb create mode 100644 docs/notebooks/insights.ipynb diff --git a/docs/notebooks/extract_info.ipynb b/docs/notebooks/extract_info.ipynb new file mode 100644 index 00000000..a609c546 --- /dev/null +++ b/docs/notebooks/extract_info.ipynb @@ -0,0 +1,273 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e69f436b", + "metadata": {}, + "source": [ + "# Extracting model information\n", + "\n", + "In the study of ODE systems, there are many calculations which are commonly performed and PyGOM has some functionality to make these easier.\n", + "We will again use the SIR model (REF) as our model system, but this time we will make use of the common_models feature, where many predefined models are stored.\n", + "This means we can avoid having to define the model from scratch again." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d499587e", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import common_models\n", + "ode = common_models.SIR_N_stochastic()" + ] + }, + { + "cell_type": "markdown", + "id": "5defac16", + "metadata": {}, + "source": [ + "## Verification\n", + "\n", + "As seen previously, the `get_ode_eqn` function allows us to check our system of ODEs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a2be3c1", + "metadata": {}, + "outputs": [], + "source": [ + "ode.get_ode_eqn()" + ] + }, + { + "cell_type": "markdown", + "id": "d9f4249d", + "metadata": {}, + "source": [ + "```{tip}\n", + "In addition to showing the equation form of the ODEs, we can also display them as either symbols or latex code, which can save some extra typing when porting the equations to another document.```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2089ef15", + "metadata": {}, + "outputs": [], + "source": [ + "ode.print_ode()\n", + "ode.print_ode(True)" + ] + }, + { + "cell_type": "markdown", + "id": "d9d71015", + "metadata": {}, + "source": [ + "We can also check in terms of transitions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ea90388", + "metadata": {}, + "outputs": [], + "source": [ + "ode.get_transition_matrix()" + ] + }, + { + "cell_type": "markdown", + "id": "9c7b5c60", + "metadata": {}, + "source": [ + "And even inspect the transition diagram" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e04194ea", + "metadata": {}, + "outputs": [], + "source": [ + "ode.get_transition_graph();" + ] + }, + { + "cell_type": "markdown", + "id": "f77cfefa", + "metadata": {}, + "source": [ + "## Algebraic insights\n", + "\n", + "We briefly outline some of the algebraic results which can be quickly accessed by PyGOM.\n", + "\n", + "Firstly, we can check if our system is linear" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1d55ef11", + "metadata": {}, + "outputs": [], + "source": [ + "ode.linear_ode()" + ] + }, + { + "cell_type": "markdown", + "id": "c3fa0e62", + "metadata": {}, + "source": [ + "For stability analysis and speeding up numerical integrators, it may be useful to know the Jacobian, Hessian or gradient" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9c6ec971", + "metadata": {}, + "outputs": [], + "source": [ + "ode.get_jacobian_eqn()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0a8b4ff6", + "metadata": {}, + "outputs": [], + "source": [ + "ode.get_hessian_eqn()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5e1c7dfb", + "metadata": {}, + "outputs": [], + "source": [ + "ode.get_grad_eqn()" + ] + }, + { + "cell_type": "markdown", + "id": "3f572e7c", + "metadata": {}, + "source": [ + "## Epidemiology specific insights\n", + "\n", + "The {func}`.R0` function may be used to obtain the basic reproduction number $R_{0}$.\n", + "We must specify which state represents the *disease state*, which in this case is the state **I**.\n", + "#TODO is this the disease state, or the infectious state?" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "b6eeb070", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix([[S*beta/N]])\n", + "Matrix([[gamma]])\n", + "[S*beta/(N*gamma)]\n", + "{S: 0, R: 0}\n", + "[0]\n", + "[0]\n" + ] + } + ], + "source": [ + "from pygom.model.epi_analysis import *\n", + "\n", + "R_0=R0(ode, 'I')\n", + "print(R_0)" + ] + }, + { + "cell_type": "markdown", + "id": "290ce7ec", + "metadata": {}, + "source": [ + "We may also wish to get the $R_{0}$ in pure algebraic terms.\n", + "This can be achieved by the following few lines of code. Note that the result below is slightly different from the one above.\n", + "The difference is due to the internal working of the functions, where {func}`.getR0` computes the disease-free equilibrium value for the states and substitutes them back into the equation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d099d92b", + "metadata": {}, + "outputs": [], + "source": [ + "F, V = disease_progression_matrices(ode, 'I')\n", + "\n", + "e = R0_from_matrix(F, V)\n", + "print(e)" + ] + }, + { + "cell_type": "markdown", + "id": "94980c72", + "metadata": {}, + "source": [ + "To replicate the output before, we have to find the values where the\n", + "disease-free equilibrium will be achieved. Substitution can then be\n", + "performed to retrieve $R_{0}$ in pure parameters." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "68ea8f68", + "metadata": {}, + "outputs": [], + "source": [ + "dfe = DFE(ode, ['I'])\n", + "\n", + "print(dfe)\n", + "print(e[0].subs(dfe))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/notebooks/insights.ipynb b/docs/notebooks/insights.ipynb new file mode 100644 index 00000000..3fb96cf1 --- /dev/null +++ b/docs/notebooks/insights.ipynb @@ -0,0 +1,43 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e395ad9b", + "metadata": {}, + "source": [ + "# ODE Insights\n", + "\n", + "As mentioned previously, once our ODE system is encapsulated in the `SimulateOde` class, it is ready to be studied using PyGOM's simulation and parameter estimation methods.\n", + "However, we can also take advantage of several useful features of PyGOM which provide us with more analytical insights which we might commonly need pen and paper to find for ourselves.\n", + "\n", + "In this chapter we outline some of these methods which allow us to quickly obtain algebraic results which we frequently find ourselves calculating." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/notebooks/unroll/unrollSimple.ipynb b/docs/notebooks/unroll/unrollSimple.ipynb index 1aa9646b..6f32bdfa 100644 --- a/docs/notebooks/unroll/unrollSimple.ipynb +++ b/docs/notebooks/unroll/unrollSimple.ipynb @@ -4,43 +4,70 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# A simple problem\n", + "# Deducing transitions from equations\n", "\n", - "For a simple problem, where we can clearly distinguish the flows from one compartment to another, we consider the SIR model defined by\n", + "Given a set of equations, PyGOM is able to attempt to distinguish the implied flows between compartments.\n", + "It may be that multiple underlying flow configurations can separately explain a given ODE system, so this functionality should be used with caution.\n", + "Here we demonstrate how this works in practice for two potentially tricky problems.\n", + "The first of which is a system where the total population count is not conserved and the second is a system where a flow out of compartment is split.\n", + "\n", + "## SIR with births and deaths\n", + "\n", + "Let's consider the SIR model with standard incidence mixing and births and deaths proportional to the total population count.\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dS}{dt} &= -\\beta SI \\\\\n", - "\\frac{dI}{dt} &= \\beta SI - \\gamma I \\\\\n", - "\\frac{dR}{dt} &= \\gamma I.\n", + "\\frac{\\mathrm{d} S}{\\mathrm{d} t} &= -\\frac{\\beta SI}{N} + B N - \\mu S \\\\\n", + "\\frac{\\mathrm{d} I}{\\mathrm{d} t} &= \\frac{\\beta SI}{N} - \\gamma I - \\mu I \\\\\n", + "\\frac{\\mathrm{d} R}{\\mathrm{d} t} &= \\gamma I - \\mu R \\\\\n", + "\\frac{\\mathrm{d} N}{\\mathrm{d} t} &= (B-\\mu)N\n", "\\end{aligned}$$\n", "\n", - "which consists of two transitions" + "Given that the force of infection, $\\frac{\\beta SI}{N}$, depends on N(t) it is necessary to keep a track of its time development in the final equation. \n", + "\n", + "Here we encounter an issue when thinking in terms of compartments.\n", + "The total number of living individuals, $N$, is not a distinct category, rather, $S$, $I$ and $R$ are a subset of it.\n", + "Thus, whilst valid to define system of ODEs as we have done above, PyGOM will run into difficulties as it will try to treat $N$ as a compartment.\n", + "One solution could be to define $N$ as a time dependent parameter, however PyGOM does not have this functionality.\n", + "\n", + "Instead, we have to be careful in ensuring that what we pass to PyGOM's transition calculating function, `get_unrolled_obj()`, consists only of state equations.\n", + "The implication for the current example is that we eliminate the final equation and substitute $N=S+I+R$ everywhere else.\n", + "\n", + "Let's set up the PyGOM model as usual." ] }, { - "cell_type": "markdown", - "id": "336381fa", + "cell_type": "code", + "execution_count": 14, + "id": "52daed16", "metadata": {}, + "outputs": [], "source": [ + "from pygom import SimulateOde, Transition, TransitionType\n", + "\n", + "odeList = [\n", + " Transition(transition_type=TransitionType.ODE, origin='S', equation='-beta*S*I/(S+I+R) + B*(S+I+R) - mu*S'),\n", + " Transition(transition_type=TransitionType.ODE, origin='I', equation='beta*S*I/(S+I+R) - gamma*I - mu*I'),\n", + " Transition(transition_type=TransitionType.ODE, origin='R', equation='gamma*I - mu*R') \n", + "]\n", "\n", - "digraph SIR_Model { \n", - "rankdir=LR; size=\"8\" node \\[shape = circle\\]; S -\\> I \\[ label = \"βSI\"\n", - "\\]; I -\\> R \\[ label = \"γI\" \\];\n", - "}" + "stateList = ['S', 'I', 'R']\n", + "paramList = ['beta', 'gamma', 'B', 'mu']\n", + "\n", + "model = SimulateOde(state=stateList, param=paramList, ode=odeList)" ] }, { "cell_type": "markdown", - "id": "160f9040", + "id": "d712e654", "metadata": {}, "source": [ - "We can define this as an ODE, as seen in {doc}`sir`." + "If we now inspect the transition matrix" ] }, { "cell_type": "code", - "execution_count": 1, - "id": "52daed16", + "execution_count": 2, + "id": "16280343", "metadata": {}, "outputs": [ { @@ -55,67 +82,467 @@ "[0, 0, 0]])" ] }, - "execution_count": 1, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "from pygom import SimulateOde, Transition, TransitionType\n", + "model.get_transition_matrix()" + ] + }, + { + "cell_type": "markdown", + "id": "669529c7", + "metadata": {}, + "source": [ + "we see that it is empty. This is because {class}`.SimulateOde` was not initialized using transitions, but by ODEs.\n", + "TODO: perhaps this should be done automatically?\n", "\n", - "ode1 = Transition(origin='S', equation='-beta*S*I', transition_type=TransitionType.ODE)\n", + "We can populate the transition matrix by calling an algorithm to extract the flow information:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "768a4cd0", + "metadata": {}, + "outputs": [], + "source": [ + "model = model.get_unrolled_obj()" + ] + }, + { + "cell_type": "markdown", + "id": "5e3c78c4", + "metadata": {}, + "source": [ + "and can verify that the calculated transition matrix now matches what we would expect." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "5750fc80", + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}0 & \\frac{I S \\beta}{I + R + S} & 0\\\\0 & 0 & I \\gamma\\\\0 & 0 & 0\\end{matrix}\\right]$" + ], + "text/plain": [ + "Matrix([\n", + "[0, I*S*beta/(I + R + S), 0],\n", + "[0, 0, I*gamma],\n", + "[0, 0, 0]])" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.get_transition_matrix()" + ] + }, + { + "cell_type": "markdown", + "id": "a373d4c1", + "metadata": {}, + "source": [ + "Birth and death processes are not between states, rather into and out of the system and so do not appear in the transition matrix.\n", + "We could always get around this by defining another class (perhaps **U**nliving) as a limitless reservoir where births may come from and deaths may flow into.\n", + "Instead, we can view the birth and death processes by inspecting a graph of the transitions." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "8251b87f", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "S\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "I\n", + "\n", + "I\n", + "\n", + "\n", + "\n", + "S->I\n", + "\n", + "\n", + "I*S*β/(I + R + S)\n", + "\n", + "\n", + "\n", + "S*μ\n", + "S*μ\n", + "\n", + "\n", + "\n", + "S->S*μ\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "R\n", + "\n", + "R\n", + "\n", + "\n", + "\n", + "I->R\n", + "\n", + "\n", + "I*γ\n", + "\n", + "\n", + "\n", + "I*μ\n", + "I*μ\n", + "\n", + "\n", + "\n", + "I->I*μ\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "R*μ\n", + "R*μ\n", + "\n", + "\n", + "\n", + "R->R*μ\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "B*S\n", + "B*S\n", + "\n", + "\n", + "\n", + "B*S->S\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "B*I\n", + "B*I\n", + "\n", + "\n", + "\n", + "B*I->S\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "B*R\n", + "B*R\n", + "\n", + "\n", + "\n", + "B*R->S\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.get_transition_graph()" + ] + }, + { + "cell_type": "markdown", + "id": "98da24d0", + "metadata": {}, + "source": [ + "## SLIAR model\n", "\n", - "ode2 = Transition(origin='I', equation='beta*S*I - gamma*I', transition_type=TransitionType.ODE)\n", + "Now we turn to a problem that does not have a one to one mapping between all the transitions and the terms in the ODEs. In this model, **S**usceptible individuals may be infected and enter a **L**atent phase. The rate at which individuals leave this state is $\\kappa$, after which a fraction $p$ become **I**nfective and the remaining $(1-p)$ become **A**symptomatic. Both these classes are capable of onward transmission, however, those in the **A** class have infectivity reduced by a factor $\\delta$ relative to the **I** class. All **A**symptomatics eventually become **R**emoved at a rate $\\eta$, whereas a fraction, $f$, of the infectives recover, the remaining $(1-f)$ going on to die (both at a rate $\\alpha$).\n", "\n", - "ode3 = Transition(origin='R', equation='gamma*I', transition_type=TransitionType.ODE)\n", + "The equations are as follows:\n", "\n", - "stateList = ['S', 'I', 'R']\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= -\\beta S (I + \\delta A) \\\\ \n", + "\\frac{\\mathrm{d}L}{\\mathrm{d}t} &= \\beta S (I + \\delta A) - \\kappa L \\\\ \n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= p \\kappa L - \\alpha I \\\\\n", + "\\frac{\\mathrm{d}A}{\\mathrm{d}t} &= (1 - p) \\kappa L - \\eta A \\\\\n", + "\\frac{\\mathrm{d}R}{\\mathrm{d}t} &= f \\alpha I + \\eta A \\\\\n", + "\\end{aligned}$$\n", "\n", - "paramList = ['beta', 'gamma']\n", + "In this case, the potential difficulty comes from the outflows of state **L** and **I**.\n", + "For **L**, this is composed of two transitions, one to **I** and the other to **A** but the ODE of **L** only reflects the total flow going out of the state.\n", + "Similarly for **I**, the outflow, $\\alpha I$, is partitioned as $f \\alpha I$ into state **R** with the rest assumed dead, though not explicitly stated in the equations.\n", "\n", - "ode = SimulateOde(stateList, paramList, ode=[ode1, ode2, ode3])\n", + "We define out PyGOM model" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "280c4be4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}- S \\beta \\left(A \\delta + I\\right)\\\\- L \\kappa + S \\beta \\left(A \\delta + I\\right)\\\\- I \\alpha + L \\kappa p\\\\- A \\epsilon + L \\kappa \\left(1 - p\\right)\\\\A \\epsilon + I \\alpha f\\end{matrix}\\right]$" + ], + "text/plain": [ + "Matrix([\n", + "[ -S*beta*(A*delta + I)],\n", + "[-L*kappa + S*beta*(A*delta + I)],\n", + "[ -I*alpha + L*kappa*p],\n", + "[ -A*epsilon + L*kappa*(1 - p)],\n", + "[ A*epsilon + I*alpha*f]])" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from pygom import SimulateOde, Transition, TransitionType\n", "\n", - "ode.get_transition_matrix()" + "stateList = ['S', 'L', 'I', 'A', 'R']\n", + "paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'epsilon']\n", + "odeList = [Transition(origin='S', equation='- beta*S*(I + delta*A)', transition_type=TransitionType.ODE), \n", + " Transition(origin='L', equation='beta*S*(I + delta*A) - kappa*L', transition_type=TransitionType.ODE),\n", + " Transition(origin='I', equation='p*kappa*L - alpha*I', transition_type=TransitionType.ODE),\n", + " Transition(origin='A', equation='(1 - p)*kappa*L - epsilon*A', transition_type=TransitionType.ODE),\n", + " Transition(origin='R', equation='f*alpha*I + epsilon*A', transition_type=TransitionType.ODE)]\n", + "model = SimulateOde(stateList, paramList, ode=odeList)" ] }, { "cell_type": "markdown", - "id": "d712e654", + "id": "690b0785", "metadata": {}, "source": [ - "\n", - "and the last line shows that the transition matrix is empty. This is the\n", - "expected result because {class}`.SimulateOdeModel` was not initialized using\n", - "transitions. We can populate the transition matrix by calling an algorithm to extract the flow information, and can see that the output matches that from {ref}`transition:defining-the-equations`." + "Inspecting the transition graph" ] }, { "cell_type": "code", - "execution_count": 2, - "id": "768a4cd0", + "execution_count": 20, + "id": "1b6cb187", "metadata": {}, "outputs": [ { "data": { "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}0 & I S \\beta & 0\\\\0 & 0 & I \\gamma\\\\0 & 0 & 0\\end{matrix}\\right]$" + "$\\displaystyle \\left[\\begin{matrix}0 & A S \\beta \\delta + I S \\beta & 0 & 0 & 0\\\\0 & 0 & L \\kappa p & - L \\kappa p + L \\kappa & 0\\\\0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & A \\epsilon\\\\0 & 0 & 0 & 0 & 0\\end{matrix}\\right]$" ], "text/plain": [ "Matrix([\n", - "[0, I*S*beta, 0],\n", - "[0, 0, I*gamma],\n", - "[0, 0, 0]])" + "[0, A*S*beta*delta + I*S*beta, 0, 0, 0],\n", + "[0, 0, L*kappa*p, -L*kappa*p + L*kappa, 0],\n", + "[0, 0, 0, 0, 0],\n", + "[0, 0, 0, 0, A*epsilon],\n", + "[0, 0, 0, 0, 0]])" ] }, - "execution_count": 2, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "ode = ode.get_unrolled_obj()\n", - "\n", - "ode.get_transition_matrix()" + "model = model.get_unrolled_obj()\n", + "model.get_transition_graph()" + ] + }, + { + "cell_type": "markdown", + "id": "00742616", + "metadata": {}, + "source": [ + "we notice that the $L$ outflow has been captured, but the outflow from $I$ is assumed to be a full death process of which a fraction are born into the recovered state.\n", + "This demonstrates the difficulty in such calculations.\n", + "One work-around is if we explicitly introduce a dead state" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "59ce2a8a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "S\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "L\n", + "\n", + "L\n", + "\n", + "\n", + "\n", + "S->L\n", + "\n", + "\n", + "A*S*β*δ + I*S*β\n", + "\n", + "\n", + "\n", + "I\n", + "\n", + "I\n", + "\n", + "\n", + "\n", + "L->I\n", + "\n", + "\n", + "L*κ*p\n", + "\n", + "\n", + "\n", + "A\n", + "\n", + "A\n", + "\n", + "\n", + "\n", + "L->A\n", + "\n", + "\n", + "-L*κ*p + L*κ\n", + "\n", + "\n", + "\n", + "R\n", + "\n", + "R\n", + "\n", + "\n", + "\n", + "I->R\n", + "\n", + "\n", + "I*α*f\n", + "\n", + "\n", + "\n", + "D\n", + "\n", + "D\n", + "\n", + "\n", + "\n", + "I->D\n", + "\n", + "\n", + "-I*α*f + I*α\n", + "\n", + "\n", + "\n", + "A->R\n", + "\n", + "\n", + "A*ε\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stateList = ['S', 'L', 'I', 'A', 'R', 'D']\n", + "paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'epsilon']\n", + "odeList = [Transition(origin='S', equation='- beta*S*(I + delta*A)', transition_type=TransitionType.ODE), \n", + " Transition(origin='L', equation='beta*S*(I + delta*A) - kappa*L', transition_type=TransitionType.ODE),\n", + " Transition(origin='I', equation='p*kappa*L - alpha*I', transition_type=TransitionType.ODE),\n", + " Transition(origin='A', equation='(1 - p)*kappa*L - epsilon*A', transition_type=TransitionType.ODE),\n", + " Transition(origin='R', equation='f*alpha*I + epsilon*A', transition_type=TransitionType.ODE),\n", + " Transition(origin='D', equation='(1-f)*alpha*I', transition_type=TransitionType.ODE)]\n", + "model = SimulateOde(stateList, paramList, ode=odeList)\n", + "model = model.get_unrolled_obj()\n", + "model.get_transition_graph()" ] } ], @@ -135,7 +562,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.15" + "version": "3.9.19" }, "vscode": { "interpreter": { From 7574242ec74291a30591bf5cbbcbbb8ff2c4deda Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 21:58:47 +0100 Subject: [PATCH 013/123] Model specification edits --- docs/notebooks/model_spec.ipynb | 188 ++++++++++++++++++++++++-------- 1 file changed, 145 insertions(+), 43 deletions(-) diff --git a/docs/notebooks/model_spec.ipynb b/docs/notebooks/model_spec.ipynb index 116e6e15..7aef2beb 100644 --- a/docs/notebooks/model_spec.ipynb +++ b/docs/notebooks/model_spec.ipynb @@ -7,142 +7,244 @@ "source": [ "# Defining an ODE system\n", "\n", - "There are 2 ways to encapsulate an ODE system.\n", + "The starting point in using PyGOM to study an ODE system is to encapsulate the relevant information about the system into a class {class}`SimulateOde`.\n", + "When set up in this object, the system is prepared for application of the various features of PyGOM such as simulation and model fitting.\n", "\n", - "We first demonstrate how to encapsulate the relevant equations in a class which will eventually be used to solve them.\n", + "\n", + "## Equations vs Transitions\n", "\n", - "One useful feature of PyGom is the ability to define the system in a variety of intuitive ways.\n", + "Firstly, we outline the two main ways we might think about defining our ODE system.\n", + "Typically, we may already know the set of equations which describes the rates of change of the dependent variables:\n", "\n", - "In compartmental models, where the states represent counts of certain categories, the changes in these quantities\n", + "$$\\frac{\\mathrm{d} \\mathbf{y}}{\\mathrm{d} t} = f(\\mathbf{y},\\boldsymbol{\\theta}, t)$$\n", + "\n", + "where $\\mathbf{y} = \\left(y_{1},\\ldots,y_{n}\\right)$ is the state vector, $\\boldsymbol{\\theta} = \\left(\\theta_{1},\\ldots, \\theta_{p}\\right)$ is the set of parameters and $f$ is a vector function giving the rates of change of each state.\n", + "\n", + "Compartmental models, whereby the variables represent categories, have another interpretation in which we may instead consider transitions between the different groups\n", + "\n", + "$$\\begin{aligned}\n", + "y_i \\rightarrow y_j = f_{i,j}(\\mathbf{y},\\boldsymbol{\\theta}) \\\\\n", + "\\end{aligned}$$\n", + "\n", + "where $i, j = \\{1,\\ldots, n\\}$ and $f_{i,j}$ are functions governing the rate at which members of group $i$ transition to $j$.\n", + "\n", + "PyGOM allows the user flexibility to choose which of these perspectives to use, or indeed combine, in order to build their models.\n", + "If given transitions, Pygom will automatically convert these into equations and, as we'll see later, it can also attempt to reverse engineer transitions from equations.\n", "\n", "## Example: SIR model\n", "\n", - "Here we use a Susceptible-Infected-Removed epidemic model (an SIR model, for short) to demonstrate the different ways to specify a system.\n", - "The rates of change of each compartment are defined by the following equations\n", + "Here we use a Susceptible-Infected-Recovered epidemic model (an SIR model, for short) to demonstrate the two different ways PyGOM supports model specification.\n", + "Since we will frequently rely on the SIR model in examples throughout the tutorial, we take a moment here to outline its key features.\n", + "\n", + "Firstly, there is some ambiguity in the naming of the Recovered class which is also commonly referred to as Removed.\n", + "In the latter sense, there is no distinction made between those who can no longer be infected due to infection acquired immunity and infection induced death.\n", + "However, for more complex models, the recovered class may become susceptible again due to immune waning and number of deaths is typically important to distinguish.\n", + "Thus, we make the distinction clear from the outset so that when we talk about deaths in this tutorial it will have its own class, Dead, separate from Recovered. \n", + "\n", + "The assumptions of the SIR model:\n", + "1) An average member of the population makes contact sufficient to transmit infection with $\\beta$ others per unit time (*standard* as opposed to *mass-action* incidence, where this would be $\\beta N$).\n", + "2) Contacts are well mixed throughout the population, so that the probability that a given contact is with an infected person is $\\frac{I}{N}$ where $N$ is the total population size.\n", + "3) The infective class is depleted through recovery at a rate $\\gamma I$.\n", + "4) No births, deaths (natural or from disease) or migration mean there is no entry into or departure from the population: $S(t)+I(t)+R(t)=N$.\n", + "\n", + "Under these assumptions, the rates of change of the population in each compartment (**S**usceptible, **I**nfected and **R**ecovered) are given by the following equations:\n", "\n", "$$\\begin{aligned}\n", - "\\frac{\\mathrm{d} S}{\\mathrm{d} t} &= -\\beta SI \\\\\n", - "\\frac{\\mathrm{d} I}{\\mathrm{d} t} &= \\beta SI- \\gamma I \\\\\n", + "\\frac{\\mathrm{d} S}{\\mathrm{d} t} &= -\\frac{\\beta SI}{N} \\\\\n", + "\\frac{\\mathrm{d} I}{\\mathrm{d} t} &= \\frac{\\beta SI}{N} - \\gamma I \\\\\n", "\\frac{\\mathrm{d} R}{\\mathrm{d} t} &= \\gamma I.\n", "\\end{aligned}$$\n", "\n", - "However, it is also true that this is the result of two transitions:\n", + "However, it is equally valid to view this system as the result of two transitions; infection, which takes subjects from susceptible to infected and recovery, which takes them from infected to recovered.\n", "\n", "$$\\begin{aligned}\n", - "S \\rightarrow I &= \\beta SI \\\\\n", + "S \\rightarrow I &= \\frac{\\beta SI}{N} \\\\\n", "I \\rightarrow R &= \\gamma I\n", "\\end{aligned}$$\n", "\n", + "Advantages of specifying our system using the transition approach are firstly that transitions are a more intuitive language when thinking about building compartmental models.\n", + "Perhaps more beneficial, though, is that it enables the computer to do our book-keeping when converting transitions to ODE equations.\n", + "This reduces the error of, for example, including a flow out of one state, but forgetting to include it in the recipient state.\n", + "In this case, we had to remember to include $-\\frac{\\beta SI}{N}$ in the $S$ equation and the opposite sign in the $I$ equation, for example.\n", + "\n", + "## Defining the model with PyGOM\n", + "\n", + "Defining the system is handled by feeding classes of {class}`Transition` into the main class we referred to at the start, {class}`SimulateOde`.\n", + "The {class}`Transition` class has 4 types, which are specified by the `transition_type` argument.\n", + "This lets `SimulateOde` know in which format we are inputting our information.\n", + "This could be as transitions or ODEs as we've just been discussing, or as the other two available options which are birth and death processes.\n", + "The {class}`Transition` class accepts 3 or 4 parameters depending on which type is being defined as summarised in the below table:\n", + "\n", + "| | Transition | Equation | Birth | Death |\n", + "|:---------------:|:-------------------------------:|:---------------------------------:|:--------------------------------------:|:--------------------------------------:|\n", + "| transition_type | T | ODE | B | D |\n", + "| origin | State transition is from, $y_i$ | State equation pertains to, $y_i$ | State birth process populates, $y_i$ | State death process depletes, $y_i$ |\n", + "| destination | State transition is to, $y_j$ | n/a | n/a | n/a |\n", + "| equation | $f_{i,j}$ | $\\frac{dy_i}{dt}$ | $\\frac{dy_i}{dt}$ due to birth process | $\\frac{dy_i}{dt}$ due to death process |\n", + "\n", + "```{note}\n", + "Arguably the state which the birth process populates could be defined as a destination rather than an origin, but this is the convention adopted here.\n", + "\n", + "Also, the {class}`Transition` class may have been better named.\n", + "Firstly, one of the four possible input types is also called \"transition\", which would imply that it has a special place within the class given that it shares its name.\n", + "However, all other forms of input (ODE, birth and death) are equally valid.\n", + "```\n", + "\n", + "Let's see how this is implemented for our example SIR system." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c80a36a", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import Transition, TransitionType\n", + "\n", + "# Define SIR model through a list of ODEs\n", + "odeList = [\n", + " Transition(transition_type=TransitionType.ODE, origin='S', equation='-beta*S*I'),\n", + " Transition(transition_type=TransitionType.ODE, origin='I', equation='beta*S*I - gamma*I'),\n", + " Transition(transition_type=TransitionType.ODE, origin='R', equation='gamma*I') \n", + "]\n", "\n", - "We can set this up as follows:" + "# Define SIR model through a list of transitions\n", + "transList = [\n", + " Transition(transition_type=TransitionType.T, origin='S', destination='I', equation='beta*S*I'),\n", + " Transition(transition_type=TransitionType.T, origin='I', destination='R', equation='gamma*I')\n", + "]" ] }, { "cell_type": "markdown", - "id": "586834ab", + "id": "bc7ee766", "metadata": {}, "source": [ - "1. Import the classes required to define the transitions" + "We now initialise two `SimulateODE` objects using these different approaches.\n", + "In addition to the ODE or transition information, we must specify which variables are parameters and which refer to states." ] }, { "cell_type": "code", "execution_count": null, - "id": "4c80a36a", + "id": "511317c9", "metadata": {}, "outputs": [], "source": [ - "from pygom import Transition, TransitionType" + "stateList = ['S', 'I', 'R']\n", + "paramList = ['beta', 'gamma']" ] }, { "cell_type": "markdown", - "id": "0ec4c9d0", + "id": "b6a2bec7", "metadata": {}, "source": [ - "2. Define our states, in this case the population states of **S**usceptible, **I**nfected and **R**emoved" + "We define the model in two different ways" ] }, { "cell_type": "code", "execution_count": null, - "id": "3ce016f2", + "id": "aceb211a", "metadata": {}, "outputs": [], "source": [ - "stateList = ['S', 'I', 'R']" + "from pygom import SimulateOde\n", + "model_ode = SimulateOde(state=stateList, param=paramList, ode=odeList) # model defined via equations\n", + "model_tra = SimulateOde(state=stateList, param=paramList, transition=transList) # model defined via transitions" ] }, { "cell_type": "markdown", - "id": "021a1927", + "id": "8e38d76b", "metadata": {}, "source": [ - "3. Define the set of parameters for our model" + "We can use the `get_ode_eqn` function to verify that the models are equivalent" ] }, { "cell_type": "code", "execution_count": null, - "id": "441e2287", + "id": "d0fb6c20", "metadata": {}, "outputs": [], "source": [ - "paramList = ['beta', 'gamma']" + "model_ode.get_ode_eqn()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4e8ec9a3", + "metadata": {}, + "outputs": [], + "source": [ + "model_tra.get_ode_eqn()" ] }, { "cell_type": "markdown", - "id": "dfd736b2", + "id": "205dec3d", "metadata": {}, "source": [ - "4. \n", - " i. Specify the transitions of the modelled states; this will form our ODE system" + "## Modifying models\n", + "\n", + "Once a `SimulateODE` object has been defined, it may be modified.\n", + "For example, let's say we wish to add birth and death processes to the the previously defined SIR model of `model_ode`.\n", + "We must update the parameters of the class to reflect any additions." ] }, { "cell_type": "code", "execution_count": null, - "id": "b5f80ab0", + "id": "0923151d", "metadata": {}, "outputs": [], "source": [ - "odeList = [\n", - " Transition(origin='S', equation='-beta*S*I', transition_type=TransitionType.ODE),\n", - " Transition(origin='I',equation='beta*S*I - gamma*I', transition_type=TransitionType.ODE),\n", - " Transition(origin='R', equation='gamma*I', transition_type=TransitionType.ODE) \n", - "]" + "model_ode.param_list = model_ode.param_list + ['mu', 'B']" ] }, { "cell_type": "markdown", - "id": "18c7fbac", + "id": "f9236e77", "metadata": {}, "source": [ - "ii. Specify the transitions of the modelled states; this will form our ODE system" + "We must also add in the new processes" ] }, { "cell_type": "code", "execution_count": null, - "id": "a2761de1", + "id": "9b1546f8", "metadata": {}, "outputs": [], "source": [ - "odeList2 = [\n", - " Transition(origin='S', destination='I', equation='beta*S*I', transition_type=TransitionType.T),\n", - " Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)\n", - "]" + "birthDeathList = [Transition(origin='S', equation='B', transition_type=TransitionType.B), \n", + " Transition(origin='S', equation='mu*S', transition_type=TransitionType.D), \n", + " Transition(origin='I', equation='mu*I', transition_type=TransitionType.D), \n", + " Transition(origin='R', equation='mu*R', transition_type=TransitionType.D)]\n", + "\n", + "model_ode.birth_death_list = birthDeathList" ] }, { "cell_type": "markdown", - "id": "21629e7b", + "id": "3685b2e1", "metadata": {}, "source": [ - "```{note}\n", - "Here, we have invoked a class from {class}`.Transition` to define the ODE object. We proceed here and ignore the details for now. The details of defining a transition object will be covered later in {doc}`transition`. Both the set of states and parameters should be defined when constructing the object, even though not explicitly enforced, to help clarify what we are trying to model. Similarly, this holds for the rest, such as the derived parameters and transitions, where we force the end user to input the different type of transition/process via the correct argument. See {ref}`transition:defining-the-equations` for an example when the input is wrong.\n", - "```" + "We can again use `get_ode_eqn` to verify that the equations are updated" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6cc2ba1a", + "metadata": {}, + "outputs": [], + "source": [ + "model_ode.get_ode_eqn()" ] } ], From 790a7dc112cb5aa5c8b0bef2dcdb1c2dc0c5c5f9 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 30 May 2024 22:00:53 +0100 Subject: [PATCH 014/123] Tidying up files a bit --- docs/_config.yml | 1 + docs/_toc.yml | 49 +- docs/bib/ref.bib | 10 + docs/md/pygom_workflow.md | 8 - docs/md/unrollOde.md | 15 +- docs/notebooks/epi.ipynb | 80 +- docs/notebooks/model_solve.ipynb | 238 +- docs/notebooks/paramfit/estimate1.ipynb | 290 - docs/notebooks/paramfit/estimate2.ipynb | 300 +- docs/notebooks/paramfit/fh.ipynb | 433 +- docs/notebooks/paramfit/gradient.ipynb | 2 +- docs/notebooks/sir.ipynb | 88 +- docs/notebooks/stochastic.ipynb | 617 - docs/notebooks/transition.ipynb | 122 +- docs/notebooks/unroll/unrollBD.ipynb | 214 +- docs/notebooks/unroll/unrollHard.ipynb | 256 +- pygom/model/_tau_leap.c | 38847 +++++++++++++--------- 17 files changed, 23750 insertions(+), 17820 deletions(-) delete mode 100644 docs/md/pygom_workflow.md delete mode 100644 docs/notebooks/paramfit/estimate1.ipynb delete mode 100644 docs/notebooks/stochastic.ipynb diff --git a/docs/_config.yml b/docs/_config.yml index 3b1d7024..84aebe0b 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -14,6 +14,7 @@ only_build_toc_files: true # this could avoid the issue of execution timing out # See https://jupyterbook.org/content/execute.html execute: + allow_errors: true execute_notebooks: cache timeout: -1 diff --git a/docs/_toc.yml b/docs/_toc.yml index 08486baa..fa34133d 100644 --- a/docs/_toc.yml +++ b/docs/_toc.yml @@ -4,28 +4,43 @@ format: jb-book root: md/intro parts: - - caption: User documentation + - caption: Getting started chapters: - file: md/getting_started - - file: notebooks/sir - - file: notebooks/transition - - file: notebooks/stochastic - - file: md/unrollOde - sections: - - file: notebooks/unroll/unrollSimple - - file: notebooks/unroll/unrollBD - - file: notebooks/unroll/unrollHard - - file: notebooks/epi - - file: notebooks/epijson + - caption: Pygom workflow + chapters: + - file: notebooks/model_spec + - file: notebooks/insights + sections: + - file: notebooks/extract_info + #- file: notebooks/epi + - file: notebooks/unroll/unrollSimple + - file: md/solving + sections: + - file: notebooks/model_params + - file: notebooks/model_solver + #- file: notebooks/transition + # - file: md/unrollOde + # sections: + # - file: notebooks/unroll/unrollSimple + # - file: notebooks/unroll/unrollBD + # - file: notebooks/unroll/unrollHard - file: md/parameter_fitting sections: + - file: notebooks/paramfit/params_via_abc + - file: notebooks/paramfit/params_via_optimization - file: notebooks/paramfit/bvpSimple - - file: notebooks/paramfit/gradient - - file: notebooks/paramfit/fh - - file: notebooks/paramfit/estimate1 - - file: notebooks/paramfit/estimate2 - - file: notebooks/paramfit/initialGuess - - file: notebooks/paramfit/profile + - file: notebooks/epijson + # - file: notebooks/paramfit/gradient + # - file: notebooks/paramfit/fh + # - file: notebooks/paramfit/estimate1 + # - file: notebooks/paramfit/estimate2 + # - file: notebooks/paramfit/initialGuess + # - file: notebooks/paramfit/profile + - caption: Appendix + chapters: + - file: notebooks/paramfit/gradient + - file: notebooks/paramfit/profile - caption: Common biological compartmental models chapters: - file: md/common_models diff --git a/docs/bib/ref.bib b/docs/bib/ref.bib index b7509dd4..cf02a3ca 100644 --- a/docs/bib/ref.bib +++ b/docs/bib/ref.bib @@ -262,4 +262,14 @@ @book{ruby author = {Flanagan, David and Matsumoto, Yukihiro}, year = {2008}, publisher = {O'Reilly Media} +} +@article{fitzhugh1961impulses, + title={Impulses and physiological states in theoretical models of nerve membrane}, + author={FitzHugh, Richard}, + journal={Biophysical journal}, + volume={1}, + number={6}, + pages={445--466}, + year={1961}, + publisher={Elsevier} } \ No newline at end of file diff --git a/docs/md/pygom_workflow.md b/docs/md/pygom_workflow.md deleted file mode 100644 index 38f79a85..00000000 --- a/docs/md/pygom_workflow.md +++ /dev/null @@ -1,8 +0,0 @@ -# Pygom workflow - -The PyGom workflow is as follows - -1. Encapsulate the ODE system using a series of {class}`Transition` objects. -2. Feed this into a class {class}`DeterministicOde` or {class}`SimulateOde` depending on how solutions are required. -3. Use functionality to verify or update model specification. Find solutions etc. - diff --git a/docs/md/unrollOde.md b/docs/md/unrollOde.md index 5b53d60c..19b2a56a 100644 --- a/docs/md/unrollOde.md +++ b/docs/md/unrollOde.md @@ -1,16 +1,11 @@ # Converting equations into transitions -As seen previously in {doc}`transition`, we can -define the model via the transitions or explicitly as ODEs. There are -times when we all just want to test out some model in a paper and the -only available information are the ODEs themselves. Even though we know -that the ODEs come from some underlying transitions, breaking them down -can be a time consuming process. We provide the functionalities to do -this automatically. - +As seen previously in {doc}`transition`, we can define a model via transitions or explicitly as ODEs. +There may be times when importing a model from elsewhere and the only available information are the ODEs themselves. +If it is known that the ODEs come from some underlying transitions, we provide the functionality to do this automatically. +Of course there is some interpretation... +Here we demostrate usage of this feature via examples of increasing complexity: {doc}`../notebooks/unroll/unrollSimple` - {doc}`../notebooks/unroll/unrollBD` - {doc}`../notebooks/unroll/unrollHard` diff --git a/docs/notebooks/epi.ipynb b/docs/notebooks/epi.ipynb index 8b47d848..9e57058c 100644 --- a/docs/notebooks/epi.ipynb +++ b/docs/notebooks/epi.ipynb @@ -6,15 +6,9 @@ "source": [ "# Epidemic Analysis\n", "\n", - "A common application of ODEs is in the field\n", - "of epidemiology modeling, where compartmental models are\n", - "used to describe disease progression through a population. \n", "We demonstrate some of the simpler algebraic analysis that you may wish to undertake on a compartmental model.\n", "\n", - "We revisit the SIR model with birth and death\n", - "processes, which is an extension of the one in {doc}`sir`. \n", - "\n", - "First, we initialize the model, this time by importing it from {mod}`.common_models`, rather than constructing it ourselves." + "First, we initialize an SIR model, this time by importing it from {mod}`.common_models`, rather than constructing it ourselves:" ] }, { @@ -22,20 +16,45 @@ "execution_count": 1, "id": "8c84ea26", "metadata": {}, + "outputs": [], + "source": [ + "from pygom import common_models\n", + "\n", + "ode = common_models.SIR_Birth_Death()" + ] + }, + { + "cell_type": "markdown", + "id": "8432a422", + "metadata": {}, + "source": [ + "We can verify" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "f7610d25", + "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Matrix([[B - I*S*beta - S*mu], [I*S*beta - I*gamma - I*mu], [I*gamma]])\n" - ] + "data": { + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}B - I S \\beta - S \\mu\\\\I S \\beta - I \\gamma - I \\mu\\\\I \\gamma\\end{matrix}\\right]$" + ], + "text/plain": [ + "Matrix([\n", + "[ B - I*S*beta - S*mu],\n", + "[I*S*beta - I*gamma - I*mu],\n", + "[ I*gamma]])" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "from pygom import common_models\n", - "\n", - "ode = common_models.SIR_Birth_Death()\n", - "\n", "ode.get_ode_eqn()" ] }, @@ -44,18 +63,9 @@ "id": "ea8c4b15", "metadata": {}, "source": [ - "\n", "## Obtaining the reproduction number (R0)\n", "\n", - "The reproduction number, also known as the $R_{0}$, is the single most\n", - "powerful piece and reduced piece of information available from an epidemiological\n", - "compartmental model. This value represents the number of the disease-naive population who can be infected by a single member of the infectious population. When the parameter values are known, $R_{0}$ provides a single number which can then lead to an interpretation of the system, where $R_{0} = 1$ defines the tipping point of an outbreak. An $R_{0}$ value of\n", - "more than one signifies growth of cases (a potential outbreak), and an $R_{0}$ of less than one\n", - "indicates that the disease will stop spreading naturally.\n", - "\n", - "#TODO reference\n", - "\n", - "To obtain the $R_{0}$, we need have to tell the {func}`.R0` function which states\n", + "To obtain $R_{0}$, we need have to tell the {func}`.R0` function which states\n", "represent the *disease state*, which in this case is the state **I**.\n", "\n", "#TODO is this the disease state, or the infectious state?" @@ -105,19 +115,15 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 4, "id": "717c6868", "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'disease_progression_matrices' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[1], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m F, V \u001b[39m=\u001b[39m disease_progression_matrices(ode, \u001b[39m'\u001b[39m\u001b[39mI\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[0;32m 3\u001b[0m e \u001b[39m=\u001b[39m R0_from_matrix(F, V)\n\u001b[0;32m 5\u001b[0m \u001b[39mprint\u001b[39m(e)\n", - "\u001b[1;31mNameError\u001b[0m: name 'disease_progression_matrices' is not defined" + "name": "stdout", + "output_type": "stream", + "text": [ + "[S*beta/(gamma + mu)]\n" ] } ], @@ -126,7 +132,7 @@ "\n", "e = R0_from_matrix(F, V)\n", "\n", - "print(e)\n" + "print(e)" ] }, { @@ -174,7 +180,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.15" + "version": "3.9.19" }, "vscode": { "interpreter": { diff --git a/docs/notebooks/model_solve.ipynb b/docs/notebooks/model_solve.ipynb index 2ec03c84..7ad3babf 100644 --- a/docs/notebooks/model_solve.ipynb +++ b/docs/notebooks/model_solve.ipynb @@ -3,96 +3,96 @@ { "cell_type": "code", "execution_count": null, - "id": "06b092c7", - "metadata": {}, + "id": "efbf9af8", + "metadata": { + "tags": [ + "remove-input" + ] + }, "outputs": [], "source": [ - "from pygom import DeterministicOde" + "# Reload all previous stuff, not sure how to do this without redoing everything...\n", + "stateList = ['S', 'I', 'R']\n", + "paramList = ['beta', 'gamma']\n", + "from pygom import Transition, TransitionType\n", + "odeList = [\n", + " Transition(origin='S', equation='-beta*S*I', transition_type=TransitionType.ODE),\n", + " Transition(origin='I',equation='beta*S*I - gamma*I', transition_type=TransitionType.ODE),\n", + " Transition(origin='R', equation='gamma*I', transition_type=TransitionType.ODE) \n", + "]\n", + "transList = [\n", + " Transition(origin='S', destination='I', equation='beta*S*I', transition_type=TransitionType.T),\n", + " Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)\n", + "]" ] }, { "cell_type": "markdown", - "id": "46f1fc79", + "id": "133de424", "metadata": {}, "source": [ - "6. And then initialize the model, which constructs our ODE system from all the information we have provided" + "# Solving the model\n", + "\n", + "We will now find deterministic solutions to the SIR model.\n", + "First we must import the relevant class" ] }, { "cell_type": "code", "execution_count": null, - "id": "d2d00708", + "id": "06b092c7", "metadata": {}, "outputs": [], "source": [ - "model = DeterministicOde(stateList, paramList, ode=odeList)" + "from pygom import DeterministicOde" ] }, { "cell_type": "markdown", - "id": "db3a166f", + "id": "46f1fc79", "metadata": {}, "source": [ - "That is all the information required to define a simple SIR model. We can verify the model using" + "Now we initialize the class, which constructs our ODE system from all the information we have provided.\n", + "For now, let's use both approaches:" ] }, { "cell_type": "code", "execution_count": null, - "id": "39171530", + "id": "d2d00708", "metadata": {}, "outputs": [], "source": [ - "model.get_ode_eqn()" - ] - }, - { - "cell_type": "markdown", - "id": "bc3f2c5c", - "metadata": {}, - "source": [ - "where we can see the equations corresponding to their respective $S,I$ and $R$ state. " - ] - }, - { - "cell_type": "markdown", - "id": "ff37e8ad", - "metadata": {}, - "source": [ - "```{note}\n", - "The ordering of the equations is in the standard $S,I,R$ sequence because of how we defined the states initially. \n", - "```" + "model = DeterministicOde(stateList, paramList, ode=odeList)\n", + "model2 = DeterministicOde(stateList, paramList, transition=transList)" ] }, { "cell_type": "markdown", - "id": "574a50f3", + "id": "db3a166f", "metadata": {}, "source": [ - "We can rearrange the state list," + "We can verify the model equations are what we'd expect by using the `get_ode_eqn()` function." ] }, { "cell_type": "code", "execution_count": null, - "id": "11304d48", + "id": "39171530", "metadata": {}, "outputs": [], "source": [ - "# now we are going to define in a different order. note that the output ode changed with the input state\n", - "stateList = ['R', 'S', 'I']\n", - "\n", - "model = DeterministicOde(stateList, paramList, ode=odeList)\n", - "\n", - "model.get_ode_eqn()\n" + "print(model.get_ode_eqn())\n", + "print(model2.get_ode_eqn())" ] }, { "cell_type": "markdown", - "id": "ed5aa20f", + "id": "bc3f2c5c", "metadata": {}, "source": [ - "and find that the set of ODEs comes out in the order that we specified. " + "where we can see that building the model via equations or transitions results in the same equations corresponding to their respective $S$, $I$ and $R$ state.\n", + "From now on, we proceed with just `model`, safe in the knowledge that they are the same." ] }, { @@ -130,8 +130,8 @@ "id": "3e7b28f3", "metadata": {}, "source": [ - "Here the SIR model was provided to PyGOM as a set ODEs by using the {class}`.Transition` to define them. \n", - "We have also provided the capability to obtain a *best guess* transition matrix when only the ODEs are available. See the section {doc}`unrollOde` for more information, and in particular {doc}`unrollSimple` for the continuing demonstration of the SIR model." + "" ] }, { @@ -139,157 +139,121 @@ "id": "bdcecb64", "metadata": {}, "source": [ - "## Extracting model information\n", + "" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "472627da", + "cell_type": "markdown", + "id": "7b7f8220", "metadata": {}, - "outputs": [], "source": [ - "model.linear_ode()" + "## Initial value problem\n", + "\n", + "We can calculate the time evolution of the system given the values of the initial conditions and parameters." ] }, { "cell_type": "markdown", - "id": "0c24bd4d", + "id": "f6f00b34", "metadata": {}, "source": [ - "Since we know that the SIR model is not linear, we may want to have a look at the Jacobian.\n" + "1. Define the model parameters. We can call `parameters` to check what is required" ] }, { "cell_type": "code", "execution_count": null, - "id": "281970f1", + "id": "c163aa2f", "metadata": {}, "outputs": [], "source": [ - "model.get_jacobian_eqn()" + "model.parameters" ] }, { "cell_type": "markdown", - "id": "189c4547", + "id": "9f56e201", "metadata": {}, "source": [ - "Or maybe we want to know the gradient." + "we then pass them to the class via a list of tuples" ] }, { "cell_type": "code", "execution_count": null, - "id": "e5440ae5", + "id": "696476fb", "metadata": {}, "outputs": [], "source": [ - "model.get_grad_eqn()" - ] - }, - { - "cell_type": "markdown", - "id": "5971ef84", - "metadata": {}, - "source": [ - "```{Warning}\n", - "Invoking the functions that compute the derivatives, $f(x)$, `model.ode()` or `model.jacobian()`, will return an error\n", - "\n", - "These functions are used to solve the ODEs numerically, and require values of initial state values, time, and parameter values.\n", - "```" + "paramEval = [('beta',0.5), ('gamma',1.0/3.0)]\n", + "model.parameters = paramEval" ] }, { "cell_type": "markdown", - "id": "2d52e99d", + "id": "f1a505b5", "metadata": {}, "source": [ - "For setting initial conditions, the numeric values of the states **must** be set in the same order that list of states appear. We can use the following to check the state ordering, as well as displaying all of the states that we have included." + "and can verify that this was successful" ] }, { "cell_type": "code", "execution_count": null, - "id": "fbf0da5a", + "id": "a94733b2", "metadata": {}, "outputs": [], "source": [ - "model.state_list" - ] - }, - { - "cell_type": "markdown", - "id": "32ce2410", - "metadata": {}, - "source": [ - "#TODO unsure if this is needed\n", - "\n", - "There is currently no mechanism to set the numeric initial conditions the states when the states are defined. This is because of an implementation issue with external package, such as solving an initial value problem." - ] - }, - { - "cell_type": "markdown", - "id": "7b7f8220", - "metadata": {}, - "source": [ - "## Initial value problem\n", - "\n", - "By setting the state initial conditions, time, and parameters, we can evaluate our model." + "model.parameters" ] }, { "cell_type": "markdown", - "id": "f6f00b34", - "metadata": {}, - "source": [ - "1. Define the model parameters. (We can call the parameters to check what we must provide.)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c163aa2f", + "id": "e80ac7f8", "metadata": {}, - "outputs": [], "source": [ - "model.parameters" + "2. Provide initial conditions for the states." ] }, { "cell_type": "code", "execution_count": null, - "id": "696476fb", + "id": "2b45e43c", "metadata": {}, "outputs": [], "source": [ - "paramEval = [('beta',0.5), ('gamma',1.0/3.0)]\n", + "i0=1e-6\n", + "initialState = [1-i0, i0, 0]\n", "\n", - "model.parameters = paramEval\n", - "\n", - "model.parameters" + "model.ode(state=initialState, t=1)" ] }, { "cell_type": "markdown", - "id": "e80ac7f8", + "id": "22c4063f", "metadata": {}, "source": [ - "2. Provide initial conditions for the states." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b45e43c", - "metadata": {}, - "outputs": [], - "source": [ - "initialState = [0, 1, 1.27e-6]\n", - " \n", - "model.ode(state=initialState, t=1)" + "```{note}\n", + "Fractional SIR models are subject to the constraint $S(t)+I(t)+R(t)=1$. It is up to the user to ensure that the initial conditions adhere to any constraints.\n", + "```" ] }, { @@ -330,32 +294,24 @@ "cell_type": "code", "execution_count": null, "id": "5badfc50", - "metadata": {}, + "metadata": { + "tags": [ + "hide-input" + ] + }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "\n", "plt.figure()\n", - "\n", - "plt.plot(t, solution[:,0], label='R')\n", - "\n", - "plt.plot(t, solution[:,1], label='S')\n", - "\n", - "plt.plot(t, solution[:,2], label='I')\n", - "\n", + "plt.plot(t, solution[:,0], label='S')\n", + "plt.plot(t, solution[:,1], label='I')\n", + "plt.plot(t, solution[:,2], label='R')\n", "plt.xlabel('Time')\n", - "\n", "plt.ylabel('Population proportion')\n", - "\n", "plt.title('Standard SIR model')\n", - "\n", "plt.legend(loc=0)\n", - "\n", - "#@savefig sir_plot.png In \n", - "\n", - "plt.show()\n", - "\n", - "#plt.close()\n" + "plt.show()" ] }, { diff --git a/docs/notebooks/paramfit/estimate1.ipynb b/docs/notebooks/paramfit/estimate1.ipynb deleted file mode 100644 index 68946810..00000000 --- a/docs/notebooks/paramfit/estimate1.ipynb +++ /dev/null @@ -1,290 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Parameter Estimation: Example 1\n", - "\n", - "## Estimation under square loss\n", - "\n", - "To ease the estimation process when given data, a separate module\n", - "{mod}`ode_loss` has been constructed for observations coming from a single\n", - "state. We demonstrate how to do parametre fitting using two models; first, a the\n", - "SIR model, followed by the Legrand SEIHFR model from {citets}`Legrand2007` [\\[Legrand2007\\]]() used \n", - "for Ebola in the next page {doc}`.estimate2`.\n", - "\n", - "### SIR Model\n", - "\n", - "We set up an SIR model as seen previously in {doc}`.sir`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "efea520f", - "metadata": {}, - "outputs": [], - "source": [ - "from pygom import SquareLoss, common_models\n", - "\n", - "import numpy\n", - "\n", - "import scipy.integrate\n", - "\n", - "import matplotlib.pyplot\n", - "\n", - "# define the parameters\n", - "paramEval = [('beta',0.5), ('gamma',1.0/3.0)]" - ] - }, - { - "cell_type": "markdown", - "id": "fbfac95a", - "metadata": {}, - "source": [ - "Initialize the model using the preloaded common model {obj}`.SIR`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f09342a5", - "metadata": {}, - "outputs": [], - "source": [ - "ode = common_models.SIR(paramEval)" - ] - }, - { - "cell_type": "markdown", - "id": "3fb03842", - "metadata": {}, - "source": [ - "We assume that we have perfect information about the $R$\n", - "compartment." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2cb19871", - "metadata": {}, - "outputs": [], - "source": [ - "x0 = [1, 1.27e-6, 0]\n", - "\n", - "# time, including the initial time t0 at t=0\n", - "\n", - "t = numpy.linspace(0, 150, 1000)\n", - "\n", - "# determine the solution.\n", - "\n", - "solution = scipy.integrate.odeint(ode.ode, x0, t)\n", - "\n", - "#TODO why use scipy?\n", - "\n", - "y = solution[:,1:3].copy()" - ] - }, - { - "cell_type": "markdown", - "id": "2a5c30e7", - "metadata": {}, - "source": [ - "\n", - "Initialize the class with some initial guess\n" - ] - }, - { - "cell_type": "markdown", - "id": "857371e4", - "metadata": {}, - "source": [ - "# our initial guess\n", - "\n", - "theta = [0.2, 0.2]\n", - "\n", - "objSIR = SquareLoss(theta, ode, x0, t[0], t[1::], y[1::,:], ['I','R'])\n" - ] - }, - { - "cell_type": "markdown", - "id": "cabcb9ba", - "metadata": {}, - "source": [ - "\n", - "Note that we need to provide the initial values, $x_{0}$ and $t_{0}$\n", - "differently to the observations $y$ and the corresponding time $t$.\n", - "Additionally, the state which the observation lines needs to be\n", - "specified. Either a single state, or multiple states are allowed, as\n", - "seen above.\n" - ] - }, - { - "cell_type": "markdown", - "id": "140a5020", - "metadata": {}, - "source": [ - "\n", - "### Difference in gradient\n", - "\n", - "We have provided two different ways of obtaining the gradient, these are\n", - "explained in {doc}`.gradient` in a bit more detail. First, lets see how\n", - "similar the outputs of the two methods are." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "de043dc5", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "objSIR.sensitivity()\n", - "\n", - "objSIR.adjoint()\n" - ] - }, - { - "cell_type": "markdown", - "id": "c47c6356", - "metadata": {}, - "source": [ - "\n", - "and the time required to obtain the gradient for the SIR model under\n", - "$\\theta = (0.2,0.2)$, previously entered.\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "c74c5449", - "metadata": {}, - "source": [ - "%timeit objSIR.sensitivity()\n" - ] - }, - { - "cell_type": "markdown", - "id": "20856aa8", - "metadata": {}, - "source": [ - "%timeit objSIR.adjoint()" - ] - }, - { - "cell_type": "markdown", - "id": "3a86770d", - "metadata": {}, - "source": [ - "The amount of time taken for both method is dependent on the\n", - "number of observations as well as the number of states. The effect on\n", - "the adjoint method as the number of observations differs can be quite\n", - "evident. This is because the adjoint method is under a discretization\n", - "which loops in Python where as the forward sensitivity equations are\n", - "solved via an integration. As the number of observation gets\n", - "larger, the affect of the Python loop becomes more obvious.\n", - "\n", - "The difference in gradient is larger when there are less observations. This\n", - "is because the adjoint method use interpolations on the output of the\n", - "ode between each consecutive time points. Given solutions over the same\n", - "length of time, fewer discretizations leads to a less accurate\n", - "interpolation. Note that the interpolation is currently performed using a\n", - "univariate spline, due to the limitation of Python packages. Ideally,\n", - "one would prefer to use an (adaptive) Hermite or Chebyshev\n", - "interpolation. \n", - "\n", - "#TODO add refs\n", - "\n", - "Note how we ran the two gradient functions once before\n", - "timing it, that is because we only find the properties (Jacobian,\n", - "gradient) of the ODEs during runtime.\n" - ] - }, - { - "cell_type": "markdown", - "id": "543ec840", - "metadata": {}, - "source": [ - "\n", - "### Optimized result\n", - "\n", - "Then standard optimization procedures with some suitable initial guess\n", - "should yield the correct result. It is important to set the boundaries\n", - "for compartmental models as we know that all the parameters are strictly\n", - "positive. We put a less restrictive inequality here for demonstration\n", - "purpose.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ff093f77", - "metadata": {}, - "outputs": [], - "source": [ - "# what we think the bounds are\n", - "\n", - "boxBounds = [(0.0,2.0),(0.0,2.0)]" - ] - }, - { - "cell_type": "markdown", - "id": "7590328f", - "metadata": {}, - "source": [ - "Then using the optimization routines in `scipy.optimize`, for example,\n", - "the *SLSQP* method with the gradient obtained by forward sensitivity.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "83eca0ba", - "metadata": {}, - "outputs": [], - "source": [ - "from scipy.optimize import minimize\n", - "\n", - "res = minimize(fun=objSIR.cost, jac=objSIR.sensitivity, x0=theta, \n", - " bounds=boxBounds, method='SLSQP')\n", - "\n", - "print(res)\n" - ] - }, - { - "cell_type": "markdown", - "id": "404ddd1c", - "metadata": {}, - "source": [ - "Other methods available in `scipy.optimize.minimize` can also be used,\n", - "such as the *L-BFGS-B* and *TNC*. We can also use methods that accepts\n", - "the exact Hessian such as *trust-ncg* but that should not be necessary\n", - "most of the time.\n", - "\n", - "#TODO add doc refs for scipy" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.9.15 ('sphinx-doc')", - "language": "python", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "3.9.15" - }, - "vscode": { - "interpreter": { - "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/notebooks/paramfit/estimate2.ipynb b/docs/notebooks/paramfit/estimate2.ipynb index ce6d24f5..6027866c 100644 --- a/docs/notebooks/paramfit/estimate2.ipynb +++ b/docs/notebooks/paramfit/estimate2.ipynb @@ -33,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "6826d12d", "metadata": {}, "outputs": [], @@ -59,7 +59,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "1d9b4bfb", "metadata": {}, "outputs": [], @@ -70,7 +70,7 @@ "71.0, 73.0, 80.0, 86.0, 88.0, 90.0, 100.0, 102.0, 106.0, 108.0,\n", "112.0, 114.0, 117.0, 120.0, 123.0, 126.0, 129.0, 132.0, 135.0, 137.0, 140.0, 142.0, 144.0, 147.0, 149.0, 151.0, 157.0, 162.0, 167.0,\n", "169.0, 172.0, 175.0, 176.0, 181.0, 183.0, 185.0, 190.0, 193.0,\n", - "197.0, 199.0, 204.0, 206.0, 211.0, 213.0, 218.0]\n" + "197.0, 199.0, 204.0, 206.0, 211.0, 213.0, 218.0]" ] }, { @@ -84,36 +84,90 @@ "Details of the models can be found in {doc}`common_models` Defining the model\n", "as usual with an approximation of what the parameters might be, here,\n", "we choose the values to be the mid point of our feasible region (defined\n", - "by our box constraints later).\n" + "by our box constraints later).\n", + "\n", + "Let's see what the data looks like:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, + "id": "937db857", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import numpy\n", + "population = 1175e4\n", + "y = numpy.reshape(numpy.append(numpy.array(yCase), numpy.array(yDeath)),\n", + " (len(yCase),2), 'F')#/population\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "f, axarr = plt.subplots(1,2, layout='constrained', figsize=(10, 4))\n", + "\n", + "axarr[0].scatter(t, y[:,0])\n", + "axarr[1].scatter(t, y[:,1])\n", + "axarr[0].set_yscale('log')\n", + "axarr[1].set_yscale('log')" + ] + }, + { + "cell_type": "markdown", + "id": "07b101f6", + "metadata": {}, + "source": [ + "Let's set up model" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "id": "5dfa5094", "metadata": {}, "outputs": [], "source": [ - "from pygom import SquareLoss, common_models\n", + "# Define SIR model\n", + "from pygom import SimulateOde, Transition, TransitionType\n", + "stateList = ['S', 'E', 'I', 'R']\n", + "paramList = ['beta', 'alpha', 'gamma']\n", "\n", - "import numpy, scipy.optimize\n", + "transitionList = [Transition(origin='S', destination='E', equation='beta*S*I', transition_type=TransitionType.T),\n", + " Transition(origin='E', destination='I', equation='alpha*E', transition_type=TransitionType.T),\n", + " Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)]\n", "\n", - "import matplotlib.pyplot as plt\n", + "ode_obj = SimulateOde(stateList, paramList, transition=transitionList)\n", "\n", "theta = numpy.array([5.0, 5.0, 5.0])\n", + "ode_obj.parameters=theta\n", "\n", - "ode = common_models.SEIR(theta)\n", - "\n", - "population = 1175e4\n", - "\n", - "y = numpy.reshape(numpy.append(numpy.array(yCase), numpy.array(yDeath)), \n", - " (len(yCase),2), 'F')/population\n", + "from pygom import SquareLoss\n", "\n", "x0 = [1., 0., 49.0/population, 29.0/population]\n", "\n", - "t0 = t[0]\n", - "\n", - "objLegrand = SquareLoss(theta, ode, x0, t0, t[1::], y[1::,:], ['I','R'], numpy.sqrt([population\\]*2))\n" + "objLegrand = SquareLoss(theta, ode_obj,\n", + " t0=t[0], x0=x0,\n", + " t=t[1::], y=y[1::,:],\n", + " state_name=['I','R'],\n", + " state_weight=numpy.sqrt(population*2)) " + ] + }, + { + "cell_type": "markdown", + "id": "fdc428cc", + "metadata": {}, + "source": [ + "Now let's param" ] }, { @@ -129,11 +183,29 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "fc31ee5f", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL\n", + " success: True\n", + " status: 0\n", + " fun: 9.045332633285773e-07\n", + " x: [ 4.919e+00 5.000e+00 5.079e+00]\n", + " nit: 10\n", + " jac: [ 9.551e-06 1.237e-08 -9.238e-06]\n", + " nfev: 11\n", + " njev: 11\n", + " hess_inv: <3x3 LbfgsInvHessProduct with dtype=float64>\n" + ] + } + ], "source": [ + "import scipy.optimize\n", "\n", "boxBounds = [ (0.0,10.0), (0.0,10.0), (0.0,10.0)]\n", "\n", @@ -144,10 +216,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "d3e42fe2", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "f = plt.figure()\n", "\n", @@ -184,10 +276,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "38badab5", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 3.11038452e-09 7.85178078e-06 -3.60499243e-08]\n" + ] + } + ], "source": [ "resDE = scipy.optimize.differential_evolution(objLegrand.cost,\n", "bounds=boxBounds, polish=False, seed=20921391)\n", @@ -197,16 +297,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "9f68ff44", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "f = plt.figure()\n", "\n", "objLegrand.plot()\n", "\n", - "plt.close()\n" + "plt.close()" ] }, { @@ -225,10 +345,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "3f01c604", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "array([7.13160861e-01, 1.88609866e+03, 8.00526800e+01])" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "1/resDE['x']" ] @@ -257,10 +388,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "id": "f4797fe3", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "1.90984074647533e-08" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "objLegrand.cost([3.26106524e+00, 2.24798702e-04, 1.23660721e-02])\n", "\n", @@ -270,12 +412,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "0573ccf8", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "\n", "objLegrand.plot()" ] }, @@ -303,22 +455,67 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "id": "fe0f36b4", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[5.0, 5.0, 5.0, 0.99999999, 0.0, 4.170212765957447e-06, 2.468085106382979e-06]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "thetaIV = theta.tolist() + x0\n", "\n", "thetaIV[3] -= 1e-8 # to make sure that the initial guess satisfies the constraints\n", "\n", - "boxBoundsIV = boxBounds + [(0.,1.), (0.,1.), (0.,1.), (0.,1.)]\n", + "thetaIV\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "2a07dc02", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: Optimization terminated successfully.\n", + " success: True\n", + " fun: 6.267485095752834\n", + " x: [ 3.850e+00 2.211e-02 4.114e+00 6.482e-01\n", + " 2.643e-06 4.215e-06 1.967e-05]\n", + " nit: 99\n", + " nfev: 10500\n", + " population: [[ 3.850e+00 2.211e-02 ... 4.215e-06 1.967e-05]\n", + " [ 4.083e+00 6.271e+00 ... 8.164e-06 1.845e-05]\n", + " ...\n", + " [ 4.550e+00 7.734e+00 ... 5.920e-06 1.729e-05]\n", + " [ 4.326e+00 3.862e-03 ... 8.806e-06 1.406e-05]]\n", + " population_energies: [ 6.267e+00 6.619e+00 ... 6.721e+00 6.385e+00]\n" + ] + } + ], + "source": [ + "objLegrand = SquareLoss(theta, ode_obj,\n", + " t0=t[0], x0=x0,\n", + " t=t[1::], y=y[1::,:],\n", + " state_name=['I','R'],\n", + " state_weight=numpy.sqrt(population*2)) \n", "\n", - "objLegrand = SquareLoss(theta, ode, x0, -1, t, y, ['I','R'], numpy.sqrt([population]*2))\n", + "boxBoundsIV = boxBounds + [(0.,1.), (0.,1.), (0.,1.), (0.,1.)]\n", "\n", "resDEIV = scipy.optimize.differential_evolution(objLegrand.costIV, bounds=boxBoundsIV, polish=False, seed=20921391)\n", "\n", - "print(resDEIV)\n" + "print(resDEIV)" ] }, { @@ -344,11 +541,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "id": "4f726a4a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'delta' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[21], line 9\u001b[0m\n\u001b[0;32m 2\u001b[0m ode \u001b[38;5;241m=\u001b[39m common_models\u001b[38;5;241m.\u001b[39mLegrand_Ebola_SEIHFR()\n\u001b[0;32m 4\u001b[0m \u001b[38;5;66;03m# initial guess from the paper that studied the outbreak in Congo\u001b[39;00m\n\u001b[0;32m 6\u001b[0m theta \u001b[38;5;241m=\u001b[39m numpy\u001b[38;5;241m.\u001b[39marray([\u001b[38;5;241m0.588\u001b[39m,\u001b[38;5;241m0.794\u001b[39m,\u001b[38;5;241m7.653\u001b[39m, \u001b[38;5;66;03m# the beta \u001b[39;00m\n\u001b[0;32m 7\u001b[0m \u001b[38;5;241m10.0\u001b[39m,\u001b[38;5;241m9.6\u001b[39m,\u001b[38;5;241m5.0\u001b[39m,\u001b[38;5;241m2.0\u001b[39m, \u001b[38;5;66;03m# the omega\u001b[39;00m\n\u001b[0;32m 8\u001b[0m \u001b[38;5;241m7.0\u001b[39m,\u001b[38;5;241m0.81\u001b[39m,\u001b[38;5;241m0.80\u001b[39m, \u001b[38;5;66;03m# alpha,\u001b[39;00m\n\u001b[1;32m----> 9\u001b[0m \u001b[43mdelta\u001b[49m, \n\u001b[0;32m 10\u001b[0m theta,\n\u001b[0;32m 11\u001b[0m \u001b[38;5;241m100.\u001b[39m,\u001b[38;5;241m1.0\u001b[39m]) \u001b[38;5;66;03m# kappa,intervention time\u001b[39;00m\n\u001b[0;32m 13\u001b[0m \u001b[38;5;66;03m# initial conditions, note that we have a 0.0 at the end because the model is a non-automonous ODE which we have converted the time component out of\u001b[39;00m\n\u001b[0;32m 15\u001b[0m x0 \u001b[38;5;241m=\u001b[39m numpy\u001b[38;5;241m.\u001b[39marray([population, \u001b[38;5;241m0.0\u001b[39m, \u001b[38;5;241m49.0\u001b[39m, \u001b[38;5;241m0.0\u001b[39m, \u001b[38;5;241m0.0\u001b[39m, \u001b[38;5;241m29.0\u001b[39m, \u001b[38;5;241m0.0\u001b[39m])\u001b[38;5;241m/\u001b[39mpopulation\n", + "\u001b[1;31mNameError\u001b[0m: name 'delta' is not defined" + ] + } + ], "source": [ + "from pygom import common_models\n", "ode = common_models.Legrand_Ebola_SEIHFR()\n", "\n", "# initial guess from the paper that studied the outbreak in Congo\n", @@ -530,8 +740,16 @@ "name": "python3" }, "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", "name": "python", - "version": "3.9.15" + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" }, "vscode": { "interpreter": { diff --git a/docs/notebooks/paramfit/fh.ipynb b/docs/notebooks/paramfit/fh.ipynb index 3b30551b..254d1a26 100644 --- a/docs/notebooks/paramfit/fh.ipynb +++ b/docs/notebooks/paramfit/fh.ipynb @@ -4,77 +4,65 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Parameter Estimation: FitzHugh Example\n", + "# Parameter Estimation via hill climbing\n", "\n", - "## Defining the model\n", + "## FitzHugh-Nagumo model\n", "\n", - "We are going to investigate another classic model here, the\n", - "FitzHugh-Nagumo, or simply FitzHugh here. The model has already been\n", - "defined in {mod}`common_models` so we can load it rather than define by scratch.\n", + "Here we demonstrate parameter estimation applied to the classic model of FitzHugh-Nagumo {cite}`fitzhugh1961impulses`.\n", "\n", - "#TODO ref for FH-N" + "$$\\begin{aligned}\n", + "\\frac{dV}{dt} &= c ( V - \\frac{V^{3}}{3} + R) \\\\\n", + "\\frac{dR}{dt} &= -\\frac{1}{c}(V - a + bR).\n", + "\\end{aligned}$$\n", + "\n", + "The difficulty in inferring the correct parameters makes this is a commonly used model when developing new methodology with regards to ODEs {cite}`Ramsay2007` {cite}`Girolami2011`.\n", + "This is due to the likelihood landscape for parameters being rough (i.e. large second derivative) as well as multimodal.\n", + "\n", + "The model has been defined in {mod}`common_models` so we can load it rather than define by scratch." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "a74b67ba", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "from pygom import SquareLoss, common_models\n", - "\n", - "import numpy\n", - "\n", - "import scipy.integrate, scipy.optimize\n", - "\n", - "import math,time,copy\n", - "\n", - "import matplotlib.pyplot as plt\n", - "\n", - "x0 = \\[-1.0, 1.0\\]\n", - "\n", - "t0 = 0\n", + "from pygom import common_models\n", "\n", "# params\n", "paramEval = [('a',0.2), ('b',0.2), ('c',3.0)]\n", "\n", + "# set up ode\n", "ode = common_models.FitzHugh(paramEval)\n", "\n", - "ode.initial_values = (x0, t0)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "100b72c6", - "metadata": {}, - "source": [ - "Define a set of time points and we can see how the two states $V$ and $R$\n", - "are suppose to behave.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e8291f05", - "metadata": {}, - "outputs": [], - "source": [ - "t = numpy.linspace(1, 20, 30).astype('float64')\n", + "# set time steps\n", + "import numpy\n", + "t = numpy.linspace(0, 20, 100).astype('float64')\n", "\n", - "solution = ode.integrate(t)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2fccb37", - "metadata": {}, - "outputs": [], - "source": [ - "ode.plot()" + "# set initial conditions\n", + "x0 = [-1.0, 1.0]\n", + "ode.initial_values = (x0, t[0])\n", + "\n", + "# solve and plot\n", + "solution = ode.integrate(t[1::])\n", + "\n", + "import matplotlib.pyplot as plt\n", + "f, axarr = plt.subplots(1,2, layout='constrained', figsize=(10, 2.5))\n", + "\n", + "axarr[0].plot(t, solution[:,0])\n", + "axarr[1].plot(t, solution[:,1]);" ] }, { @@ -83,36 +71,55 @@ "metadata": {}, "source": [ "\n", - "## Estimate the parameters\n", + "## Estimating the parameters\n", "\n", - "Obtaining the correct parameters for the FitzHugh model is well known to\n", - "be difficult, because of its multimodal surface. Although this\n", - "has been shown many times in the literature, so we will omit the\n", - "details. For further details see {citets}'FitzHugh`.\n", + "Now we use optimisation algorithms to find the parameters by minimising the loss function.\n", "\n", - "#TODO ref?\n", - "\n", - "We will give the fitting a go with an initial guess which will enable us to recover the original parameters. First, we try the fitting process with only one target state.\n", - "\n" + "Let's assume we only know the $R$ state:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "97050c8b", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH\n", + " success: True\n", + " status: 0\n", + " fun: 1.38065348108425e-12\n", + " x: [ 2.000e-01 2.000e-01 3.000e+00]\n", + " nit: 18\n", + " jac: [ 1.479e-05 7.406e-08 9.735e-06]\n", + " nfev: 21\n", + " njev: 21\n", + " hess_inv: <3x3 LbfgsInvHessProduct with dtype=float64>\n" + ] + } + ], "source": [ - "theta = [0.5, 0.5, 0.5]\n", + "from pygom import SquareLoss\n", + "import scipy.optimize\n", "\n", - "objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::,1], 'R')\n", + "theta = [0.5, 0.5, 0.5] # initial guess for params\n", "\n", - "boxBounds = [(0.0,5.0), (0.0,5.0), (0.0,5.0)]\n", + "objFH = SquareLoss(theta, # initial parameter guess\n", + " ode, # PyGOM ode object\n", + " t0=t[0], x0=x0, # initial time and conditions\n", + " t=t[1::], y=solution[1::,1], # time steps and solution\n", + " state_name='R') # name of param in solution\n", "\n", - "res = scipy.optimize.minimize(fun=objFH.cost, jac=objFH.sensitivity, \n", - " x0=theta, bounds=boxBounds,\n", - " method='L-BFGS-B')\n", + "boxBounds = [(0.0,5.0), (0.0,5.0), (0.0,5.0)] # min and max parameter estimate bounds\n", "\n", + "res = scipy.optimize.minimize(fun=objFH.cost,\n", + " jac=objFH.sensitivity, \n", + " x0=theta,\n", + " bounds=boxBounds,\n", + " method='L-BFGS-B')\n", "print(res)" ] }, @@ -121,31 +128,7 @@ "id": "f2cbc5b1", "metadata": {}, "source": [ - "Then we try the same again but with both states as our target. " - ] - }, - { - "cell_type": "markdown", - "id": "fa53fd4a", - "metadata": {}, - "source": [ - "objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::,:], ['V','R'])\n", - "\n", - "res = scipy.optimize.minimize(fun=objFH.cost, jac=objFH.sensitivity, x0=theta,\n", - " bounds=boxBounds, method='L-BFGS-B')\n", - "print(res)\n" - ] - }, - { - "cell_type": "markdown", - "id": "d94fcdab", - "metadata": {}, - "source": [ - "\n", - "Note how the estimates are the same, unlike other models.\n", - "\n", - "#TODO why is this?\n", - "\n" + "We see this is a good fit." ] }, { @@ -155,23 +138,42 @@ "source": [ "## Estimating initial value\n", "\n", - "We can further assume that we have no idea about the initial values for\n", - "$V$ and $R$ as well. We also provide a guesstimate to set off the\n", - "optimization. The input vector $\\theta$ must have the parameters first,\n", - "then the initial values, along with the corresponding bounds.\n", + "We can extend this example to the case where the initial values of $V$ and $R$ are unknown.\n", + "We also provide a guesstimate to set off the optimization.\n", + "The input vector $\\theta$ must have the parameters first, then the initial values, along with the corresponding bounds.\n", + "We must also use the `costIV` and `sensitibityIV` options to let the solver know Initial Values.\n", "\n", - "First, only a single target state, i.e. we only have observations for\n", - "one of states which is $R$ in this case" + "First, only a single target state, i.e. we only have observations for one of states which is $R$ in this case" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "138e3689", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH\n", + " success: True\n", + " status: 0\n", + " fun: 0.7339990203493604\n", + " x: [ 0.000e+00 6.052e-01 8.512e-01 -7.159e-01 9.061e-01]\n", + " nit: 20\n", + " jac: [ 4.341e+00 3.166e-04 -2.071e-04 -1.664e-05 -5.012e-05]\n", + " nfev: 25\n", + " njev: 25\n", + " hess_inv: <5x5 LbfgsInvHessProduct with dtype=float64>\n" + ] + } + ], "source": [ - "objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::,1], 'R')\n", + "objFH = SquareLoss(theta, ode,\n", + " t0=t[0], x0=x0,\n", + " t=t[1::], y=solution[1::,1],\n", + " state_name='R')\n", "\n", "boxBounds = [(0.0,5.0), \n", " (0.0,5.0),\n", @@ -181,30 +183,105 @@ "\n", "res = scipy.optimize.minimize(fun=objFH.costIV,\n", " jac=objFH.sensitivityIV,\n", - " x0=theta + [-0.5,0.5],\n", + " x0=theta + [-1.0,1.0],\n", " bounds=boxBounds, \n", " method='L-BFGS-B')\n", - "\n", "print(res)" ] }, { "cell_type": "markdown", - "id": "af2b3afa", + "id": "636b28df", "metadata": {}, "source": [ + "We see not so good from values and also when we plot: We fit well to the data which we know." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "a515c219", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA/MAAAEFCAYAAACvqLeOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAC1eElEQVR4nOzdd3hUZfbA8e+dmfRKekhC6L333qUjiCI27O7a1r7uuu666urPLeqqa6+o2KVKE5TeIRA6oZNOem9T7u+PdyYUA6TMzJ2ZvJ/nycNkksycwGXmnvue9xxFVVUVSZIkSZIkSZIkSZLchk7rACRJkiRJkiRJkiRJahiZzEuSJEmSJEmSJEmSm5HJvCRJkiRJkiRJkiS5GZnMS5IkSZIkSZIkSZKbkcm8JEmSJEmSJEmSJLkZmcxLkiRJkiRJkiRJkpuRybwkSZIkSZIkSZIkuRmD1gFcicViITMzk6CgIBRF0TocSZIkSdKUqqqUlpbSsmVLdDrPuR4v3+8lSZIk6bz6vt+7dDKfmZlJQkKC1mFIkiRJkktJS0sjPj5e6zDsRr7fS5IkSdJvXe393qWT+aCgIED8EsHBwRpHI0mSJEnaKikpISEhofb90VPI93tJkiRJOq++7/cunczbSu2Cg4Plm7skSZIkWXlaKbp8v5ckSZKk37ra+73nbLiTJEmSJEmSJEmSpGZCJvOSJEmSJEmSJEmS5GZkMi9JkiRJkiRJkiRJbkYm85IkSZIkSZIkSZLkZmQyL0mSJEmSJEmSJEluxqHJ/CuvvMKAAQMICgoiKiqKmTNnkpKS4sinlCRJkiRJkiRJkiSP59DRdBs2bOChhx5iwIABmEwmnn32WSZMmMDhw4cJCAhw5FNrpspo5k8L9pNdXEV0sC9RQT5EBfvQNTaEoe3C0ek8a5yQ1LypqsrpvHLiWvjhY9BrHY4kSVKDVBnN7DlbyPbTBew5W0i/xBY8Oq6DfK+WJEmS3IJDk/lVq1Zd9Plnn31GVFQUSUlJjBw50pFPrZkfk9JZkpxZ59faRwVyz/A2XNcnDl8vmfhI7u/5pYf4fNtZvPU6esSH0D+xBX0TWzCyQyR+3vIYl9zb+pQc9pwtJKu4iuySKrKLqwjx8+LGAQlc26ulfB13Yydyyvj70oPsOl1IjdlSe//mE3lkFFXyz1k9MOjlTkRJkiTJtTk0mb9UcXExAGFhYXV+vbq6murq6trPS0pKnBKXvZjMFj7ceAqA2wa3onV4ADml1WQVV7H+aA4ncsp4ZuEBXv05hdsGJ3L3sDaE+HtpHLUkNc7CPel8vu0sADVmC0lnC0k6WwhAWIA3dw5tze1DEgn199YyTElqlBM5Zdz52a46v7b7bCEvLz/Cjf3juW1wIonhnllp5qkOZhRz+6c7KSivASA62IchbcOJDfXjw42n+DEpnZJKI2/d3EdesJEkSZJcmqKqquqMJ1JVlRkzZlBYWMimTZvq/J7nn3+eF1544Tf3FxcXExwc7OgQm2zpvkwe+WYvYQHebPnT2ItWJkurjHy3K43Ptpwho6gSgCAfA3cPb8Pdw9sQ4ieTesl9HM0uYeY7W6gyWnhkXAdm9YljtzWZ33gst/YY9/fWc8vAVtw7oi0xIb4aRy1J9fe/X4/z2ppjdIgKZEbvlsSE+BET7MvBzGLmbz9LeqE4xnUKXNurJX8Y14F2kYEOj6ukpISQkBC3eV+sL2f9XjtPF3DPvF2UVpvoERfCGzf1pm1EAIoiyurXHD7HQ1/vocZkYUjbcD68vR9BvvL9WZIkSXKu+r4vOi2Zf+ihh1i+fDmbN28mPj6+zu+pa2U+ISHBLU5aVFVlylubOZJVwhPXdOSRcR3q/D6T2cLKg9m8s+4ER7NLAQj2NXDviLbcPbwNgT5OLZaQpAYrrTJy7dtbOJ1XzsiOkXx25wD0F+wvNZktrDiYzXvrT3IkS1TXeBt03DYokQdGtyMyyEer0CWp3qb9bxMHM0r41/U9mDOg1UVfM1tUNhzL4fOtZ9lwLBcQSf2M3nE8PLa9Q5N6mcw33rqjOdw/P4lqk4WBbcL45I7+dSbq207mc98XuymrNtG3VSg/3j9U7qGXJEmSnMqlkvk//OEPLF68mI0bN9KmTZt6/5w7nbSsT8nhzs924e+tZ+ufx161tNhiUVl5MJs3fjnG8ZwyQJQmPzi6HbcNTpSlfZJLUlWVB+bvYdWhbFqG+LLskRGEBdR9rKuqyoZjubyz7gS7zojyez8vPXcMbc3vR7alxWV+TpK0llZQwYh/r0OnwK5nxxMeePkLUAczinnz1+OsOXwOEEn9rL7xPDquAwlh/naPzZ3eFxvC0b/X2qPn+N0XSZgsKmM7R/HurX2v+D57IL2Ymz/aTlm1ic/uHMCYzlF2j0mSnOVcSRVbTuRhsqioqorZAmEBXozvEi17Q0ge41xJFYv2ZrB8fxbtIgP467SuRFzh/dvVuUQyr6oqf/jDH1i0aBHr16+nQ4e6V6svx51OWuZ8sI0dpwu4d3gb/jqta71/zmxRWbY/kzd/Oc6pvHIAYkN8eXRcB27oFy9fZCWX8vnWM/x96SG89Ao/3D+U3gmhV/0ZVVXZdDyP19YcY19aESC2mPx+lKhG8feW1SiSa/lk82n+sewwA9uE8f3vh9TrZw5mFPPGL8f45UgOAF56hVsHJfLQmPZ2rUZxp/fFhnDk75VZVMnkNzdRXGlkeq+WvH5jL7zq8d76j2WH+WTzacZ0iuSzuwbaNSZJcpafD2Xz1A/7KK0y/eZr1/WJ4/Ube9VuM5Ekd6OqKqsOZvPd7jQ2HsvFckFWGxbgzYszujG1R6xbHuP1fV90aKb40EMPMX/+fL7++muCgoLIzs4mOzubyspKRz6t0yWdLWTH6QK89Ar3jKh/5QGAXqcwo3ccqx8fyb+v70nLEF+yiqv488IDTPjvRlYdzMJJOyEk6aoW7kkH4OmJneuVyAMoisLIjpEsfnAoH9/eny6xwZRWm3h19TFG/ns9X2w7Q43JcvUHkiQn+flQNgCTusXU+2e6x4Xw8R0DWPzQMIa1D8doVpm39Qwj/72ON3455qhQpaswW1Qe+zaZ4kojPeNDeG12/RJ5gNsGJwKw/lguZ/PLHRmmJNmd0Wzh5eWH+f2XSZRWmWgfFciYTpGM6xzF+C5R6HUKi/ZmMG/rGa1DlaRGsVhUnl18kAe+2sP6FJHI909swd+mdaVzTBAF5TU8/PVeHvxqD7ml1Vd/QDfl0GT+vffeo7i4mNGjRxMbG1v78d133znyaZ3u/Q0nAZjZO47YEL9GPYZBr+PGAQmsfWo0z03rSliAN6fyyrl//h6ue3cr20/l2zNkSWqUM/kVAIzoGNHgn1UUhfFdo1n+h+G8eVNvWoX5k1dWzXNLDjH+9Q38tC9TXriSNJdXVs2uMwUATOgW3eCf750Qylf3DuarewfRKyGUSqO5tmu6O9i4cSPTp0+nZcuWKIrC4sWLr/ozGzZsoF+/fvj6+tK2bVvef/99xwdaT2+vPcHOMwUEeOt566Y+eBvqf9rTJiKAUR0jUVWYv/2sA6OUJPvKKq7k5g+389Gm0wDcO7wNKx8dwWd3DeSTOwfw8R0DeGZyZwBeWn6EHfIcU3IzZovKnxbs5+sdqSgK/H5UW9Y9NZofHxjKPcPbsPTh4Tw6rgMGncLKg9nMfGcL5dW/rU7xBA5N5lVVrfPjzjvvdOTTOtXJ3DLWHD5XeyA1la+XnruHt2HDH0fzyLgO+HvrSU4r4qYPt3P3vF0cP1dqh6glqeGKK4wUVxoBSGjR+L3AOms1yi9PjOIfM7oREehDakEFf/hmLzPf2SIvXEma+uXwOVQVesSFEN+E43xY+wgWPziUD+f24+Gx7e0YoWOVl5fTq1cv3n777Xp9/+nTp5kyZQojRoxg7969/OUvf+GRRx5hwYIFDo706nafKeDNX0VVxD9mdqd1RMNHCN4+RKzOf787ncoas13jkyRHyCmpYta7W9l9tpAgXwPv39aPv07r+puKlHuGt2FG75aYLSoPfb2HrGLPqpqVPJfJbOHJ75P5ISkdnQJvzOnNM5O70OaC13hvg47Hr+nIkoeH0TLEl4yiSr7Zmaph1I4jN2Q30W7rCs7gNuG0jwqy2+MG+XrxxDUdWf/H0cwdnIhBp7D2aA4T39jIMwsPkFNaZbfnkqT6SC0Qq/IRgT4E2GHqgrdBx9whrdnwx9E8Pr4j/t569qUXc9OH27ln3i5O5MgLV5Lz2UrsJzZiVf5SiqIwoVsMUUHuM5Zx8uTJvPTSS8yaNate3//+++/TqlUr3njjDbp06cK9997L3XffzauvvurgSK+suMLIo98mY1HFvuBZfeueonM1oztFEd/Cj+JKI0v3Zdg5Skmyryqjmd99mURWcRVtIwNY9ofhTOpe93YhRVH456yedIkNJq+shvvn76HaJC9YSa7NaLbw2HfJLE7ORK9T+N/NfZnRO+6y39+tZUjthLGPNp3yyGNcJvNNlF0s9mC0jrB/12KAqCBf/jGzO6sfH8nEbtFYVPhmZyqj/7Oet349LlcKJKc5WyD2jCaG2/dYD/Ax8Oj4Dmz44xhuG9wKvU7h16M5THxjE88tOehWJcqSeyutMrLlhKgMmdiA/fLN2bZt25gwYcJF902cOJHdu3djNBov+3PV1dWUlJRc9GEvqqryzKL9ZBRVkhjuz4szujX6sfQ6hbnWvfOfbz0rtwJJLktVVZ5ddJDktCJC/Lz49I4BJIZfuRrFz1vPB7f1I8TPi31pRbz163EnRStJjfPSssMs25+Fl17h3Vv7MrVn7FV/5rq+ccQE+3KupJpFezzvoqxM5psou0SUJUUHO3blpW1kIB/M7c8P9w+hV0IoFTVmXl9zjHGvrWdJcoY8wZAc7qx1v3yiA8ZtAUQG+fDSzB6sfnwk47tEY7aofLHtLKP+s44PN570yKupkmtZl5JLjdlC28gA2kc5bla8J8nOziY6+uIqhujoaEwmE3l5eZf9uVdeeYWQkJDaj4SEBLvFZDSr+HsbMOgU3rqpT52z5Bvixv4J+Bh0HM4qYU9qoZ2ilCT7+mTzaRbsSUevE0lOfbeVtAr35/+u6wHANzvTZENayWX9fCibz7eJ/iVv39K33hfdfQx67rU2KH9vw0lMZs86xmUy30TZxaLcPTbEOWWUA1qHsfjBobx1cx/iQv3ILK7i0W+Tuf69reyVJxmSA6Vak3lHzM6+ULvIQD6+oz9f3zuIrrHBlFaZ+L8VR5n4343W/czywpXkGOdL7GPccoyNVi79u7L9H73S3+EzzzxDcXFx7UdaWprd4vE26Hh1di9WPTaSXvWcunElLQK8ubZXSwC+2CYb4UmuZ11KDv+34ggAf5vahWHtG9akdmK3aKKCfCgor+HXI+ccEaIkNUlGUSVP/7gfgN+NbNvg6rmbB7aihb8XZ/MrWHEw2xEhakYm802UZU3mHb0yfyFFUbi2V0t+fXIUT00Qe433pBZx3btbeeqHfR49fkHSjm3PvL3L7C9naPsIfvrDcP59fU8ig3w4k1/BvV/s5vZPd8pGkJLdVRnNrD8qZsTLEvv6i4mJITv74hOjnJwcDAYD4eHhl/05Hx8fgoODL/qwN3tWV9w+pDUAKw5kkVcm32Ml15FZVMkj3+zFosJNAxK4Y2jrBj+GQa/jhn6ir8R3u+13YU2S7MFktvDoN3sprjTSKz6EpyZ0avBjBPgYuHOoWJ1/d90Jj1oYksl8E50rsa3MN24kXVP4eul5eGwH1j01uvZF+MekdMa+up6PN53C6GFlJJK2nJ3Mg9iveuOABNY9NZr7R7XDW69j0/E8Jr25iX8sO0xp1eX35EpSQ+w6U0B5jZmYYF96xoVoHY7bGDJkCGvWrLnovtWrV9O/f3+8vJpW3u5QqgqFZ6CiQNy+ih7xIfSMD8FoVlnlYas6kvtSVZW/LDpAaZWJ3gmhvDije6Orim7sL7a6bDyWKzvbSy7lrV+Pi+kMPgb+d3PfBo0YvdAdQxMJ8NZzNLuUdSk5do5SOzKZb4Iqo5nCCpFMxDhxZf5S0cG+vDq7F4seHEqv+BBKq028tPwIk9/cxNYTl9+zKEn1VW0yk2l9c28V1vDxTk0V6GPgz5M7X7Sf/pPNpxn72gYW75U9I6SmSy8Ux3e3lsHodM23xL6srIzk5GSSk5MBMXouOTmZ1FQx0ueZZ57h9ttvr/3++++/n7Nnz/LEE09w5MgRPv30Uz755BOeeuopLcK/ssoiOLQYljwMr3eFN3vBv9vAKwnw3nD49lZImgfmui8STukhGi2tPJjltJAl6UqWJGeyPiUXb72OV2f3bHSSA9A6IoBBbcKwqPDj7nQ7RilJjbf1ZB7/W3cCgJdn9aBVExaUQv29udXa0PSddSc95tyx6fOlmjHbqryfl55gP+3/Kvu0asGiB4fxY1I6/1p1lBM5Zdzy8Q5m9G7Js1O6EKXhBQfJvaUXVqKq4O+tJyLQW7M4WkcE8PEd/VmfksPzSw9xJr+Cx75L5uudqfxjRnc6xdhvPKTUvOSUiNLpqGAfjSPR1u7duxkzZkzt50888QQAd9xxB/PmzSMrK6s2sQdo06YNK1as4PHHH+edd96hZcuWvPXWW1x//fVOj/2yTDWw7iXY9g5YTOfv13mBxQg1pXDugPg4ugy2vAVj/wpdZ4LufHI0uXsM/1x5lO2nCigoryEsQLvXQknKK6vmhZ8OAfDIuPZiPLKqwtmtsOsjOHdIXJiymMSfPkHQfRb0vgVatK7zMecMSGDH6QK+253GQ2PaN+sLm5L2qoxm/rRgP6oKc/on1PYuwWKBgpOQtU985B2DoFiI7w9x/SCiI+j0dT7mvcPbMG/LGZLOFrIvvZjeduirojXtM1A3ZtsvHxPi6zLNknTWsuSJ3WN4bXUKX24/y5LkTNYeyeHJCR2ZO6Q1evniLDWQrfldqzB/lzjWR3eK4ufHw/lo4yneXneCnacLmPrWJu4b2ZZHxnbAz7vuF3FJupycUvF6HulGM+EdYfTo0VdcrZg3b95v7hs1ahR79uxxYFRNkJsCC+6FbNE4iYiO0H68+EgcBqhQlCZK7s8dgO3viZPEH++C2Ddh4svQejgAieEBdGsZzKHMEtYczmbOgFaa/VqS9PzSQxRWGOkSG8zvh8XB3vmw433IPlD3D5Rlw4Z/iY/WI6Dv7dBtFujPpwKTu8fy9yWHSC+sZNup/AY30pMke3p3/UnSCiqJCfblb9O7grESNr0ujvPqOsaZJn0m/vQOgi7TYfzzEHTxtJWoYF8mdY9h6b5MftqX6RHJvCyzbwLbyryWJfaXE+LnxYszurP0oeG1pffP/3SY697dwqHMYq3Dk9yMbb98Kwd3sm8IH4PoGfHLE6O4pms0JovKe+tPMuGNDaz3oL1QknPkWBuHRgY175V5j6GqsPMj+GCkSOT9wmDOfHh4F0x6BdqPAy9f8PKDyI7QcQKMeBIe2Quj/wLegZCVDJ9Phz1f1D6srdR+xQG5b17SzupD2Szbn4Vep/C/UeD1zgBY8pBI5A2+0PcOmLsI7v4Z7l0Lv98I138CbccACpzZBAvvgy9nQtn590s/bz0z+ojVz+92yUZ4knbO5JXz/oaTADw3vSuBZ36BdwbBxn+LRN7gB3H9of89MOVVGPoIJA4HrwBRbbXva3i7P2x/H8ymix57mnU2/fL9WVgs7l9qL1fmm+DClXlX1SM+hIUPDuPrnan8e9VR9qcXc+3bW7h3RBseG9dRrmBK9VI7Y96Jze/qK76FPx/d3p/Vh7L5+9JDpBVUcudnu5jWM5bnr+1GRKBMzqSrsyXzUTKZd3+mGvh+LhxbJT5vNxZmvAvBsVf/WZ8gGP0nGHAP/PwX2P8dLP0DVBbCsEeZ3D2G//ycwpYTeRRXGAnxd+Emf5JHKqky8rclBwH4d7c02i9/HowVEBwHA+8Tibx/2G9/MLYX9LhBVKIkfw1b3xJJ/fsjYPY8SBwCwJz+rZi/PZVVh7LlMS5pQlVVnlt6iBqThWvbqEw++DikrBRfDI6Dif8HnaddVFVSy2KGtJ3i9TtzD6z6EyTPh6n/hYQBAIzsGEmQj4Hskir2pBbSv3Ud/1/ciFyZb4JsN0jmQXQEnzs4kV+fGMWUHjGYLSofbDjFxDc2ygZ5Ur2kFpQD0Crc+c3v6mtCtxjWPDGKe4a3QafAsv1ZXPO6bJAn1U+eTOY9h8EbAiJB7wOT/gm3LqhfIn+hgAi47gMY9pj4fM1zsOY52kYE0DkmCJNFZY2cxy1p4J21JzhXUsXTwWuYdfxPIpFvNw4e3AbDH687kb9QaIK4YHXfOojsLMrv502FrW+DqtI9LpguscHUmCwsTs5wzi8lSRdYdTCbjcdyaa3P57WyP6GkrASdAYY9Cg/thG4z607kQeyVTxwC9/4C0/4LvqGiYuWzyXDkJ0BMA7umqyi/X7bf/RuaymS+CWqTeRcss69LVLAv797aj49u709siC+pBRXc8vEO/rr4AGXVpqs/gNRsnc13vTL7ugT6GPjbtK4seWg4XWKDKaww8th3ydzz+W4yi+SoHaluqqqSa0vm3eT1XLqKSf+E362HwQ9c1MSuQRQFrnkBrnlRfL7lTfjpESZ1iwJg5QH3PwmU3EtaQQWfbznF/xk+4cGaz1BQRZnxLd+DbwNHakZ2hHt/he43gGqG1c/CiqdQgDn9z487liRnKq828eKyw8SQz+LAf+JVmg5h7eD+LeK12Cewfg+k00P/u+EPSWL/vMUIP9wpJpoA03pZS+0PZGF281J7mcw3QXaJe6zMX+qartGsfnwktw0WzXvmb09l4n83svm4XKWXfstiUc/PmHfxZN6mR3wISx8expPXdMRbr2Pt0Rwm/ncj3+9Ok6v00m8UVRipMVsANJ3WINmRTyBEd7XPYw17FK59GxQd7PmC24wLANh0PI/SqrrH2EmSI/xr1VEeU77hFsNaVBRx0Wrqa5dfpbwan0C4/mOY/B9AgV0fw5Y3md6rJToFDmQUk2Z9/5ckZ/jf2hOYi7P4we//CK3OgBZt4M5lENW5cQ8YEAE3zIOec8Rkhx/vhgM/Mrx9JCF+XuSWVrPrTIFdfwdnk8l8E7jbyvyFgny9eGlmD76+dxDxLfzIKKrktk928OyiA1TUyFV66bzcsmqqTRb0OoW4Fn5ah1NvXnodfxjXgeWPDKdPq1BKq008/eN+7vsiqXYVVpLg/H75UH8vfAyyj4hUh75zYfqbAITv/A+zWxynxmxh7VHZbFNyjj2phVgOLuJ+gygVVmZ9JCpPmjphRlFg0O9EY0iAX/5O+OmfGNw2HICVB2UFiuQc6YUVLNm8l6+9XyZBzYLQVnDHTxDcsmkPrDfAzPeg962iCmXhfXgf+oGJ3Wyl9pl2iF47MplvJJPZQm6ZOAGMdbOV+QsNbR/Bz4+N5PYhiQB8tSOVqW9tJjmtSNvAJJdhK7FvGeqLl979XjI6RAfx4/1DeXpSJ7z0Cr8cOcfENzbKElmpVq7cLy/VR9/boc9cFFReMP6XGPJZIV9HJCdQVZV5i1fxH68PxB1D/wA9Z9v3SQY/AIMfFLcXP8AdcWK/vJzcIDnL/1Yf5gP9v2ivy0QNjheJfGiCfR5cpxcVVn1vB9UCi37PbZGnAFh5IBuTtTrPHbnfmbmLyCurwWxR0esUwt28W3aAj4EXZ3Rn/j2DiAn25XReOde/t5U3fznu1ge3ZB9n863N79ykxL4uep3Cg6Pbs/RhsZe+oLyGB77aw1M/7KNc9oto9mwz5qOa+Yx5qR6m/AdieuJvKuJd7zfZkpIlX0Mkh1u95ziP5r1AgFJNTcIwGPe8Y55owktif7G5hmv2PU57XQbJaUVkyJ4zkoMdO1dK4oE36ak7jcmnBcodS6FFa/s+iU4H096EXrcAKj12/pH2fmXkl9ew/ZT7ltrLZL6RbPvlo4N80OuaWOLkIoZ3iGDVYyOY1jMWs0Xlv78c48YPtpFeKPdLNWfnZ8y7bif7+uoSG8ySh4bx0Jh26BTR3Gfa/zZzMKNY69AkDckZ81K9efnBjV+g+obQV3eCJ/mSdSmy1F5ynGqjEf8VD9FOl0WJTzTeN33R+D3yV6PTw6yPIH4AuupiPvd7Ex9qWHVQrs5LjrV4yY/8Xi+2kBhmvAXh7RzzRDodTHsdorqhlOfyfsAH6LCw/ID7ltrLZL6RsovFVcpoNy6xr0uovzdv39KXN2/qTZCvgT2pRUx9azOrD8kX8ubKlWfMN4a3QccfJ3bm6/sGExsiKlGue3cLH208hcXNO5pKjZNTIsvspQYIa4Ny3YcA3GX4mYztCzQOSPJke374DyPMO6nBgPfN80VDL0fy8oObv4XAGOLM6Txh+EFuS5McKvlEKjenv4xeUSnpfCN0vdaxT+jlB7PngZc/7cuSeEi/mJUHszG6aTWyTOYbydb8zp33y1/JjN5xrHhkBL0SQimuNPK7L5N44adDVJvMWocmOZm7dbKvr8Ftw1n56AgmdovGaFZ5ecUR7v1iN8UVsjt1c2PrfyJX5qV66zSJnB6/A2BaxptUlZdoHJDkiaoKM+lx7H8A7O/6NL6tBzrniQMiYPobANyrX4EldUftea8k2ZOqqhQueJIEXS4FXjEEz3zNOU8c2RGmvg7AY14L6VS5ny0n3HOql0zmGynLVmbvhp3s6yshzJ8ffj+E+0a0AeCzLWeY/f42uXeqmakts/eQlfkLhfp78/5t/XhpZne8DWKE3bS3N8my+2Ymx/p6LmfMSw0ROf15sogkTskl66eXtA5H8kBp3/+RQCo4orSn58wnnPvknSZDz5vQKyr/8fqAX/afce7zS83C4bVfMaZyNRZVwTzzffANdt6T974Zet+KHgtver/Nxr1HnPfcdiST+UY65+Er8zbeBh3PTu3KJ3f0J9Tfi/3pxUz/32a2nnTPq1dSw5RWGSkorwHcuwHelSiKwm2DE1n4wFASwvxIK6hk1ntb+W5XqtahSU5i62Yf6ebNTCXnUrwDWN/2SQASUj6B3GMaRyR5kupTW+iQtQyAtCEv4u3t5fwgJv+Tcu8I2umyCN7+b+c/v+TR1MpC4jc/A8C22NuI7DbG+UFM+Q8VIe2JUQrpefS/btn4WybzjZRV7Pkr8xca1yWaZX8YTvc40Ql87ic7+WTzaVRV7jH2ZLb98mEB3gT5anAi4UTd40JY9vAIxnWOosZk4U8LDvDMwv3UmNzvhV1qGFsDvKhgmcxLDdNm2Gx+NffBoJqwLH8S5HuiZA8WM2ULHwPgJ/14Ro+drE0cfi2onChKkaeWLaQwZbM2cUge6cyS/yNELeGkGkeXW/6pTRDeAXjPeheAmazj8M5ftYmjCWQy30jnSmwr834aR+I88S38+fH+oVzXJw6zReUfyw7z+HfJVBnlPnpPdb6TvWeuyl8qxN+Lj27vzx8ndkJR4Judadz+6Q4KrdUJkuepqDFRZh0tJhvgSQ01oE04b3rdS5Xqhe7MRjgom+FJTWfc8THhZccoVv0xjv4b3gbtTtcj+s1grc849IqKbunDYJZ9ZaSmU4vSaHl0HgB7Oz1OWHCgZrEYEgexK3QKAOEbnwWLe+U1MplvBFVVa1fmY5rJyryNr5ee12/sxd+nd0WvU1icnMmtH++oLcWWPEtt8zsP3C9/OTqdwkNj2vPJHf0J8Naz/VQBM9/dwomcMq1DkxzAVmLv56Un0MdB454kj6XXKXTr3pN3TDPEHT8/C1WyGZ7UBOV5WH79BwAfed3GtCE9NQ4Izgz4G3lqMCHlp2HP51qHI3mAnKV/x4cadqpdGDVtrtbhUDP6b5SofsRVpmDZ86XW4TSITOYbobjSSLW19LY5lmUqisJdw9rw5T0DCfY1kHS2kFnvbuF0XrnWoUl2Ziuzby4r8xca2zmahQ8OI76FH2fzK7ju3S1sPJardViSnV1YYq8oisbRSO5oUvdYPjRPI5UYKMuGTU7qxix5JNOvL+NjKuWQJZH4ax7UdFXeZlyfjrxpmgWAZd0/obpU44gkt5Z9kMhTCwHY1/lJIl1gYXRA9868q8wBwLzmeago0DagBtD+FcIN2VblwwK88fXSaxyNdoa2i2Dhg0OJb+HHmfwKZr27hd1n3Ofgl64utUBcoGmOyTxAp5ggFj80jP6JLSitMnH3vF0sSc7QOizJjmwz5mXzO6mxhrQNx9vXnxdrbhV37PwQyuSFP6kRSjJR9opVwXd972VWv0SNAxISwwPYFzWT05ZodBW5sPVtrUOS3FjxT39Bh8oKyyCmTp6mdTiAaPid13kuRy0JeFUXwrqXtQ6p3mQy3wjZzWAsXX21jwpi0YPD6BUfQmGFkVs+3sHPh7K1Dkuyk/Nl9gEaR6KdiEAfvrpvENN7tcRkUXn022TmbTmtdViSneSU2sbSyWReahxvg47xXaL5xdKXTP8uYKyArW9qHZbkhsyb30SvGtlh6czQcTNcYlXeZkKPeP5tukl8svV/UHpO24Ak93RqPSEZGzCqeg52eoyWoa7Te2xizwSeN90BgLr7U8jar3FE9eM6rxJuJLuZjKWrr8ggH7793RCu6RpNjcnCg1/tYem+TK3DkppIVVXOWVctm/ux7mPQ8+ac3twxRKySPP/TYV5fnSKnOXgA2575qKDmfYxLTTOpewyg8LrxenHHzo+hLEfTmCQ3U5aDmjQPgC8MN3J933ht47nE5B6xrLQMJNnSHozlsEGj7uOS+7JYqFzxLABfmcdz48RRGgd0sREdIjhg6MFP5sEoqgV+fUHrkOpFJvONkN3MxtLVh5+3nvdu7cssa6f7R7/dy/e707QOS2qCsmpT7Vi28EBvjaPRnk6n8Py13Xh8fEcA3lp7gueWHMJikQm9O7PtmY+UneylJhjZIRI/Lz0/lnahIrIPmCph8xtahyW5EXXbOxjMVSRb2tF1+LUut42zXWQgnaKD+T/jzeKOpM8h77i2QUnu5dhK/PIOUqr6cazTA7SOcK2qT18vPWM6R/Ef0xws6OHEL5CepHVYVyWT+UaQK/N1M+h1vDq7F7cMaoWqwtM/7ueLbWe0DktqpLwyMaHA31uPv7fs8g2i+eOj4zvwj5ndURT4cvtZnv/pkFyhd2MymZfswc9bz5jOkYDCsvA7xZ27P4FSue1MqoeKAsw7PgLgA67ntsGttY3nMib3iGGn2oVk/yGgmuGX57UOSXIjVRv+C8CX5mu445r+GkdTtyk9YklVo1mlt1YNuEEFikzmG8G2Z765jaWrD51O4eWZ3blneBsAnltyiM/k/mK3lF8mkpwI2RjsN+YOTuTVG3qhKPDFtrO8vPyITOjdVI719VzOmJeaalL3WADeS0tEjR8Ipiq5Oi/Vz44PMJjKOWxJJKb/DEL8vbSOqE5Teohj/Jni61EVHRxdBpl7NY5KcgtpO/HN2kWNqudk61voFBOkdUR1Gt0pEl8vHf+qmIaq6OH4apdfnZfJfCPYVuZj5Mp8nRRF4a9Tu/DwmPYAvPDTYRbtTdc4KqmhbCvzssS+btf3i+f/rusBwMebT/Oq3EPvluSeeclexnaOwseg43R+Bak9HxV37v4USmQPGekKqkowb3sXgHfM13HPiLYaB3R5HaICaRcZwBFzS9Ljpog75QUrqR5qNommoEvMw7h+zACNo7k8f28DozpGclaN4XDERHHnhn9pG9RVyGS+EWpX5mUyf1mKovDkhI7cPUys0P/xh/2sOyqbAbmT/HKR5IQHyBXLy7l5YCtenNENgHfWneStX09oHJHUEEazhYIKcdFKdrOXmirQR5wEAvxY2B4SBoO5WiY70pXt+hh9TQnHLXF4db+W+BauOwpWURQmWytQPuNaceeRpZB/UsOoJJdXcAqvY8sB+DVsDkPahmsc0JXZKlD+WTFdVKAc/xky9mgc1eXJZL6BKmvMFFcaAZnMX41thf66PnGYLCoPfJUk59C7kXzrynyEXJm/otuHtOavU7sA8N9fjvHtzlSNI5LqK7+sBlUFvU4hzF8e51LTTe0pTgKXH8xGHfUncefe+VBZpF1Qkusy1WDe9h4A75hmcN+o9hoHdHWTe8QA8NWZYExtx4NqEaPqJOkyzFveRkFlnbkX14wajaIoWod0ReO6RONt0LEpP4Ti9teJOzf8W9ugrkAm8w1kW5X399YT5CObgl2NTqfw7xt6MqZTJFVGC3fP28XR7BKtw5LqIc+6Z16W2V/dvSPa8ui4DgD8dfFBtp7M0zgiqT5sM+YjAr3R6Vz75EJyD2M7R+Ft0HEqt5yUgH4Q1VWM8dr7pdahSa7o6DL0FTnkqKEUtplGt5YhWkd0VV1jg0kM96faZGFn3FxxZ/LXcu68VLfyfNTkrwD4zvs6pvdqqXFAVxfoY2C0tcpqYeBNoOjg2EqX7Q8hk/kGyiquBMSqvKtfWXIVXnod797aj36JLSipMnHPvN0UlNdoHZZ0FedX5mX5cX08Nr4D1/ZqKapQ5u/hVG6Z1iFJV5FTIvfLS/YV5OvFyA7iJHDFwXMw+AHxhR0fgtmkYWSSKzJZO9h/Yx7L3aM6ahxN/VxYav9VdgLE9RfbSXa8r3FkkitSd32MwVzFAUtrug+dirfBPVJPW5XV/BPeqN1vEHdufFXDiC7PPf5GXcg52cm+Ufy89Xx6xwBah/uTUVTJo9/uxSznc7u08yvzMpmvD0URVSi9E0IprjRy7+e7Ka4wah2WdAW5ZbZkXh7jkv1M7SnKkFccyIIes8E/HIpTIWW5xpFJLuXcYQxpWzGpOraGTGNkhwitI6q3KdZS+7VHc6ke/Ii4c9cnUCUrL6ULGCsxbf8AgM/U6dzioiMX62IrtT+VW86pLr8Xdx5dDoVnNI2rLjKZb6As2cm+0UL8vXh/bj/8vPRsOp7Hf9cc0zok6QryrdUTEQGyzL6+fL30fHh7P+JC/TiVV84DXyVhNFu0Dku6DNvKvJwxL9nTuC7ReOt1nMgp41iBCfrdJb6wXa5cSuepuz4BYLWlP1OH93Oras8ecSHEt/Cj0mhmrdofwjtAdTEkzdM6NMmVHPgRr6p80tUI/HpfT5gbnU9eWGq/OD0I2o4BVNj5kbaB1cGhyfzGjRuZPn06LVu2RFEUFi9e7Mincwo5xqhpOscE88/rxTivt9edYM1hucfKVeXLlflGiQry5eM7+hPgrWfryXx50cqF2fbMy5V5yZ6Cfb0YYV1lXXEgCwbcCzoDpG512T2XkpNVl2JO/gaAH3WTmNU3XuOAGkZRFKZaO34vO3AOhllX57e/C6ZqDSOTXEn1jk8BmG8az10jXL+546VqG5oeyEIddL+4c8+XUO1a2ygdmsyXl5fTq1cv3n77bUc+jVPlyQ7fTTajdxx3Dm0NwBPfJXM6r1zbgKTfMJktFFpLxGUDvIbrEhvMf2b3AuD9DSflFAcXlWO9OBspt01JdmYbbbTiQBYEx0K3WeILcnVeAtj/HQZTOSctsbTqO5FAN2yoPK2naGT269FzVHS+HoJioTQLDi3SODLJJZw7hM+5PRhVPRmtZ9E+KkjriBrswlL7o0GDIaydqEDZ943WoV3Eocn85MmTeemll5g1a5Yjn8ap8qwnf7IpWNM8O7UL/RNbUFpt4oH5SdSYZCmyK7E1KNQp0EKO7GqUKT1iub5vPBYVHv8+mdIquX/e1ZyvtJKv55J9je8ajZde4di5Mk7klJ5vhHdwAZRmaxucpC1VpWbbhwB8ab6G262LG+6me1wwrcL8qTJa+PV4MfS/R3zBun1Aat5Mu+YBsMbSj+tG9NY0lsYK9DEwquMFDU0HWffO7/gALK6Tt7jUnvnq6mpKSkou+nA1+eUymbcH0eG+L2EB3hzNLuXDjSe1Dkm6gK0CJSzAG70c2dVoz1/blfgWfqQVVPLiT4e1Dke6hC2Zl3vmJXsL8fNihLWr/fL92RDXFxIGg8UIuz/VODpJU2e34l2QQoXqQ3ab62gbGah1RI2iKArTbGXI+7Og7+1iO0n6Tsg+oHF0kqaMlVj2fQvAL36TGNUxSuOAGm/ahaX2vW4Gn2DIPw4n12oc2Xkulcy/8sorhISE1H4kJCRoHdJv1JbZB8nVyqaKCvbluWldAXhr7Qk5ysuF2C5ahQfIJKcpgny9eP3G3igK/JCUzqqDWVqHJFmpqipX5iWHmtxddPxefiBT3DHYuudy96dglpU6zZVtHN1i8zBuHN5N42iaxraneF1KDmXe4dB5mviCXJ1v3g4vwdtYQroaQYch17r1otBFpfaFQJ/bxBd2vKdpXBdyqWT+mWeeobi4uPYjLS1N65AuIvYRy9nb9jSjd0tGdoykxmThmYUHsMhxdS7BNmNe7pdvuoFtwrh/VDsAnll4gBzreEtJW0UVRmqskwbkyrzkCBO6xeCt13HsXBkp2aUi0QmIgvJcOLZK6/AkLZTnoxz9CYBfAqe59YolQNfYYNpEBFBtsvDrkXMwwFpqv/97OaauGSvbKi7m/GAZy40DWmkcTdNcVGp/IAsG3gcocOIXyDuubXBWLpXM+/j4EBwcfNGHKymoqEFV5T5ie1IUhZdndsfPS8+O0wV8v9u1LuA0V3LGvH09Pr4jXWODKaww8tLyI1qHI3G++V2ovxc+Br3G0UieKMTPi5HWk8Bl+zNB7wW9bxFf3POlhpFJWlEP/oheNXHA0pqhw8a49YolXFxq/9O+LGg9AiI6grEc9n+ncXSSJnKPEXhuJ2ZVoajjbI84j7Qd48v2Z6G2aAMdJ4kv7PhAw6jOc6lk3tXllcp9xI6QEObPkxM6AvB/K47UjouStFM7Y16uzNuFt0HHv2/oCcDSfZkcSC/WOCJJlthf2bvvvkubNm3w9fWlX79+bNq06bLfu379ehRF+c3H0aNHnRixa5rey5boZKKqqthXDHBiDRRnaBiZpIWKXfMBWMooZvdzva2kjWErtd94LJeSahP0v1t8YfenoMpqy+ameudnAKy19OHakf01jsY+xnWJxseg43ReOYcyS85vmdr3jUuMqXNoMl9WVkZycjLJyckAnD59muTkZFJTUx35tA5jW62UJfb2d+fQ1vSIC6GkysQLslGY5uTUBvvrHhfCdX3iAHHRSpUnOZqyXTSUJfa/9d133/HYY4/x7LPPsnfvXkaMGMHkyZOv+t6dkpJCVlZW7UeHDh2cFLHrGt8lGl8vHWfyKziYUQLh7SBxGKgWSP5a6/AkZ8o5SkDefoyqHmOXWYT4e2kdkV10ig6ifVQgNWYLaw6dg143g8EPcg5D6natw5OcyVSNxfq6tjl4Kn1btdA4IPsI9DEwvks0IC7M0mYUhLWFmjI4vFjb4HBwMr9792769OlDnz59AHjiiSfo06cPzz33nCOf1mHOlx7L1Up7M+h1vDKrB3qdwvL9WSSdLdQ6pGbNtjIfHiCPdXt6ckJHvPU6tp3KZ31KrtbhNGs5tSvzcsb8pV5//XXuuece7r33Xrp06cIbb7xBQkIC77135YY/UVFRxMTE1H7o9XL7QoCPgXGdxUngsv3WRni21fm9X7rUeCPJsar3iCRnvaUX04f20jga+1EUhak9znf8xi8UelwvvrhbNsJrTixHluNnLCJbbUGn4dehKJ5TxWyrslq2PwuLCvSZK77gAlumHJrMjx49GlVVf/Mxb948Rz6tw9iagsnVSsfoHhfCDX3jAXhn3QmNo2ne8uWeeYeIb+HPncNaA/DKyiOYZcNHzeSUyDL7utTU1JCUlMSECRMuun/ChAls3br1ij/bp08fYmNjGTduHOvWrbvi97rDKFp7uegk0KJCl2vBJwSKzsKZjRpHJzmFxYxp7zcAbAuaQN9WodrGY2e2PcWbjudSXGE8P3P+8BIoz9MwMsmZirZ9DsASxjCjb6LG0djX6E5RBPoYyCiqZG9aoeh/oughbTvkpmgam9wz3wCyzN7xHhjdDp0Ca4/mcDBD7ivWSp7sZu8wD41uT4ifF8fOlbEgKV3rcJotWWZft7y8PMxmM9HR0RfdHx0dTXZ2dp0/Exsby4cffsiCBQtYuHAhnTp1Yty4cWzcePlE1R1G0drLb04Cvf2hxw3ii3u+0DY4ySnU0xsJqM6hSA0gccgsj1qxBOgQHUSn6CCMZpVVh7Igri+07APmGkj+SuvwJGcoyyUkU7zmV3WdTYCPQeOA7MvXS8+EruJ9cWlyJgTFQAfrRe+92q7Oe9bftIPlenqZfUUBpO+C9N2QsRsy9kBV0cXf49cCYnuJF+nY3hA/AELi7BZC64gAru3VksXJmbyz7gTv3dbPbo8t1Y+qqrVz5iM98cKVxQJZe8VxXp4rPspyoboEAiIhNAFCrB/xAyAg3K5PH+LvxcNj2vPyiiO8tiaF6b1a4ucty5GdrbbMPliW2dfl0mRDVdXLJiCdOnWiU6dOtZ8PGTKEtLQ0Xn31VUaOHFnnzzzzzDM88cQTtZ+XlJR4bELv66Xnmq7RLNqbwU/7suiXGCZK7Xd/Akd+Eu+9/mFahyk5UOHWzwkDVqhDmdGvjdbhOMS1vVvyn59TWLovkzkDWkHfOyBzLyR/A0MfAQ+7gCFdrHzPDwRgYZ+lLdeMGK51OA4xvXdLFu7NYPmBLP42rSuGvnPh2ErY9y2MfQ4M2uSHMplvAI8ts09Pgm1vi3Io1Xzl760shFPrxYdN4jDofSt0nQE+gU0O58Ex7VmcnMmqQ9kcP1dKh+igJj+mVH/lNWaqjGIfp8dcuDJVw6kNkLJCzHcuzarfzyk6SBgMnSZDpykQ0d4u4dw+NJHPt50hvbCST7ec5qEx9nlcqf5kN/u6RUREoNfrf7MKn5OT85vV+isZPHgw8+fPv+zXfXx88PFpPn/303vFsuiCk0B9y94Q0wOyD4iZ3LbuyJLnqS4l8NRKAHLbXkeoh442vraXSOa3nswnp6SKqG7Xwco/Qe4RyEoWi0CSxyrf/TUBwM6g8dzX0rVGi9vL8PYRhPp7kVdWw47TBQzrMAECoqA8R5xbdr1Wk7hkmX0D2MrsPWK10mIRyfsnE+HjsXBooUjkwzuITqRTX4PfbYCnTlzwcRx+tx6mvQH97hQr9ChwdgsseRBe6wRLHoK8pu137xgdxKRuMagqvLv+pB1+WakhbPvl/bz0+Hu7+fU+s1GMx3mzF3w9G5I+E4m8dyB0nAwD7oPRf4Gpr8Osj2HCyzDoAeg8DSI7i47TqVthzd/g7X7w4Wjx/8ZylYteV+Fj0PPENWIc4xfbzmAyyyZYzpZTIsrsZTJ/MW9vb/r168eaNWsuun/NmjUMHTq03o+zd+9eYmNj7R2e2xrePpIQPy9yS6vZcTpf3Nn3DvHnni/kCC8PVrlvEd5qFacsMQwdNUnrcBwmIcyfPq1CUVXRHwK/UOg8VXwx+RtNY5McS80/SVTJAcyqQouBN2kdjsN46XVM7n5+3Ch6L7F3HjQttXfzM3Xn8phu9gWnYcnDcHaz+FznBT1mw+AHILbnlX82MOriq6vF6WLO4t6voPA07J0vXrT73g6j/yz2lDTCw2Pbs+pQNkuSM3hsfAcSwwMa9ThSw3nEfnmLRVygWvcyFJwS9wXGQJdpYpW99Qgw1COJK0qFlFViRf/MZlEy+P3tEN4ehj0KPefU73HqMK1nS15efoRzJdWsS8nlmq71X/WUmqa82kR5jbggI8vsf+uJJ55g7ty59O/fnyFDhvDhhx+SmprK/feL1eNnnnmGjIwMvvhC7Pd+4403aN26Nd26daOmpob58+ezYMECFixYoOWv4VK8DTomd4/h211p/LQvi6HtIsS++Z+fhZxDkL3feoFc8jTF27/AD1jvN567Wnv2dooZvVqyN7WIJfsyuXt4G5HoHFoIB36ACS9pVoYsOVbW5i9pCWylJxMGXSWPcHPTe8Xyzc5UVh7M5sUZ3fHuMxe2vAEnfoGSTAhu6fSY5Mp8Pamq6v5l9hYL7PwI3hsmEnmvABjxFDx+EK577+qJfF1C4mHkH+GRvXDXSug4SazwJ30Gb/aGX16AqoZ3Ke4eF8KYTpFYVHh/g1yddya372SffxI+GQ8L7hGJvH8ETP43PLZfVJy0H1//BDy0FQz6Hdy+GJ48CiOfBt9QyD8BS/8A/+sPR1c0Kkxvg47r+4npDd/uvPL8bsm+bPvl/b31BHpYkx57mDNnDm+88QYvvvgivXv3ZuPGjaxYsYLERNGdOCsr66KZ8zU1NTz11FP07NmTESNGsHnzZpYvX86sWbO0+hVc0rSe4iRv5cEsakwW0YOmk3Wldv/3GkYmOUxxOjEFuwDw73ezxzW+u9TUni3RKbAvrYiz+eXQdoy4kF5ZAMdXax2e5AiqitehHwBIjZtKsK+XxgE51qA24UQF+VBcaWTT8Vyx/bLVUFHJqVGzR5nM11NxpRGTdYyUW65YFqXBF9fCiqfAWC5WJh/YAuP+1ujV84soCiQOhVu+E0l9/EAwVcLm1+G9oRfvsa+nh8eKfcQ/JqWTVVzZ9BilerHNmI90x+P84EL4YBRkJIF3EIx5Fh5NhkG/b/QKeq2ACBj7rLj4NeFlCIqF4lT49mb45hbxf6yB5gwQDb/WpeTIY9yJZIn91T344IOcOXOG6upqkpKSLmpkN2/ePNavX1/7+dNPP82JEyeorKykoKCATZs2MWXKFA2idm1D2oUTGeRDUYWRjcdyxZ09bhR/HlzQ5O07kuvJ2irKy3daujBx2ECNo3G8yCAfhrWPAKwdv/UG6Gk9xvfJUntPVHlmF5E16VSoPnQcdbPW4TicXqcwtecFpfYAfS+YOW9x/rZJmczXk63EPsjXgI/BzTpPZybDx+PgzCbw8ofJ/4Hbl0KYgzqqJg6Fe1bDTV9Di9ZQnAZfzIDlT0J1Wb0fpl9iGANbh2E0qyxJznRMrNJv1K7MB7hRomOsgmVPwI93QU2paFr30A4Y9TT42LmBok8QDH0Y/pAEwx4DnQFSlsM7A2HzGw06IW8XGcjANmFYVPhhtxxT5yy1neyDZIm95Dx6ncJ06+r84uQMcWeHa8A3RPTyOLNZw+gkR7AcEFtNTsdMoEWAG14gb4Rre4ljfMm+TFRVPb+n+NjPUJ6vYWSSI6RtmAfANq9B9O/omRNJLjXdeoyvPnyOihqTaADuHQRFZ8W0JCeTyXw92fYRu13zu+O/wGdToOwcRHUTq/GDfgc6B//TK4pofHL/Fhhwr7hv18fw/jBI3V7vh5nRR/yHWXGgnt3HpSZzuz3zJVnwyTVizBPA8CfgzuV2HZlYJ+8AuOYFuH+zmOhgrIBf/i4uXJXU/3i9eaB48/tuVxoWi2yC5Qy2ZD4y2M1ezyW3N9P6nvbLkXOUVZtExVDXGeKLB2SpvSepyT1FXMURzKpC/FDPbQp2qYndY/A26DiRU8aRrFKI6iJGGVuMcPBHrcOT7MlsIip1OQBVXa73+G0kNn0SQmkV5k9FjZk1h8+J88GZ78BDuyDO+SO1ZTJfT7aVebfaL7/nC/j6RlFW32YU3L0Swto6NwafQLFPee5iMbe78AzMmyr27teje+/EbjHoFNifXkxqfoXDw5UubPToBsd64Rn4bJJoHuUfDrcugPF/F6V9zhLVRVw8uPZt0YfizCZ4f7hohlIPk7vHEuxrIKOokk0n8hwcrASQUyrL7CVt9IgLoW1EAFVGCz8ftI7/s5XaH14qqowkj3B6gxjNuEfXncE9u2gcjfME+3oxtlMUAEv2WStQbKvzyV9rFJXkCJl7VxJqKSJfDWLAuOu1DsdpFEVhZm9rldVe6zHedQZEdtQkHpnM11OedSUnIshNVis3/kc06FLNYtTcrT+KUj6ttBsDD2yFbrPAYhJ79xc/CMYr7xOOCPRhcNtwAFYclKvzznC+0aOLH+u5x+DTySKhb9Ea7lsLHcZrE4uiiD1Tv98A0T2gIg/mXw9r/g5m0xV/1NdLz6y+shGeM+WWiNfzaNnJXnIyRVGY0VtUDdWW2icOg+A4qC6B4z9rGJ1kT77HlgCQ13oqel3zWLG0mWFNdJbtyxIVZ91vEJOTspLh3GFtg5PsJm+buGC1L3gsUaF23tLo4mb0Ea/jG4/n1W5P1YpM5uvJ1hTMLfYRb/0frH1J3B75R5j5nmuMA/ENhhs+FeNJFB3s+xo+nXTVxmG2RhOy1N458svdoAolax98NhlKM8U8+LtWiYReaxEd4N5fzm8t2fKGqI65ykSHm6yl9msOnyO3VNs3hebgnFyZlzRkS3S2nMgTVSI6HXS3rmrJrvYeoSD1CIk1JzCpOjqNvkXrcJxuTOcognxExVlSaiEEhEPHieKLshGeRzBVV9A2fyMAgf3naByN87WLDKRnfAhmi8qy/drmJzKZrye3KbNP+hxW/1XcHvs3GPtXsWroKhQFhv4B5i4CvzBxlfajsSI5uwxZau9c+a6+Zz5zL8ybLla/Y3vDnSsgOFbrqM7z8hVbS2bPEw0nT/4Kn04UM+svo3NMML0TQjFZVBbskY3wHC2nRDbAk7TTOiKA3gmhWFT4aZ/1JNDW8fv4aqgs1C44yS5Orf8CgP3efWhrHenYnPh66ZnYXUxKqi1D7mXtG3BwoSYdvyX7Orx5CYFUcI4w+gybqHU4mphprbJaZDvGNSKT+XrKLbWWHrtymf3BBfDTo+L2sEdhxJPaxnMlbUfD79aLkuTyHPhs6mXH18lSe+cxW1QKKly4CiX/JMy/AaqLodUQuGOpuOLvirpdB3etEDN2cw7DR+MgPemy325rhPdjkkzmHa22m71sgCdpxLbfcomt1D66O0R2AXON2DsvuS1VVQk/Y20K1mmGxtFox5boLNufRbXJDO2vER2/S9IhfafG0UlNVbXPOqkhcjxeBif2KXIh03u1RK9TSE4r4kxeuWZxyGS+nvJcfVzXsZ9h4e8AFfrfDeNfcK0V+bq0SIS7louZ9zWlIkk7uKDOb5Wl9s5RUF6DqopDp4W/l9bhXKz0HMyfZV2R7wW3/qBtH4j6aNkH7vtVnKiX54jmj0dX1Pmtk3vEolPgRE4Z2cWyCZajVBnNFFcaAVlmL2lnmvUkcH96Madyy8SLbs/Z4osHftA2OKlJThzaTRvLWWpUPd3GNb8Se5sh7cKJCfaluNLIuqM5omqtyzTxxcuc60nuoaSsjC7FYpRm5KDmV2JvExnkw7D2EcAFPVA0IJP5erLtI450xZX5zL3w/R2isVyP2TDlNddP5G18Q+C2BdB1phhb8uM9sP3933ybLLV3Dttx3sLfG4PehV4eqkrgqxvON7u79Uf7z493lJB4uHsVdJgApkr47jY48NvxPMG+XnSPExcntp2SXe0dxdaTwNugI8TPxS5YSc1GRKAPw2tPAjPFnT2syfyZzVCsbdmm1HgZm0XH9pTAgYS0iNQ4Gu3odUrteOGFe6zHs603xKFFV20OK7mufesXEqRUkquE07bvGK3D0dR1fc53tVfrMaXLEVzobN215dnK7F1tz3xpNnxzi0gS2o8Xze4cPUPe3gw+ojHegPsAFVb9CTa/cdG3yFJ753DJTvamapEAZ+8H/wi4bSEERmkdVcP4BMFN30DPOWLCxIJ7Yc+Xv/m2IdZjfNvJfGdH2GzUzpgP9Gk2M3El12SbOb8k2XoSGNoKEgYDKhxeom1wUqNUG00kZq8CwNCz+YzqupxZfcSklnUpORSW14gtln5hUJ4LZzdrG5zUaOqhRQBktZyAotNrHI22JnSNwc9Lz5n8CvalF2sSg5tlfdoorzZRaTQDLjZ721gJ394iOnpHdBIJsd5NV5p0epjyHxj1Z/H5L3//TUIvS+0dz+W2k6gqLHscTm8QM9xv/QHC22kdVePoDTDzfeh3F6DC0od/U4UyuJ01mT8lk3lHybV1spf75SWN2U4Cz+ZXsCe1SNzZbab48/BijaKSmmLXjs20IZNqvOg48katw9Fcp5ggusYGYzSrLDuQJc5Ru1r7CNRRoSa5vrScQnpXbAOg5bCbNY5GewE+BiZ0iwYuaPboZDKZrwfbaqWvl44Abxe5AqWqYo58RhL4tYCbv3H9/cNXoygw5hkY/Yz4/JKEXpbaO57LdbLf8T4kfyVGGd74BcT11TqiptHpYNp/YcjD4vNLqlAGtA5Dr1NIK6gkvVAe445Q2/xO7peXNBbgY2CyteP3QtsUC1uik7ZDltq7oeIkkaCeaTEUvZ+bn5PZyay+1o7ftmPcVmp/ZCmYajSKSmqs5PULCVYqKdBHENF5hNbhuISZ1pnzP+3LxGh2/qQGmczXQ+4FY+lcpixz02uiSY7OIJIcd12trMvoP9eZ0F9Yar/myDmNgvNsLjWC8dR6+PlZcXvCS9BhvKbh2I2iiN/nwiqUHR8AEOhjoGe8dd+8LLV3CDmWTnIls/qKMuSf9mVSZTRDcEtrqT0i2ZHcRnGFkQ4F6wAI7D1L42hcx7W9WqJTYE+qteN34lAx5aWqGE6u1To8qQFUVcX7mHhdKmg1yf229TrIiPYRhAd4U1ptIiW71OnPL/8V6qG29NgVEhyA42tg7T/E7cn/hjYjtY3HES5N6K3Jjq1r5L60Io0C82y1K/MBGq/MF5yGH+4U+8t73gSDH9Q2HnuzVaGM+pP4fOXTsEfMJa7dNy9L7R0ix1ZmL1fmJRcwpF04sSG+lFSZ+PVIjrjTVmp/aLFWYUmNsHn7Vjoq6ZjQ03Jg8x1Jd6moYF+GdxCNABftzRDbKrtdJ74ou9q7lb2nzzHEuAOAOFliX8ug1/HxHf3Z/dfxtY2MnUkm8/VgS3AiXaH0uCgVFt4nbve/Gwbco208jjT6zxcnO/t/oIf1P8mBDG2aTHg6Wzf7CC0Tneoy+PZWqCwUo92mv+E+0xkaavQz50vulz4C+39giHXf/PaT+Zp1RvVkcsa85Er0OoXrrCWataX2Xa4Vf6Zth5JMjSKTGqpk70IAMlsMRPFroXE0rmWW9RhfbGv2aCu1T1kBNXJLmbs4tHERwUolxYYI/NoO1Tocl9KnVQuCfbXpWyaT+XpwmdJjU7UYQVdZCC37wqR/ahuPM4x+Bgb+XtxefD99qncBcDqvvHZWtGQ/eVqvzKsqLHkIcg5BQBTM+Qq8/LSJxRlsJff97wZUWPR7BlZtw0uvkFlcRWqBPMmxN1lmL7kaW6n9+mO5YnRiSBwkDBJfPCxL7d1BVnElXYs3AhDUV5bYX2pCt2j8vW3NHgshvj+EtIKaMji+WuvwpHqoMVkIPbMCgPJ2U2SJvQuR/xL14DLJ/M/PQuYe8A2FGz8XI908naKIixY9ZoPFRNCSu5kcchaAg3J13u5sK/OabSnZ8YHo4qwzwJwvxUmtp1MUmPIa9LoZVDM+i+/lpmixQif3zdtf7Wg6WWYvuYj2UYH0SgjFbFFZus+6Et91pvhTdrV3C2u3J9FLdwoLOlr0uU7rcFyOv7eBSdZmjwv2ZIj3ve7Wix4HZVd7d7DpSAaj1N0ARA++SeNopAvJZL4eXKLD9/4fYNdH4vasj8Q82uZCp4MZ70L7a8BUyWvGl+mgpLNfo3mOnkzTOfPpu2H1X8XtCS9Bq8HOj0ErOh1c+zZ0ngbmap4tfpH2SrrcN29nJrOl9oKVLLOXXMkN1o7fC5Iu6Wqfuh1K5DhWV1e6V8zdzg3rC4GRGkfjmm64tNmjLZk/vkZsr5NcWsqOFQQrFZQZwtAnDtE6HOkCMpmvh1ytV+Zzj8FPj4rbI/8IHSdoE4eWDN6ia3/CIPwtZXzm/W/Onj2ldVQepaLGREWNGdBgZb6iQDS8sxjFftFB9zv3+V2B3gDXfwzxA/E1lzLP+98cP3Fc7pu3o/zyGlQVdAqEB8hkXnId03q2xEuvcDirhCNZJaIqKX4goMqu9i4uJbuUPhWbAQiSq/KXNbhtOHGhfpRWmfj5UDbE9IQWrcFUBSfWaB2edAUVNSbCU38GoKr9ZFli72Lkv0Y9aFpmb6wUSY6xHNqMOt/hvTny9oebv6UyqDXxSh63n/mzbJxiR5lFost3gLeeAG+9857YYoFFv4fiNAhrCzPe9tyGd1fj5Qe3fIclrD3xSh6v1fyD05nZWkflMWz75SMCfdDrmukxJrmkFgHejOscDVzQCE92tXcLa3buZ4CSAoB/z5naBuPCdDqF6/uJ1fkfk9LF+7yt2aPsDeHS1hzKZKwielaF979e42ikS8lkvh40LT3++S/WZmCRorxe58QkyxX5h2G++TsK1UC6qieo+eFekQxKTZZmbbbWKjwAxZnJ9Jb/igY4Bl9RfeHr/LEeLsU/DN3cBRTpWtBFl4rfwjvALJs92kPtWDpZYi+5oFnWUvtFezMxmS0XlNpvg1J5Uc8VWSwqFfuXolNUClv0hJB4rUNyabZS+80n8sgoqjzfG+L4arF4Jbmkwzt+IVIpoUofhNJ6hNbhSJeQyfxV1JgstV3Tnb4yf2gR7P4UUGDWhxAU7dznd1GBLTvzvP9fqFYNeB9fLubQS01m65zeKsyJ3ePPboW1L4nbU16FmB7Oe25X1qI1K3v9jzLVl9j8HbDij6LTv9QktuZ30bKTveSCRneKIizAm7yyajYezxWJYfwARKn9T1qHJ9Vh99lCBldvASCwtyyxv5pW4f4MahOGqsLCpHSI6wvB8aKr/cm1Wocn1aGoooboDLENoqbdBLHtVXIpMpm/CluzJINOIcTPifMDC8/AUus++eGPQ7uxzntud5A4lKeNvxO3t74FSfM0DccTnE/m/Z3zhOX58OM9oFqg503Qd65zntdNtO81jEeMD2NBgaTPYOeHWofk9mrH0jlrZd5igT1fgtnknOeT3Jq3QcfM3mJ1/vtdl8ycl8m8S/p59xGG6A4D4NV9hsbRuIfZ/RMA+HFPOipAV1lq78pWHshigm4nAMGyJ4RLksn8VeSVihL7sABvdM7aY2k2iiSnulg0wBnzF+c8rxvpERfCEstwlrS4Q9yx/CnR9VdqNKcm86oKix+A0kwIbw9TX3P8c7qZXvGhbKQf/zRaR8Cs+jOc+FXboNzcOWuZfaSzVuY3vw5LH4Zv5sjKCqle5gwQic4vR86Jfj1dpokvnNksGoVKLsNktmA8vAIvxUxZaCcIb6d1SG5hSo8YAqwz53edKTy/nSRlJZhqtA1O+o19uzYQr+Rh1PlCu3FahyPVQSbzV5FXrkHzu7X/gIzdYu/wDZ+A3okVAW6iV0IoAK+UXSv2XFmM8N1cKM7QNC53Ztszn+CMZH7bO3D8Z9D7wOx54BPo+Od0M94GHa3C/PnQPI2ctrNEBcMPd4npFlKj1K7MO2PG/NltsO5lcbvbdc23qaPUIJ1igugVH4LJorJ4b4ZoChrdHVQzHFuldXjSBbafKmCYSSwi+PWQq/L15e9tYGrPWAB+2J0mFq0CY8QC1ukNGkcnXSi7uIq4bLGIYGwzVjSillyOTOavIs+6xzLCGSd/IFbetrwpbl/7dvOaJ98AXWOD0SmQXVpNzrjXxclOeQ58d6tsotIIqqo6b2U+PQl+eV7cnvR/cp/8FbSJCAAUfmn/F0gYLE52vpkjV+gaKdfWAM/Rr+cVBbDAtoVkDvS+1bHPJ3mUG62r89/tShOjKTtbV+ePLNMwKulSPyefYqRuPwD6rtM1jsa92Ertlx/IotxogS7Wv7/Di7ULSvqNZfszmagTXez9e8kSe1clk/mryLN1sg9wQsOHshxYZJ2v3f+e8/uIpN8I8DHQPkqs5h7IMcFNX4FfGGTuhZ8ekyWtDZRfXkNFjRlFgbgWDmyAV1kEP94lKim6zhDHuXRZIpmHkwVGcYyHtIKCU7DwPrCYNY7O/dga4EUFO7DM3raFpCTj/BYSuSovNcD0Xi3x9dJxPKeMvWlF5xOdk79CTbmmsUmC0Wyh7PBq/JQaqgLi5UXpBuqf2ILW4f5U1JhZcSDr/Pnu0eVyeosLSUraSUddBmbFAB0maB2OdBkymb+K/DInrcxbLCKRL8+BqK4w8WXHPp8H6BEXCsD+9GJo0VqUayt62P8tbH9Xy9Dcjm1VPjbYFx+Dg8Yfqir89AgUnYXQRJj+lkxyrqK1NZk/k1cOAREioTf4wolfYP0rGkfnXiwWldxSJ5TZb39XlEPrfeCGz8AnyHHPJXmkYF8vpnS/oAw5upt4jzNVif/7kuY2n8hjmGkHAN7dp8v3sgZSFIUbrDPnf9idDq2Ggn8EVBaK/hCS5s7ml9M6dx0A5sSR4BeqbUDSZclk/irybMm8o2fMb3tbXHU3+MENn4KXE8eDuame8WIe+f70InFH21HnL4Ks/psYeybVi1P2y+/+FA4vAZ1BJDnyjeGq2lqT+dN51tW42J7iIgjAxv+IVQypXgorajBZRMWOw3qgZCTBGuuozIkvi38vSWoEWxnyT/uyqDCaLyi1l13tXcGK5DTG6fYAoLM1KZQa5Pp+8egU2HmmgJMFVeebPR6RXe1dwfIDWUzUiy723t1lpbArk8n8VaQXiv3XMSEOTK4zkuDXF8TtSa9AVBfHPZcH6WFN5g9kFIt9hQCD7oceN4pmQT/cCaXntAvQjaTmO3i/fPZBWPWMuD3+BYjv55jn8TBtIkUyn1pQgclsEXf2miOOc4CFv4e84xpF515sJfZhAd54Gxzw1ldZJF5zLEYxTmzAvfZ/DqnZGNw2jMRwf8qqTaw4kH1+RN2x1bLjt8aqTWbyj6ynhVKG0SdM9DORGiw2xI/RnaIA0R/iojGMchuZ5nYm76e37hQqCnSeqnU40hXIZP4qbCtithUyu6sqhh/vBotJvJD1u9Mxz+OBusYGY9Ap5JXVkFUsGluhKDD9DYjsAmXnxN+tnPF8VQ5tflddJpIcczV0mAhDHrL/c3io6CBffL10mCxq7YVFACa8JMoSa0rh21uhulS7IN1EjiNL7FUVljwERaliC8m1/5Nlt1KTKIrCbGsZ8ve70iB+AARGiyaYZzZqHF3ztvFYHiOsJfaGLpNBb9A4Ivd1k7XZ44KkdGoShoNvKJTnQtpObQNr5lLzK2iVux4AU9xACIzSNiDpimQyfwXFFUbyy8UV8NaOSOZVVTRrKzwjGltdK/cQN4Svl56O0WI/6v704vNf8A6AOV+CdyCc3QxrX9QoQvdRm8yHOyCZX/FHyD8OQS1h5nvyGG8AnU6hdfglpfYgxlXOngdBsZCXAksfkU0fryKnxDZj3gHJ/M4P4egy0HnBbLmFRLKPC8uQT+VXQKcp4guy1F5Ty/ZlcI0+CQClsyyxb4qxnaOICvIhv7yGNSkF0HGS+MJROblBS8sPZDFRtxsAr26yxN7VOTyZf/fdd2nTpg2+vr7069ePTZs2Ofop7eZ0vjh5jgryIdDHAVde93wOhxZa9xB/Cn4t7P8cHu43++ZtIjrAjHfE7S1vypOfq3DYnvnkr2Hf16Do4IZPICDcvo/fDLS1ltqfyruki3VQNMz+XLx+HFoIuz7WIDr3cX5l3s6d7DP2wOq/itsT/gFxcguJZB+xIX6M7BgJwHe7087vKT66QpYha6TKaCbjyHbilTzMBj9oN0brkNyaQa9jdn9RgfLtrtTz5dxHfpIXqDW0cd9RBumOiE9kib3Lc2gy/9133/HYY4/x7LPPsnfvXkaMGMHkyZNJTU115NPazem8MuD8eCi7OncYVv5J3B77N0gYYP/naAY6x4iV+VO5dYzr6TYThjwsbi9+UIz0kn6j2mQmy7pqadcy+3OHYdkT4vbov0DiUPs9djNiW5k/c2kyD9BqkOhBAKInQUaSEyNzL7Wd7IPtuDJfVSxGLZprRIMyWy8DSbKTmwe2AuDH3dYyZJ8QMfUmfZfGkTVP61NyGGERJeC6DuNls2I7mNNfHOObjueRHj5UTGwpOgvnDmocWfOUml9By3MbMSgWTJFdIayN1iFJV+HQZP7111/nnnvu4d5776VLly688cYbJCQk8N5779X5/dXV1ZSUlFz0oaXT1gTRtjJmNzUV4gTQVAXtxsHQR+z7+M1IXAuRfGYWV9b9DeOfh4RBUF0CP9wFpmrnBecmMgorUVXw99YTHmCnqQ3VZfDDHWCqhHZjYcST9nncZqjNpR3tLzXkIZFIWozw/Z1itI/0G5lF1mam9poxr6qw9A/nt0nNeFtuIZHs7sIy5J+PFkDHieILstpME8v2ny8/liX29tEq3J/h7SMA+DY5X5wXAxyRpfZaWH4giwl6cYwbuk7XOBqpPhyWzNfU1JCUlMSECRMuun/ChAls3Vr3yLBXXnmFkJCQ2o+EhARHhVcvp60dvu2+Mr/yacg9CoExcN0HoJOtCxqrZag4Mc8ovEwyr/c6v4UhKxnWPOe84NzEhc3vFHskI6oKy5+AvGNiT/esj+Qx3gRXTeYVRWwpadEailNh0QNgsTgvQDdxPEdUWrWPCrTPA25/zzpq0bZPXm6TkuzPS69jjrVJ2Dc7Uy8otV8uy5CdrMpo5sTR/XTWpaEq+vMXVqQmu2mgOMZ/SErD3Mla1i33zWvi1/2nGanbLz6RF6zcgsPOsPPy8jCbzURHR190f3R0NNnZ2XX+zDPPPENxcXHtR1pamqPCq5fzZfZ2OvkDsYd475eAArM+hMBI+z12MxQfKlbm88trqDJeZg9hSDzMfF/c3vG+XNG4hN072e/5AvZ/B4peXEgJiLDP4zZTtmQ+s7jy8se4Xyjc+AXofeDYStj2P+cF6AaqjGbOWHugdIi2w+t56g5Y8zdxe+LLEN+/6Y8pSZcxZ0ACigJbT+ZzJnSI+H9eeBpyjmgdWrOy8Vguw83WLuuth8sLeHZ0TddowgK8OVdSzUalvzh/OHdQbo90stT8CsKzN+On1GAObgUxPbQOSaoHhy+XXbrSp6rqZVf/fHx8CA4OvuhDK6qq1pbZ221l/sI9xGP+Am1H2edxm7FgPwMB3nrgfBltnTpNgqF/ELcXPyRKYyXAzjPmsw+I7vUA4/4m98nbQViAN8G+BlQVzlr/reoU2wsm/0vc/uUFOdrnAidyylBVaOHvRWRgE/fMl+dZ58mboNt1MPB3dolRki4nvoU/o62N8L5Ozoe2o8UXUpZrF1QztOpgNhP1oleBLLG3Lx+Dnuv7xgEwf18JtB4mviBL7Z3qwhJ7fddpcuuYm3BYMh8REYFer//NKnxOTs5vVutdUW5pNeU1ZnSKnZKc6lL4/vYL9hA/1fTHlFAUhZahogFNZlHVlb953N/FrN7qYuv++RonROj67DaWrrIQvrvNOk9+Agx91A7RSYqiXFBqX3blb+53J3S/AVQz/Hg3VBQ4PkA3cOxcKQAdooOatpXEYoYF90BpJoR38Oh58g2dRLNhwwb69euHr68vbdu25f3333dSpM3DLYMSAfgxKR1jx8nizqMymXeWGpOFPUdS6KccF3d0nqJtQB5ozgDRCG9dSg5FidYtDLLU3ql+3p/GON0e8Ym8YOU2HJbMe3t7069fP9asWXPR/WvWrGHoUNdfrbONgUoI88fb0MS/JlWFnx49P2tb7iG2q/PJ/BVW5uH8/nnfUMjcA7++4Pjg3ECqPcbSWSyw8Pei4iG0lewFYWfnk/krrMyDSCyn/RfC2kJxGix5SO6rBY6dExdBOkUHNe2B1v8TTq0HL3+Y8yX4NPHxXFRDJ9GcPn2aKVOmMGLECPbu3ctf/vIXHnnkERYsWODkyD3XmE6RxAT7UlBew1pLP0CBzL1QnKF1aM3C1pN5DDbuRKeoqC37iO17kl21jwpkcNswLCp8V9pT3Jm2E0rPaRtYM5FWUIF/9g5ClXIsfuHQarDWIUn15NCz7SeeeIKPP/6YTz/9lCNHjvD444+TmprK/fe7/vgeW7Mpu5TY7/oYDi4Q86Bnz5N7iO3MlsxnXC2ZB5Fo2ubPb3sbjq12YGSuT1XV2hnzTapA2fgfOP6zGCkzZz74h9kpQgnO9+246so8gG8w3PAZ6L0hZYVo1NbM2VbmOzZlv/zRFbDx3+L29DchqosdInNNDZ1E8/7779OqVSveeOMNunTpwr333svdd9/Nq6++etnncLXpNa7OoNdxo7UR3mf7yiFhoPhCygoNo2o+Vh3MZkJtF3s5d9tR5g5uDcDH+2uwtOwLqHI7iZOsOpjNRJ3YRqLrPBl0eo0jkurLocn8nDlzeOONN3jxxRfp3bs3GzduZMWKFSQmJjryae3Cbsl82i4x/xnEmLRWg5r2eNJvxNk62tcnmQfRDdi2z3Xx/VCS5aDIXF9BeQ3lNWYUBeJCGzkv9/gaWP+KuD31dbF3W7Kr1hHiQstlO9pfqmVvmPCyuL3muWY/f/58Mt/IlfTcY7DQ+pox4D7oeaOdInM9jZlEs23btt98/8SJE9m9ezdGo7HOn3G16TXu4KYBCegU2H6qgPz4a8SdstTe4UxmC5sPnWGYzjr3vLMc1+UoE7pFExnkQ25pNSktrH2l5L55p1h1MIsJeuu5gjzG3YrD62AffPBBzpw5Q3V1NUlJSYwcOdLRT2kXp2wz5puSzJeeg+/nivnPXabDkIftFJ10obgW9Syzv9A1/xBdOivyYeF9Yi9sM2QrsY8J9sXXqxFXYQvPwIJ7ARX63w19brVrfJLQtnZl/ipl9hcaeJ943bEYRY+IqmIHRefayqtNpFtHVzYqma8qgW9vgZpSaDUUJr1i5whdS2Mm0WRnZ9f5/SaTiby8vDp/xtWm17iDlqF+jOkUBcB3pdYu02c2QWWRdkE1AztPF9Crahc+igk1rB1EdtI6JI/lpddxs7UC5aOcruLO0xvlMe5gOSVVmNKTiFUKsHj5n2+yKbkFuan1Mpo8ls5UAz/cAaVZENEJZr7nsY2StNYypBHJvJevKEX2ChAnQ5tec1B0rq1J++Wry+CbW6CqCOL6waR/2jc4qZZtZT6vrJqSqrpXOn9DUeDat8XWkqKzsPSRZrl/3jZfPjLIhxYB3g37YYsFFv1e9DsJjoMbPxe9N5qBhkyiudz313W/jStNr3Entw0WlY3vH1SwhHcUUxVO/KJxVJ5t5cHs2g7fShfZ4dvRbhrYCp0CC9MCqAltLy5Iy2PcoVYfPne+xL7DNeIcWXIbMpmvg8lsqU1y2kQ2cmV+9bOQug18guGmrz22UZIrqG2AV1yFxdKAZCWiA0y1JvHrX4EzWxwQnWtr9H55W5KTcwgCouDGL8HQxJFf0mUF+XoRYR2pdqa+pfYg5s/f8Jno13F4MSR95pD4XNmx7Cbsl9/4b7EnWe8jGt4FRtk5OtfTmEk0MTExdX6/wWAgPDzcYbE2R6M6RtIqzJ+SKhNHQ62VjrLjt8NYLCq/HkxjjG6vuEN2+Ha4lqF+jOsiXmt2+FgbZh/5ScOIPN/PB7Nqk3m6XKttMFKDyWS+DhlFlRjNKj4GHbHBjbg6tfcr2PmhuD3rI4hob98ApYvEhPiiKGJ0TH55A8fN9b4Zet0MqkWUi5fnOyZIF5Xa2GR+/SviBFLvDTd9BSFxDohOulDb2o72DUjmAeL7i7GMACv/DNkH7RyZa0tp7H75w0vO94KY9l9RfdIMNGYSzZAhQ37z/atXr6Z///54eTWPSgZn0ekU5lpX5z/KsTZhPL4GTNUaRuW59qQW0r5iL8FKJWpgNMT11zqkZsF2jL+b3VncceIXMF5l/LDUKMUVRnJP7aedLgtV5y1GC0tuRSbzdTh1QfM7na6B5VTpu2HZ4+L26Geg0yQ7RyddykuvIzpIXHRpUKm9zZRXxczo0kxY/ECzKkVuVDJ/cOHFXb1tXZUlh2rT2GQeRL+ODhPAXA0/3Cm2SDQTjWp+l7FHjFoEGHR/s+sFcbVJNM888wy333577ffff//9nD17lieeeIIjR47w6aef8sknn/DUU09p9St4tNn94/Ex6FicG02NXxTUlMHpTVqH5ZFWXtjFvtMUOXLVSYa3jyAx3J/t1a2o8LUd4xu0Dssj/Xr0HOMUsSqvtBstJuJIbkW+KtXhdG4jO9kXpcE3N4sT5k5TYOTTDohOqkvLhna0v5BPIMz+TJTSHv8Ztr1j5+hcV1qB+Puq9575rH2w+EFxe8jD0PsWB0UmXap1U5J5nQ5mvg9BsWL/94qnms1FqwYn88Xp8M1NYKqE9tecnwrQjFxtEk1WVtZFM+fbtGnDihUrWL9+Pb179+Yf//gHb731Ftdff71Wv4JHC/X3ZmbvOFR07PC2zoI+KsuQ7U1VVVYfzOSa2g7fssTeWXQ6hdsGJaKiY606QNwpt5M4xM+Hspmk3yk+kce4W5LJfB0aNZauulScAJbnQHQPUV4vr+A6TVwLkYw2amUeRGf7Sf8nbv/yPKR7/iivGpOFzGLx91WvlfniDPjaluSMh2tedHCE0oWatDIPEBAO138Cig72fQN759sxOtdUXGHkXIkoP+5Qnz3z1WXidbzsHER1hRs+Bb3BwVG6pitNopk3bx7r16+/6PtHjRrFnj17qK6u5vTp07Wr+JJjzB0iLqx8lmcttU9ZKXqZSHZzJKuUiOKDRCtFqN6B0GaE1iE1Kzf0ExUo35T2FHccXdFsJw85SmWNmePHDtNDdwZV0YmFSMntyGyzDg1O5i1mWHAfnDsomoHd/I1Y7ZWcpkkr8zb974GuM0Tn1B/v8vhRKBlFlagq+HnpiQi8SpfvqmL4arbYihDZWSSFukaMspMa7cJkXm3sqnrrYTDmWXF7xVMev3/+WI5YlW8Z4kuw71X2blvMYkxl9gEIiIRbvpPlhpLL6h4XQr/EFmw2d6VaHyAuQGV4/kVoZ1p9+IIu9h0nyiavTtYiwJsZvVuyw9KFCl0gVORB2k6tw/IoG47lMtpi/TttNRgCI7UNSGoUmczXwZbMt61vJ/tf/g7HVooy7Zu/gdAEB0Yn1SUutBHj6S6lKDD9rfOjvJY85NGlyLby48Rw/yuOnMJshO/vEJ3rA6Ph1h9El3TJqcS/E5RWmRre6PFCw58QlRWmKjE+s7rUfkG6GNsx3uFqJfaqCiv/dL5z/U3fiNcBSXJhtw9JpAYvNqq9xR2yDNmuVl+wX57OU7UNppm6Y2hrTBhYbewt7pDHuF39fCibiXrrfnnZxd5tyWT+ElVGc+3qbr1mzO/6BLb+T9ye+a7oHC053flZ803sduoXCrPniS7tR5d59P75pLOFAPRp1eLy36Sq8NNjcGodeAWI1UqZ5GjC10tfe5yfzW9kqT2I7T/XfSjmpuefgJ8e9diLVraxdJ1irpLMb3oVdn0EKHDd+5AwwPHBSVITTe4eS0SgD0ur+og7ji7XNiAPkl5YgencYdHhWy87fGulW8sQBrYJY6XZem595CePfb9ythqThT1HjjFASRF3yAtWbksm85c4Yz1JDvHzooX/VcoyDy+F5U+K26P/Aj1ucHB00uW0tMfKvE1cP5ho3T+/5jk4u63pj+mCdp0pAGBA6ysk8xv+DcnzxT7r2fOgZR/nBCfVKTpYlHnmlDRxDFVA+Pn58wcXwO5P7BCd6zl2TnTt7xB1hQuze76AtS+J25P/Bd1nOSEySWo6b4OOmwcmsN7SGxMG0dwy95jWYXmENYfPMUln6/A9FnwaONpSspu7h7Vmo6UnVXiLqslzh7QOySNsP5XPYONOdIqKGttbLtS4MZnMX+LCTvZXLD0+s0XMJUeFfnfCKNm5Xku2Mvv88hqqjHZokDLgXuh+A6hmsX++LLfpj+lCKmvMHMwoBmBA67C6v2nHh7DeelFj6mvQUa5MaC3KOoIxp9QOM6VbDYLxL4jbq56BtF1Nf0wXYyuzv+zKfMpKUZkAYvvBoN87KTJJso9bByVSqQtgi7mruCNFrs7bw+pD55hs6/Aty481Nb5LNGGhLdhk7iHukKX2diEuWIljXOkiu9i7M5nMX+JUfZrfnTt0wQi6qTDlNbHfWtJMsJ+BQB/RdbpJTfBsFEXMUI/oBKVZsOAej+qiui+9CKNZJTrYh/gWfr/9huRvYOUfxe1Rf4L+dzs3QKlOkUFiZT7XHsk8wJCHoMt0MNfA93Oh9Jx9HtcF5JVVk19eg6JA+7pW5s9ugx/uAtUCvW+Fcc85P0hJaqKYEF+m9oxltcVahixL7ZusqKKGc2cO00WXiqroodNkrUNq1gx6HbcPSWS1pR8Aqkzmm0xVVbYdPsVQnbXKQV6wcmsymb/EVTvZF6XC/BuguhgSBsMNnzTb0UWuRFGU2o72dim1BzGR4MYvwMsfTm84X4rrAXZbS+z7tw77bQXKkWWi+R/AoAdg9DNOjk66nChrMp9T2sTeEDaKAjPfO3/R6vvbwdSE5nouxLYqn9DCH3/vS16j03aJ6QymSrEXdvqb8oKs5LbuGd6GNWaR6JC+C0qztQ3Iza09msM1inXFss0I8L9M9ZrkNHMGJLBJ1x+zqqBkH4DCM1qH5NYOZZbQtWwHPooJS3gHiOykdUhSE8hk/hJXTOZLMuHz6efHc938DXjVsaopacKu++ZtojrDtdYGh5tfhwM/2u+xNbTrjGh+NyDxkv3yJ9eJbQWqWaxWTvw/meS4kCjbnnl7rcyD2At609fgEwJp22HVn+332BqyNb/reGkn+4w9MP96qCmF1iNg9uegv0p/FElyYT3jQ0ls3Za9lvbijpQV2gbk5lYfOscka4dvukzXNhgJgFB/b8b27cpOSxdxh6xAaZI1h88xWb8DAF1XuSrv7mQyf4Eak4XDmSVAHXssS7NFIl94Blq0htsWyqu1LsaWzGc0taP9pXrcAEMfEbeXPASZe+37+E5mtqjssXay73/hfvnTG+HbW0TJdZdrxZg+nXyJcCV2L7O3iWgP11u7ue/+RDSFc3PHckTzu47RF5TYZ+2HL68TlVWthorpDN7+GkUoSfZz97A2rLZ2/DYflmXIjVVlNJNy/Ch9dCdQUaCz3EvsKu4c2ppVFjFppPrAYm2DcXObD59hjC5ZfNJ1ppahSHYgz9QvsD+9iEqjmbAAb9pHXnACWJYLn18rxjiFJMAdP0FInHaBSnWyy6z5yxn/vCjHNVXBN7e4dRljSnYppdUmAn0MdLZdtDrxqyg7NlaIGeTXfyy3j7gguzbAu1THiTDmWXF7+ZNwdqv9n8OJUi4dS3fuEHwxA6qKIH4g3Po9eF+hN4okuZEJ3WLYFzhMfHJ6A1SVaBuQm9pyIo+RZrFiScIgCIrRNiCpVsfoIAoTrgHAO3OXR/V4caaMokpizm3CVzFiDm0NMT20DklqIpnMX2DbyXwABrcNQ6ezlhZXFIgTwLwUCGopEnk5vsEl2X3P/IV0epHgRnQU2yy+vRWMdq4AcJLdZ8V++T6tQjHodXBstWjoaKqCjpNgzldg8NE4Sqkutj3z+WXVmC0OmLU74klRlWGuEcdEbor9n8MJSquM7E8vAkQJMum74bMpUFkALfvCbT/KUVOSR9HrFMYOH85JSyx61YR6fI3WIbmlC7vYK7L82OXMGjOIZEs7FFQqDy7VOhy39OuRc0zRbwdA3/06uZXSA8hk/gLbT4tkfkjbcHFHaTbMmwo5hyAwGu5cBmFtNIxQupK4UFEua5du9nXxDYGbvxV/ZuyGpQ+DxeKY53Kg2v3yrcPEvrNvbxGTGTpPgxu/BC9fjSOULicswBtFAYsK+eUOWJ3X6WDWhxA/QKxgz7/BLVc/tpzIx2hWaR3uT5vinaKyqqpI/F5zF4r/w5LkYW4ckMA6ZSAAubsXahyN+zFbVPYcOcYA5ai4Q5bYu5xRHSNJ8h8OQN5Oz+hh5GwbD55hjG6f+KTrDG2DkexCJvNW1SYzu61JzuC24VBwCj6ZADmHITBGrMiHt9M4SulKbCvzWUVVWByxagniGJg9DxQ9HPgBfv4LqA56LgdQVZVdp8XK/GTzWtG93GKEbteJ38vgrW2A0hUZ9DrCA6xN8EockMyDaOp587cQ1haKU+Hr2VBd5pjncpANx3IAuD/6CHx9IxjLoe0YuH0J+LW4yk9LknsK9vWCzlMBCEpdCyYHvUZ4qH3pRfSr2oZeUbHE9oYWiVqHJF1CURRaDr4RgNjCXdSUFmgckXsprTLid3Yd/ko1xuBWENtb65AkO5DJvNW+tGKqTRYiAr1pr56FTydB0VnR7O6en+XYBjcQHeyLToEas4U8R6xa2rQbCzPeEbd3vAebXnXcc9lZRlEl2SWVPGZYSIetT4PFBD1vglkfy47ebqK2CV6ZA4/xgAi49UfwD4esffDDnWA2Oe757EhVVdYdzeVG/TrmnH72fEPHW76Te+Qljzfhmqlkqy3wUytITVqpdThu5dcj55isEyX2OtnF3mWNHT6E47TCgJl9a7/VOhy3suFYLhMUUWLv1X2mLLH3EDKZt7Ltl78pNhtl3hQoOwdR3eDun0VCL7k8L72O6GDbvnkH72fvfTNMfEXcXvsS7PrEsc9nJ0mncviX4SMeM1jL04Y/IeaMy2Z3bsO2bz7XUSvzNuHt4JbvweAHJ9bAgnvAbHTsc9pBSlYRd1d8wr+9PkJRLdDnNrjhM9kHQmoWWkUEkhI6CoDMrd9pHI172XHoJEN1h8QnXeR+eVflY9BTmDgJgJqDS1DdqDpSaxsOpjJWZ53I1G2mprFI9iOTeavtp/KZodvM4xlPQFWx6HZ813LZydTNOGTW/OUMeRBGPCVuL38SDi5w/HM2RVUxXdbfxxzDeizoYOrrMP7vcvycm4lyxsq8TXx/uPFz0HnB4cVihd5U4/jnbayqYvx+vI3fGawziEc+Dde+LS9WSc1KwrCbAOhYtJH0fNnVvj7SCytok78eL8WMKaIrRHbUOiTpCjqPuQWAfjVJbD2aqnE07sFotmA8toYApZrqgDjRDFbyCPIsHqiqMTI6/V3e9H4XvaVGdPS+fbHcW+mGnJrMA4z9K/S7C1BhwX2wd75znrehsg/Ah6PpWLqTCtWH5GHvwoB7tI5KagRbmX1OiZOmKXScCDd9BXpvOLpM9Flwxb24Bafg42tILNhMlerFxp7/grHPyjJCqdlp2+8aSnXBhCll/LpqkdbhuIV1R3OYrtsGgKHnLI2jka4mOLE3BT5x+CpGdv/yg9bhuIVdZwoYYxYjZ716yC72nkQm81UlVHwxh9/rlgCgDnscbvpa7q10U7ZZ8+mFTkrmFQWmvga9bgHVDEsegs1vuFZTvL1fwcfjoeAU6WoEc2r+RuIQebLirmwr8w6ZNX85HSfCzd+AwReOrYTvbnOt0YwHF8KHoyEvhWy1BbNr/k7rUbdrHZUkaUNvoKzNRAAMKcspLHfhahoXsf3g8fMl9t3k+6PLUxQM3UQn9tY5v3IkS1agXM36Q2mM0+0BQCdL7D1K807ms/bDx+MJS/+VatWLL2KfRbnmeTFTXHJLcY6cNX85Oj3MfBeGPiI+/+XvsPqv2o+tM1bC0j/AkgfBVEVezAimVb9MeUQPwgPl/mF3FWXtC5HrzGQeoP140UTO4AfHV4uxncUZzo3hUtWlsOgB+PEuqCqmMKwX11a/RHlED1qF+2sbmyRpKGbQbADGKzv4cttpjaNxbeXVJsLOrsKgWKiK6C4nF7mJ4D7iostY3V4+XndE42hcX8Xh1QQqVVT6xYotdJLHaJ7JvMUCW96Ej8ZCXgoFujBurPkbht43aR2Z1ESxIdYy+2InJvMgVugn/AOu+Yf4fNvbsOj3UFPh3DhszmyB94fDni8ABcY8y3/C/0ERQWL0ouS2IrVYmbdpOxpu+1HMac/YDR+OgjObnR8HQPpueH8E7PsaFB2MfJp/xf6XHFowumOUNjFJkotQ2o7GaAgkWiliz9Y1VBnNWofksjafyGOiIkrsfXrdoHE0Ur3F9cPoH02QUknRoTWk5mt0vuUGTuWW0b98PQD6btfKEnsP0/yS+eJ0+OJaWPMcWIyYO05hcvU/2ae2Z0g7meS4O1s3e4fN4L6aYY/AzPetc+i/F8lOZrLznr+qGH56DOZNgfwTEBgDcxdSOeRJlh8Us7dn9o5zXjyS3Z0vs6/Spotv6+Hwu/UQ3R3Kc+Hza2H7e87bWlKeD8seh0+ugcLTEJIAdy5HHfMX1h4rBGBM50jnxCJJrsrgg76z6Pg9tGYrPySlaxyQ69px4AhDdIcBUGT5sfvQ6fDqJqYOTFR28v7GkxoH5Lo2HjrLBF0SAN69b9Q4Gsnemlcyf2o9vDsUzmwCrwC49n/sGPgW58yBRAf70FqWZbq9qGCR6OSX12C2aLRvvffNMHcRBMVC3jH4eBxseh0sDlwZsVjgwI/wzmBI+kzc1/cOeGgHtBvL6sPZlFWbSAjzo3+ibOzozmwr81VGC2XVGs1+D2sL96yGHrNFr4hVf4ZvboJ8B55MmU2w4wP4Xx/Y/SmoFuhxI9y/GRKHcjirhJzSavy89AxsE+a4OCTJTei6ikRnkm4nH204icms8dYvF2SxqHgfW45eUSkN7wlhbbQOSWqIbtcBMFG/iyW7z5Bd7EK9XFxI6f6f8FeqKfGLh7h+Wocj2VnzSubDrPug4vrB/Zug7+1sP1UAwJC24Siy7MTthQd4oyhgtqgUaNn0p+0oeGArdJkOFhP8+gJ8Ph3Sk+z7PBaLaP713hAxB7w0UyRad/wE174FfqEALNwj9jZf1ycenU4e5+7M39tAoI8YtaZJqb2NdwDM+ggm/RN0Bji2Ct4ZJKqequzYjMhUDclfw/vDYOXTovokujvcuRyu/6j2GF+fkgvAsPbh+Bhk3xNJov14VIMfrXS5BBUd4af9mVpH5HL2ZxQz2iS2Cvn1ma1xNFKDtRoMgTGEKBUMUPfx8aZTWkfkckqrjHTN+xkAc7cbZIm9B2peyXxoAty1Au7+ubbBiS2Zl/uIPYNBryM84HwZsqb8w+DGL8Wca68AOLsFPh4LX14HZ7c27bGrSs4nOD/eBblHwScExjwrLiK0GVn7rTmlVWw6LhKdWX1kib0nqJ01r2UyD+KkYPAD4phrNw4sRtGP5H/9YNu7UJbT+McuPQfrXoH/doPFD4hj3K+FmB7xuw2i3P8C61PEc43uJPfLSxIA3gEo7ccBMFG/k7fXntCuYs1F7dh3kIHKUQAM3a/TOBqpwXR66Cq62k/T7+CrHalyesMldhw6wQhlHwAtBt6scTSSIzSvZB4gpjvovQAorjSyN03ssZT75T2HJqO7LkdRoO9ceHAr9L5V7KU/uRY+mwyfToLt70POkfrtN64ph0OLxFiw/7QXCU7OYZHEj34GHtsPo54GL7+LfmxpciYWFfq2CqV1hBy56AkiXOkYB4jsBLctgFu+h/D2UJ4DPz8Dr3USF6+Sv4GKgis/htkEabtgw3/gs6kiid/wT7EvP6gljHsOHtkLA+4FveGiH00vrCDprHgtH91J7peXpFpdRKn9VMMuTuaWs/JglsYBuRbLoaXoFJX8Fr3Fgo/kfqyl9pMMSZiNVXy29Yy28biYwt0L8FbMZPt1gKjOWocjOYDh6t/iuVYcyMJoVukUHUSrMLlf3lNEBvlAFuRq1QSvLi1ai/F1o54Wc+iTv4LUbeIDICBKrDQGtxTJuJe/mOldkiH23eemQFEqcEHSH94Bes6BgffVlhrXZYG1xH5W33hH/XaSk9VesCpxof2BiiLm0bcdA3u/EJUjGUni4tXJteJ7fEPF/4UWieAXBpWFUJEvEv3iNKi+pDw/fiAMvl8kJNaLsHWZvz0ViypK7ONbyNdySarVcSLovGhnyaCDks7ba4OY0j1WbrcCsoor6V++DnTg21t2sXdbCYMgqCWBpZmM0O1n3hY/fjeybe12tObMYlFpk70CgOrOsvLEUzXrI32RbR9x3zi5X96DXNjt2+W0aA3T34CRf4T938HpjZC6XaxkHlp49Z8PTYTus6D79WLf8FWO28OZJRzJKsFbr2Naz1i7/AqS9qKCrLPmy1zogpWNwVusng+4VzTEO7hANGfMS4GqIshKFh918Q2FNiPECLy2Y+o177nKaObbXakA3DGktX1+B0nyFH6h0H4cHFvFLO8d/Cs7njVHzjGxW4zWkWluZ/IBZuiOYUEhoM/1WocjNZZOB91mwvZ3uck/iV/L+vHltrM8MPrq7x+e7sixFPpaDoMCscNu1TocyUGabTKfVlDBzjMFKIoc1eVpbB3tXaYEuS4hcTDiCfFhqhYzs9O2i+ZeNRVgrARjBQRGQURHUcYc0QkCIhrUvGTRXjGOaFyXKEL9vR3120hOZuto71LVJ3UJbyeqUUY9LbaJFJ6ForNQeEYc635horeEfxgERkNkZ7EHsgGWJmdSVGEkvoUf47pEO+b3kCR31v16OLaKOX47+Vf1LP639jgTukY3+0UM877vAMgM6UN8cEuNo5GapNt1sP1dRrMLH+7ko02nuH1IIgHNfHU+d/s3dFNUTvj2oH1Ea63DkRyk2R7li/aKVflh7SKICfHVOBrJnmyrlprNmm8ogw+0HiY+7MhktrA4WXQvliX2nsWl+kLUl3cARHcVH3aiqirzrPsj5w5ORC9LhyXptzpNBoMvYVVp9PNOIylDYX1KLmM6N99mkdVGEz3zV4ECSs+btA5Haqq4/hAcj1dJOteHpPB1cQ++kKvzxKUtA6Ck/QyNI5Ecqfk1wEOcANqS+etkd2+PU9vp2xVLkJ1oy8l8ckuraeHvxaiOsimYJ4l0lW72Gks6W8jhrBJ8DDpu7C+bV0lSnXyCoMMEAJ6MOwTAW2uPo9an8aqHOrJnM+2VdKrwJnbIHK3DkZrKVmoP3B+xH4APN56krNqkYVDayj97iA7mE5hUHa1G3KJ1OJIDNctkPjmtiNN55fh56ZnUXe4b8zTny+xdcM+8E31hXbGc3qsl3oZm+V/dY8ljXLCtys/sHUeLALmNRJIuq/ssAAaVr8fHoLA3tYiNx/M0Dko71UlfA3A0eBg6/1Btg5Hsw9rVPiF3A53CDRRWGPm8GXe2z9o8H4B93n2IiJYLl56sWZ7h21blJ3WPafb7aTzRhWX2zXXlITmtiF+P5qDXKdw1rI3W4Uh2ZjvGCyuM1JgsGkejjXMlVaw6mA3AHUNbaxuMJLm6DhPBKwB9SRpPdy8H4LXVKc3zPdJsokPuzwCYut+ocTCS3cT1g5AElJoyXugqRjB+tOkUpVVGjQPTgKoSdXoxAHltrtU2FsnhHJrMv/zyywwdOhR/f39CQ0Md+VT1VmOysHSf2EcsS+w9k60EudpkoaSqeZZY/XfNMUAc423kbHmPE+rnhcG6PzyvmW4n+Wr7WUwWlYGtw+jaMljrcCTJtXn7i73zwC0Bu/D31rM/vZg1h89pHJjz5SSvJEwtIl8NpuOwmVqHI9mLotSW2g8sX0fbyACKKozM23JG07C0YDy1mShTJmWqLy2HyAtWns6hyXxNTQ2zZ8/mgQcecOTTNMj6lByKKoxEBfkwrH2E1uFIDuDrpSfIV1Rc5DbDMuSks4VsOJaLXqfwyNgOWocjOYBOp9RetHKrJnh2UmU08/VO6zg6uSovSfXTXYxf8zv2E3cNbQXA62uOYbE0r9X58l1fAbAzYDTBAf4aRyPZVfcbANClrOTJkWIb7UebTlHSzFbnC7d+BsAvumF0S5RjiT2dQ5P5F154gccff5wePXo48mkaxFZiP6N3S9n52IPVdvt2l472dvTGL2JVfna/eFqFyxMVTxXVjJvgzdt6hryyGmJDfJnQTY6jk6R6aT8OfEKgNJMH2uQR5GvgaHYpyw5kaR2Z81SV0PLcWgAquszWOBjJ7mJ7iRGn5mom63bQPiqQkioTn20+o3VkzlNdRujpFQCkJl6HTuY6Hs+l9sxXV1dTUlJy0Yc9FVcY+fVIDiBHdXm62n3zzSzR2Xm6gE3H8/DSKzw0pr3W4UgOdH5lvnlVn+SVVfPO2hMAPDWhE156l3obkyTXZfCBLtMACDyxhN+NaAvAG2uOYTI3j94bxoOL8VGrOWFpSff+o7UOR7I3RYGeYjqBbv/3PDpOVCd+vOkUheU1WkbmPIcX422p5KQllta9x2odjeQELnUW9MorrxASElL7kZBg31FDSakFmFWVzjFBdImVeyw9WXPt9m3bKz+7fwIJYXJV3pNFWi9YNbeV+f+uOUZptYkecSGy74kkNVQ30dWew0u4a2gCYQHenMorZ6G1atHTle0UJfa/eI2mY0yQxtFIDtHzRkCBs5uZmmCka2wwpdUm3ll3QuvInKJ695cALLSMZKQcS9wsNDiZf/7551EU5Yofu3fvblQwzzzzDMXFxbUfaWlpjXqcyxnbOZrtz4zj1dm97Pq4kutpjiXIW0/mse1UPt56nVyVbwaimuGe+ZTsUr6x7pX/27SusnzQAQoLC5k7d27tRfW5c+dSVFR0xZ+58847f3MeMHjwYOcELDVM21HgFwbluQRmbOaBUe0AePOX454/GaM4ndCcHQCUdJyFosjXD48UEg+thwOgO/gDf5rcGYAvtp0lvbBCy8gcL/8kPhnbMasKKdFTCfWXI1ubgwYn8w8//DBHjhy54kf37t0bFYyPjw/BwcEXfdhbZJAP3eNC7P64kmtpbmX2ZovKv1YeBeCmgQnEhfppHJHkaJHNrC+Eqqq8tPwwFhUmd49hYJswrUPySLfccgvJycmsWrWKVatWkZyczNy5c6/6c5MmTSIrK6v2Y8WKFU6IVmowvVdtIzySv2HukESignzIKKrk6x1ntY3NwdS9X6Ggst3ShT49emodjuRIvW4Sf+7/jpHtwxnSNpwas4X/rjmubVyOlvw1AJssPenVtavGwUjO0uAh6xEREUREyC7wkmurLbNvJonOZ1tOsy+9mCBfAw/LVflmobb6pJmMplufksum43l463X82brSItnXkSNHWLVqFdu3b2fQoEEAfPTRRwwZMoSUlBQ6dep02Z/18fEhJibGWaFKTdH7Ztj1ERxdhu+0Mh4d34FnFx3kzV+PM6tfPMG+XlpHaH8WM6bdn+MF/GAZx4vtwrWOSHKkLtfC8ich7xhKVjJ/ntyZGe9sYeHedO4b2YbOMR641dZiRk3+GgX4wTyK+ztFaR2R5CQO3TOfmppKcnIyqampmM1mkpOTSU5OpqyszJFPK0nNqjlYWkEFr60We+X/MqULUcG+GkckOYPtGM8t8fxj3Gi28NLywwDcOaw1ieEBGkfkmbZt20ZISEhtIg8wePBgQkJC2Lp16xV/dv369URFRdGxY0fuu+8+cnJyrvj9jm54K11By76i47epCg4tYk7/BNpHBVJYYeS99Se1js4xTq7FqyyDIjWAgsRJBPg0eC1Lcie+wdB5qri9/zt6JYQypUcMqgr/WZWibWyOcmo9SmkmRWoAe/0G062lB16wkOrk0GT+ueeeo0+fPvz973+nrKyMPn360KdPn0bvqZek+mou+4lVVeWZhQeoNJoZ3DaMmwbYt2mk5LpsF21yy6pRVc+eE/3BhpOczC0nLMCbh8fKyhNHyc7OJirqt6s5UVFRZGdnX/bnJk+ezFdffcXatWt57bXX2LVrF2PHjqW6+vKvv45ueCtdgaJA71vE7eSvMeh1/HmSqHb5ZPNpMooqNQzOQXaLudsLzCMZ1lk2zmwWelpL7Q/8CGYjT03ohF6n8OvRHHaeLtA2NkdIFs0dl5iHMrhTnOwp04w4NJmfN28eqqr+5mP06NGOfFpJqu30XVplospo1jgax/khKZ3NJ/LwMej456yesqFPMxIRKBrbGM0qRRVGjaNxnP3pRbzxi9jn+OyULp5ZAuxgDWlcW9driKqqV3xtmTNnDlOnTqV79+5Mnz6dlStXcuzYMZYvX37Zn3F0w1vpKnrOAUUHaTsg/yTjukQxqE0YNSYLr/3sYSuXJZmox1YB8LV5LKM7yQ7fzUK7sRAQCRV5cHItbSMDmWNd8PjnyiOedRG8LBeO/ASIEvvRssS+WXGp0XSSZC/BvgZ8DOLw9tR98zmlVby0TJQeP35NR1pHyNLj5sTHoCfUXyS2nlqBUllj5rHvkjFZVKb0iGFWX7mi1hj1bVwbExPDuXPnfvPzubm5REdH1/v5YmNjSUxM5PjxyzebckbDW+kKgmKg3ThxO/lrFEXh2aldAFiUnMHBjGINg7OzvV+hqGZ2WDpTFdKedpGBWkckOYPeAN1vELf3fQvAY+M64OelZ09qEcv2Z2kYnJ3t+RzMNSRb2nGYtozsIHubNScymZc8kqIoHj1rXlVVnlt8iJIqE93jgrl3eButQ5I04OkjGF9ZeYRTueVEBfnw8swesvKkkSIiIujcufMVP3x9fRkyZAjFxcXs3Lmz9md37NhBcXExQ4cOrffz5efnk5aWRmxsrCN+Hcleet8s/tz3LVgs9IwPZUbvlqgq/N8KD1m5tJhFogN8YxrLqE6R8nWkObF1tT+6DMrziQr25YHRYhzjP1ce9YzKTbMJdn8KwOemCfRp1UKOpGtmZDIveSzbeDpPTHQ+33qGVYeyMegU/nV9Twx6+V+5ObId4+c8sAneupQcvtgmRmW9OrsXLQLkyYmjdenShUmTJnHfffexfft2tm/fzn333ce0adMu6mTfuXNnFi1aBEBZWRlPPfUU27Zt48yZM6xfv57p06cTERHBddddp9WvItVHp6ngEwIl6XBmIwBPTeiEt17H1pP5rEu5chNDt3ByLRSnUUIgKy0DGd1Rltg3Ky17Q2xvMNfU7in/3ci2xIX6kVFUyYcbT2kanl0cWwklGZToQllhGSSP8WZIZgCSx/LUJnhJZwt5afkRQHSv79YyROOIJK3Ehohk3tMaVhWU1/D0j/sBuHNoa0bKkxOn+eqrr+jRowcTJkxgwoQJ9OzZky+//PKi70lJSaG4WJRh6/V6Dhw4wIwZM+jYsSN33HEHHTt2ZNu2bQQFBWnxK0j15eULPWwz58V86oQwf+4a1hqAl5YdocZk0Sg4O0maB8APphFY9D4MbS/Lj5ud/neLP5PmgcWCr5e+drzpe+tPkl3s5hfDd34IwLfm0VTjLffLN0MymZc8VpQHjqfLL6vmoa/2YLKoTO0ZW3vSJTVPieH+AJzNr9A4Evsxmi384Zs95JZW0yEqUM6Ud7KwsDDmz59fOy5u/vz5hIaGXvQ9qqpy5513AuDn58fPP/9MTk4ONTU1nD17lnnz5snu9O6il7Wr/eGlUCXGAz40tj0RgT6cyivn0y2nNQyuiUqyIGUlAN+Yx9A/MYxAOZKu+el+PXgHQcHJ2gqUaT1jGdC6BZVGM/9adVTjAJsg5yic3oiq6JhXPZaIQG85kq4Zksm85LFso7s8pQGe2aLyyLd7yS6pom1kAP+6Xnavb+5aWeetpxV4TjL/0rLDbDmRj7+3nv/d0gdfL73WIUmS54rvD+EdwFQJhxYCEOzrVXsR7a1fj7vvyuWez0E1k+LTnRNqvOxi31z5BEKvOeK2dW+5oig8N60bigKL9mawJ7VQwwCbYNdHAKSEjCCTCEZ1jJIj6ZohmcxLHisy0LPK7P+75lhtkvPBbf3kCoNEqzDrynxBucaR2MfXO1L53LpP/r9zetM5Rq4wSJJDKQr0vV3c3vkxWJvezeoTR99WoVTUmHll5RENA2wkYyXsFInOB5VjARglk/nmq99d4s+jy6FUTOzoER/CDX3jAXjxp8NYLG7W8LGqGJK/AeDTmvEA8oJVMyWTecljRQZ7TjK/cE86b6/7//buPC7Kan/g+GfYd8SNRQV3UEFT3HDfcimvluVaLi1etbyldW9561dZ95ZL271li5ZbWbapXctyS0TNXdHcNxBIREDZERiY8/vjgVFkQFCWmeH7fr3mxTBznmfO4TBz5jznnO85D8C8USG08pa1qAICCjvzV9JzLT4q776oq7z6v+MAPH9va4a086nhHAlRS3R8FOyc4coxiN0LgI2NjjdGBqPTwf+OxLMv6moNZ7KC/vgWspPJcfHjf3ld8PFwIlDazdrLJxgadwVDPkTeiAHyj6GBuDrYciQule8PxdVgBu/A0W9An4XeqyXfXWuOjQ76tJLOfG0knXlhtW5s22WhUwQL7TyXZAwG9tc+zRl5j+y1LTR1XOxxL5yhYclT7eOuZTOjMBbE8Pa+zBzQsqazJETt4VIX2o/W7u9fbHw4uJEn47v6A/Da+hPkF1hIMDyDAfZ8BEBE3YcpwJa+rWVLulrPGAhvpbZlIdqOMLPvbQ3AvF9PczXTQgZ/DAY48DkAkT5jAB2d/L3wdLGv2XyJGiGdeWG1irbtupqVZzlfQm5x/FIa0788RL5BMaKDH3OGSjAwcYNOp8PfwoPgJWfmMnnZfq5l5RHSyJO3H+4gX7qFqG5d/6r9PPUTpMcbH/7H4EA8ne05nZDBqr0xNZS5Cjq3GZLPgqMHH6aGATL9WADtHgCnOpAWq21ZWGhKj6a08fUgNVvPm79YyJKSs79q/+MO7nyR3R2Q//HaTDrzwmrVc3XA1kaHUlqH3tLEXcvmsRUHyMoroEeLerw9ur0ENhElGCPaW+DIfNp1PZOW7icqOYtGdZxZMikUZwcJeCdEtfMJAf8e2jTkwu3cALxcHfj7kEAA3tl8lstpFrAN5p5FAKS3e5TjyQpbGx09W8mWdLWevTPcU7h7Q2EgPAA7WxveelBbUrL28CV2X0iuoQyWk1Kw4x0A8js/wbZo7T0pW9LVXtKZF1bLxkZHfTcHwPIi2idn5jJ5+X6SMnIJ8nHn04mhONpJJ0eU1KRw3bylTbO/nlfAEysOcPJyOvXdHFn1ZDd8PZ1rOltC1F5dp2o/Dy6H/BsXwCd09aejfx0yc/N55cfjKGXGgcLiI+HiTrCxY4v7AwCE+nvh4STTjwU3AuGd3QhXLxgf7ujvxSPdtCUl//fjcXLzzTgGTVQ4xB8GO2cO+Y4nO6+ABu6OsiVdLSadeWHViqbaW9Je88mZuUz4bC9RSdpo5crHu8oXEVGqgLra9nQxVy0non1evoHpqw5xMCYFDyc7vnyiK83qu9Z0toSo3dr8Bdx9ISsRTv7P+LCtjY4FD7XH3lbH1lOJ/HIsoQYzeRu7tVF5gh9ifbQ2k61fkEw/FoUatIZWg0EZYPcHxZ76x5Ag6rs5EpWUxeKIqBrKYDnseFf7GTqZLTHaEtJ+EhOiVpPOvLBqRUHwLCWifVFH/uyVTLw9tNFKbw+nms6WMGNF29PFWsjIfF6+gWdWRxJxNglne1uWP9aVNr4yoiBEjbO1vxEkbP+SYk+19nZnRj8tMOVr64+Tmm2GS9dS4+DEOgCyO89gzwUtAv+9bbxrMlfC3PSarf088jVk3Lgw5elszyvD2wCwKPw8UUmZNZG7ssXuhZhdYGMPPZ5h+9kkQKbY13bSmRdWrUFRZ94CptknZ+byyGf7jB35b/4aJqOV4raK1szHpVw3+31yc/QFTF91iI0nEnCwtWHJpFBCA7xqOltCiCKdJmsdhT/3a1PWb/J0/xa0bOhGcmYeb24ww0Bhez8BVQDN+rAj3Ye8AgMB9Vxo2dCtpnMmzElAD2jSHQryYO/HxZ4a0cGP3q3qk5dv4O/fH6XA3NrUwrXy3DOeuAIvzidmYmujo5fEhKjVpDMvrNqNkXnznmZf1JE/cyVDOvKiQnw9nbCz0ZGXbyAh3Xz/z7Pz8nly5UG2nU7Eyd6Gzyd3prfsiSuEeXH3hnYPaveLpqwXcrSzZcFDIeh08P2hP9l1zowChaXHw8Gl2v2ez7LlZCIAg9p4y/RjUVLR6PyBZXA91fiwTqdj/kPtcXO043BsKp/vNKPp9vFH4PwW0NlAz1nGUflQfy88nWUpZm0mnXlh1Rp4FK2ZN9+R+bhr2Tz8yW5jR3711O7SkRflZmdrQyMvLXCcuU61z8jRM3nZfnadT8bVwZYVj3WlT2vpyAthlno+o/08vgaSzhZ7KjSgLpO6BwAwZ+0fZOToqzt3pkUshPwc8O9BQbMBbDt9BdA680KU0GowNGwLeRnG/dqLNKrjbJxu/+7ms5y9klETOSxpZ+Fa+eCHoF4Ltp/WLlj1lS3paj3pzAurZu5r5k9dTmfUJ7u5eDWbxl7OfPPXMJo3kCmBomKM6+bNcK/55MxcHvl8HwcupuDuZMeXT3aje/N6NZ0tIURpfEIgaDigYMfCEk//Y2gQjb2c+TPlOnPXn6z+/N3q6gWI/FK7P/BVDselkpKtx9PZns5NZRmPMMFGG90GtOUZ+uJbLo7p3IT+gQ3IKzDw/HdH0RcYqj+PN7tyEk79pN3v9Rw5+gJ2F8aE6C/r5Ws96cwLq1bUmU82w878vqirjFm8x7j93JoZPWREXtwRcw2CF52cxaiPd/PHn2l4udizemp3OvnLl2shzF7fF7Wfx34oMTrv5mjH+2PvwUYHaw7/yYY/LtdABm+yfR4Y8rXR1oAwtp7SRuX7BzbA3la+5opSBD8EdfwhOxkiVxV7qmi6vaezPccupfHJ9gulnKQaKAWbXgIUtB0J3m2JOJvEdX0Bfp5OtPF1r7m8CbMgn3LCqhXtW30lPYccvfnsG7rxeAKTlu0nIyefLk29+HZamEStF3esKAhejBl15g/HpjDq49+JvZZNk7rO/DCjB8GNPGs6W0KI8vBtX+bofJemdXmqMLr9S+uOcTnteok01SLhuHbBAWDA/wGw9aTWmR8oU+xFWWztoEfhkpLdH0BB8SUj3h5OvD6iHQAf/HaO45fSqjuHmnObtb3lbR1g0OsAxgto94X4SkwIIZ15Yd28PRyp7+ZIvkHV3AfxTZRSfLL9AtNXHSI338CgNg358oluErxE3BX/wr3mY81kr/nNJxIYv2QvKdl6Qhp5snZGT1rI8hEhLEsZo/MAzw5qRfvGnqRd1/P374/WzG4a4W8CSgva59uBqKRMLiRlYWejk7XE4vbueQRcG0BqLBxcXuLpkff4MbSdD/kGxd9WR5KZm1+9+SvQw6aXtfvdpkPdZuToC4yzT+5v71u9+RFmSTrzwqrpdDo6+dcBIDI2tUbzkpdv4IUf/mDBxtMATAoL4NNHQ3Gyt63RfAnLZy7T7JVSfBpxgWmFF6v6Bzbgm792N24RKYSwILcZnbe3teE/Y+/B2d6W389fZemu6OrNX9wBOPML6Gyhv9bh+e2UFhSse/N6eDjJRXJxGw4u0O+f2v3tb0H2tWJP63Q65o0KwdfTiejkLF5aewylqvGi1YGlcPUcuNSHPn/Xsnkmiey8AhrVceaeJnWqLy/CbElnXli9joVrdA/HptRYHlKy8nh06T6+P/QnNjp4fUQ73hgZjJ2s5xOVwL9wmn1Ktp70GoounaMvYPa3R5j/62mUggnd/PlsUmdcHe1qJD9CiErQ9wXtZymj880buPHK8LYALNx0msjqameVgi2vavfvmQD1WwEYRywHtZGgYKKcOk3WIttfT9F2RbiFl6sDiyZ0xNZGx/qj8azeH1c9+cq+psWDABjwMjhpy9Q2HNOm2N/fXqbYC430JITVq+mR+RPxaYz4aBf7o6/h7mjHsildmNyjaY3kRVgnN0c76rk6ADUT0T4hLYexi/fw45F4bG10vDGyHW8+IBerhLB4vh1ujM6H/9tkkvFdmzC0nQ/6AsWMVYdJqo6As5FfQuxusHcxLgdIycrjYIx2MUHWy4tys7WDIW9q9w98ZvKiVWhAXV4YEgjA3J9OcDI+verzFbEQclK1Cw0dJwFwPa+A34qm2IfIFHuhkW9awuqFNPbE1kZHQnpOtQfpWRf5Jw99spu4a9dpUteZNU/1oJ9sIyKqQNHofHVPtT8Uc40Ri3Zx9M806rjY8+XjXZkU1lRGDISwFv3+CTobOPk/OL+1xNM6nY63R7enRQNXEtJzmPn1YfKrciuvzETYrAW7o/9LUKcJANvPJlJgUAT5uNOkcOmREOXSYgC0HqbtilD0v3WLqb2bMyCoIXn5Bp7++nDVrp9POqNdWADtQoOtNsNt+5lEsvMKaOzlTPvGElBWaKQzL6yei4MdQT7a1h2HY1Kr5TX1BQbmrj/B7G+PkqM30Ld1A36a2YvW3rKFiKgaAYVfXmOqaWReKcWyXdGMXbyXxIxcWjV0439P96RHy/rV8vpCiGriEwzdZmj3NzxfYk9uAHcnexZP7Iybox37oq8x/9fTVZefX1+EnDTwvedGvrgR4XugTLEXd2Lwv8HGHs5tMnnRysZGx7ujOxjXzz//3ZGqCfpYoId107QLC62HahcaCv1cNMVeotiLm0hnXtQKRXtbV8d6vstp1xm/ZC8rdl8E4JkBLVk2pQt1XByq/LVF7VWdQfAyc/OZuTqSN34+Sb5BcX97X9Y93ZOAeq5V/tpCiBrQ/yXwaAQpF2HH2yaTtGzoxjujOwDw+a5o1h+Nr/x8nN0EJ9ZqQe9GfGAcsYy9ms1vp7Xgd6M6Na781xXWr35L6DZNu7/pZSgoOfKurZ/vhIOtDZtOXGHBpiq4aBWxEOIjtTXy979nfPh6XgHbCgM8ShR7cTPpzItaoWPhuvmqDoIXfjqR+/67k4MxKbg72vHZpM48NzgQWxu5giqqln9hRzr2WtVuT3cmIYMRi3ax4Y/L2NnoeO0vbVk0viNuEuhOCOvl6AbDCoOD/f5fSDxlMtnQYB+e6tcCgBd/+IM//kytvDzkZmozAwDCntLW8xdaueciSkHf1g1kG0xx5/r8A5zrQtJp2PmOySShAV4seDgEgMURUazeH1t5rx+778brDv8PeDYyPhV+JpHr+gKa1HUmpJFMsRc3SGde1ApFI/PH49PJzS+o9PPrCwzM++UUj604QEq2nuBGHvz8TC/ubStBeET1qOqReaUUX+6NYcSiXUQlZeHj4cS308J4rGczme4nRG3QZjgE3qdN//15NhhMr4t/fnAgfVs34Lq+gCnLDxCVlFk5r7/t35AWB3UCoN9Lxoczc/P57oAWYXxKz6aV81qidnKuA8MWaPcjFkD0TpPJHuzYmGcHajsovPLjcXadS777187NgLVTQRmg/TgIHlXs6aJlJPeH+EmbK4qRzryoFQLqueDlYk9evqHSo5DGXs1m7OI9LN4RBcCUHk1ZM6OHTDkW1SqgMABefGoO+koOPpWancf0VYd45cfj5OYb6BfYgA3P9CI0wKtSX0cIYeaGLQR7V4jdA0dWmUxia6Pjo0c60b6xJ9ey8pi4dD9X0nPu7nVP/QT7PtHuD39f2x+80NrDf5KRm0/z+q70bdXg7l5HiPZj4J5HtU71michy3RHfdagVjxwjx/5BsWMrw5x7krG3b3ur3MgNQY8/eG+4lvkZefl89tpiWIvTJPOvKgVdDqdcb/5ytqiTinFmkN/ct8HOzkcm4q7kx2fPtqJuSPa4WhnWymvIUR5NXR3xNHOhgKD4lJK5e3asC/qKvf9dyebTlzB3lbH/93fhmWTu1DPzbHSXkMIYSHqNNHWzwNs/CdcOWkymZujHcundKFZfVcupV5n0tL9pGXr7+w1E47D2sK1zN1mQMuBxqcMBsWK3y8C2qi8jSxpE5XhvoVQPxAyE2DddJOzUHQ6HQsebk+Xpl5k5OQzadl+Libf4TK3Yz8UXhzTwajFxj3li6zYfZEcvYGAei4EN/K4s9cQVks686LWMO43H5d61+dKy9Yzc3Ukz39/lMzcfLo09eKXZ3ozNFiumIqaodPpKnWqfW5+AfN+OcW4z/YSn5ZD03ourJ3Rkyd7N5cvzELUZt2mQ9PekJcJq8dCZpLJZPXcHPni8a40dHfkzJUMnlh5gOy8Cm7nlZUMq8eDPgua99Mijt8k4lwSUclZuDvaSeA7UXkcXGH0crBzgvNbYM+HJpM52tmyeGJnWjZ043JaDmOX7Kn4spJzW7ULBgC9ZkNAj2JPJ2bk8NG284A2G0Cm2ItbSWde1BpFI/OHY+4uCN7Oc0kM/e8OYwCwfwwJ5Ju/hsm+tqLGFU21j7nLzvypy+mMXPQ7i3dEoRSM6dyYn5/pTYjsayuEsLWDMV+AVzNIjYVvH4X8XJNJm9R14YsnuuLhZMfBmBQe+XwfKVl55Xud/Dz4bhKkxWqv9fByY/T6IkWj8mO6NJEgnKJyebeDofO1+7+9AdE7TCar6+rA6qndae3txpX0XMYu2cv5xHJ26GN2a+8fgx7ajYIBJfe4f3fTWbLyCujQpA4jOzQycRJR20lnXtQaHZrUQaeDS6nXSbyD9XuZufn8c+0xJi7dz+W0HJrVd2XNjB483b+lRKsXZsG/rhanYX/0tTs6Pr/AwMfbzzNy0e+cTsignqsDSyaGsvDhDvJFWQhxg0tdmPAdOHpC3F746VlQpvfcDvLxYMXjXfF0ticyNpWHPt3Nnym3ueCoFPz6AsT8Dg7uMP4b7TVvcj4xk4izSeh0MDmsaSUVTIibhE7ROtmGfPhqtLY1ogkN3B1ZPbU7QT7uJGXkMm7J3tuvoY8/Al+Phfzr0GowPLgYbIov0Tx+KY3vDmnBHV8d3lZmxQmTpDMvag03RzsCvd0BOFzBdfO/n09myPs7jFuQTOnRlA3P9KJDkzqVnEsh7tyIe/zQ6eCno/HsuXC1QseeupzOgx/vZuHGM+QVGBjUxptNs/swuJ1PFeVWCGHRGrTWpiLrbOHoatj1XqlJO/l78cP0MPw8nYhKymLUx7s5dbmUYLT5efC/p+HQckAHD30ODYNKJFu6Sws6OzDIG/96MjNOVAGdDh74GFoPhfwc+GaCtr7dhHpujnw9tTttfT1Izszl4U/3EH460fR5E0/BqlGQmw4BPbWZLnYOxZIopXjj55MoBSM6+EnAWVEq6cyLWqWjcd18+abap2Tl8eIPf/DI5/u4lHqdxl7OrJ7anbkj2uHiICOVwrzc06QOj3TzB+DldcfKtQ1jXr6B97ac5S8f7uLYpTQ8nOx4++H2fDYplPoS5E4IUZaWA29s5fXbG7Dh76VOuW/l7c6ap3oQ6O1OYkYuYz7dw+YTCcUTZV+DLx+EI19pFwmGvw+BQ0uca+muaFbv10Ysn+jVrFKLJEQx9s4wdhWEjNZG6Nc8CQeXmUxa19WBr6d2o0OTOqRd1/PYigO8vek0+UU7zCgFB5bCZwMg+yr4ddRmndg7lzjXxuMJ7I++hqOdDS8OK3kxS4gi0pkXtYoxon1MapnplFJ8fzCOAe9u59uD2heGR7r5s2lWH8Ja1KvqbApxx/4xJIgG7o5EJWfxyfYLZaaNOJvEfR/s5IPfzpFvUAxp583W5/oyunMTCbIjhCifrlNv7Pt+4DNYfh+k/Wkyqa+nM99NC6Nr07pk5Obz1y8P8bfVkVzNzIXk8/D5IIjZpU2tn/AddH6sxDlW7Y3hXz9rUfSfHdhK2mRR9Wzt4cEl0OVJQMHPs7Vb+uUSSeu4OPDdtO5M7B4AwEfhF3h06T6SL1+Erx6GDc+BPlsLIvnIGnAqGZ0+R1/AW7+eAmBan+Y0qlOysy9EEZ1SpSxyMgPp6el4enqSlpaGh4dsxSDu3vnEDAa9twMnext+mtmLVoXT7m92KCaFBRtPG9cdB3q78+aDwXRuWrdEWiHM0c9/xDPz60gcbG34dVZvWjRwK/b8haRM/v3zScLPaFGo67k68MbIYO4L8ZFOvJmz1nbRWstVq5zdBGunQk4auNSDUUug5SCTSXP0Bby/9Syf7YjCTWUy1Xk70+x+xkGfru2zPeFb8G5b4rjvDsbxwg9/ADC9bwteHBoon1mi+igF2/4FO9/Vfrdz0i5m9ZwNriUvKq0/Gs9/1myjd8F+ZtuvoQ6ZKFtHdIPmartC2JQcU90ffY2X1x3jXGIm3h6OhP+9n8wEraXK2y5KZ17UKgaDovfCcC6lavtwDwv24en+LQn0cefX4wks2xXNkcKt65ztbZk1qBWP92qGva1MYhGWQynFYysOsP1MEmHN6/H11G5cSc/lcGwKO88l8/3BOPINCjsbHVN6NOVvA1vh6Wxf09kW5WCt7aK1lqvWSbmoRaC/fFT73TsYQh6G4Iegjn/xtGmXSNryHq7Hv8IFrU0+ZRvI750/oG+ndrRs6IZOp0NfYCAqKYsdZ5N469dTKAWP9WzKq8PbSkde1IzonVqnPm6f9ruDG7ToD+5+4O4D7r5w7QKc3QgJx4yHHTM05f90z9AzrCeP9WxGA/cbS9lSsvKY9+spvjuozWqp5+rAh+M70qNl/WotmjAfNd6Zv3jxIv/617/Ytm0bCQkJ+Pn58eijj/Lyyy/j4OBw+xMgjbuoGheSMnl74xk23rRWr46LPanZegAc7GwY2cGPZwe1orGXBNURlinuWjb3vh9Bjt5AfTdHkjOLr2Md1KYhL93Xhua3jNoL82at7aK1lqtW0ufA5pfh8BdQcNM2dN4hgIKcdG30Pjdd+x1IdmnJ/PQh/JjfjXy0UcjmDVxxtrfl3JVM8orWHAMTuvnz5gPB0pEXNUspOL9V69QXXbwySYehcReOefbnhdhunEm6sZuSo50N7k72eDjZkZyZS3pOPgDju/ozZ2gQni5ykb02q/HO/MaNG/n2228ZP348LVu25Pjx40ydOpWJEyfyzjvvlOsc0riLqnT2SgYfhZ/np6PxGBTUd3NkYvcAHunuL4G/hFX4NOIC8389DYCNTtsiKjTAi2HBPnK130JZa7toreWq1a6nwMn1cOx7uLiLoo57MU17Q89noeUgrmXr2XryChtPJLDrXHKxDrybox1BPu4MaNOQ6X1ayBZdwnwoBVHbIfkcZMRr6+gzLmtLTVoPgZb3GqfgGwyKLaeu8HH4eY7+mVbiVIHe7rw1KpjQAFnWKcygM2/K22+/zSeffEJUVFS50kvjLqpD7NVsYq9l06WZF452trc/QAgLYTAoNp9MwMPZng6N6+Aqe8VbPGttF621XKJQ2iWIPwwOrtre9E4e4FzX5DpjgIwcPb+fTwZ0tPX1oLGXs3TghVVJy9aTnqMnIyefzNx8DEoRGuAlyzqFUXnbxWr9ZpeWlkbduqVfbcrNzSU398ZU0PT0UvYgFaIS+ddzkT1qhVWysdExNNi3prMhLMibb77Jhg0bOHLkCA4ODqSmpt72GKUUr7/+OkuWLCElJYVu3brx0Ucf0a5du6rPsLAMno20Wzm5O9nLZ5ewap4u9jKNXlSKarv8c+HCBT788EOmT59eapp58+bh6elpvDVp0qS6sieEEELUenl5eYwePZoZM2aU+5iFCxfy3nvvsWjRIg4cOICPjw/33nsvGRkZVZhTIYQQQlS4Mz937lx0Ol2Zt4MHDxY7Jj4+nqFDhzJ69GiefPLJUs/9z3/+k7S0NOMtLi6u4iUSQgghxB15/fXXmT17NiEhIeVKr5TiP//5Dy+//DKjRo0iODiYlStXkp2dzddff13FuRVCCCFqtwpPs585cybjxo0rM03Tpk2N9+Pj4+nfvz9hYWEsWbKkzOMcHR1xdJTAY0IIIYQliI6OJiEhgcGDBxsfc3R0pG/fvuzevZtp06aZPE6W1QkhhBB3r8Kd+fr161O/fvmiIF+6dIn+/fsTGhrK8uXLsbGRoA5CCCGEtUhI0Lb49Pb2Lva4t7c3MTExpR43b948Xn/99SrNmxBCCGHtqqx3HR8fT79+/WjSpAnvvPMOSUlJJCQkGBt+IYQQQlS9O1keV1G37vmtlCpzH3BZVieEEELcvSqLZr9582bOnz/P+fPnady4cbHnqnE3PCGEEKJWq+jyuIrw8fEBtBF6X98b0ccTExNLjNbfTJbVCSGEEHevyjrzU6ZMYcqUKXd1jqJOv6ylE0IIIW60hxW5KF6R5XEV1axZM3x8fNiyZQsdO3YEtIj4ERERLFiwoNznkfZeCCGEuKG87X217jNfUUXb2sgWdUIIIcQNGRkZeHp6Vvp5Y2NjuXbtGrGxsRQUFHDkyBEAWrZsiZubGwBBQUHMmzePBx98EJ1Ox6xZs3jrrbdo1aoVrVq14q233sLFxYUJEyZUqDwg7b0QQghxs9u192bdmffz8yMuLg53d/cy195VRHp6Ok2aNCEuLg4PD49KOWdNsaaygJTHnFlTWcC6ymNNZQEpz+0opcjIyMDPz68SclfSq6++ysqVK42/F422h4eH069fPwDOnDlDWlqaMc0LL7zA9evXeeqpp0hJSaFbt25s3rwZd3f3cr9uZbf38n9kvqypLCDlMWfWVBawrvJYU1mgaspT3vberDvzNjY2JdbbVxYPDw+r+OcB6yoLSHnMmTWVBayrPNZUFpDylKUqRuSLrFixghUrVpSZ5tYpfzqdjrlz5zJ37tw7ft2qau/l/8h8WVNZQMpjzqypLGBd5bGmskDll6c87b3sFSeEEEIIIYQQQlgY6cwLIYQQQgghhBAWptZ15h0dHXnttdesYkscayoLSHnMmTWVBayrPNZUFpDyiMphbX93ayqPNZUFpDzmzJrKAtZVHmsqC9RseXRKNn0XQgghhBBCCCEsSq0bmRdCCCGEEEIIISyddOaFEEIIIYQQQggLI515IYQQQgghhBDCwkhnXgghhBBCCCGEsDDSmRdCCCGEEEIIISyMVXbmP/74Y5o1a4aTkxOhoaHs3LmzzPQRERGEhobi5ORE8+bN+fTTT6spp6WbN28eXbp0wd3dnYYNG/LAAw9w5syZMo/Zvn07Op2uxO306dPVlOvSzZ07t0S+fHx8yjzGHOulSNOmTU3+rZ9++mmT6c2pbnbs2MFf/vIX/Pz80Ol0/Pjjj8WeV0oxd+5c/Pz8cHZ2pl+/fpw4ceK2512zZg1t27bF0dGRtm3bsm7duioqQXFllUev1/Piiy8SEhKCq6srfn5+TJo0ifj4+DLPuWLFCpP1lZOTU2NlAZgyZUqJPHXv3v225zXHugFM/o11Oh1vv/12qeesqbopz2eypb13LJ01tPVgXe29tPXmVS/W1N5bU1sP0t5Le1959WN1nflvv/2WWbNm8fLLLxMZGUnv3r0ZNmwYsbGxJtNHR0dz33330bt3byIjI3nppZd45plnWLNmTTXnvLiIiAiefvpp9u7dy5YtW8jPz2fw4MFkZWXd9tgzZ85w+fJl461Vq1bVkOPba9euXbF8HTt2rNS05lovRQ4cOFCsLFu2bAFg9OjRZR5nDnWTlZVFhw4dWLRokcnnFy5cyHvvvceiRYs4cOAAPj4+3HvvvWRkZJR6zj179jB27FgmTpzI0aNHmThxImPGjGHfvn1VVQyjssqTnZ3N4cOHeeWVVzh8+DBr167l7NmzjBgx4rbn9fDwKFZXly9fxsnJqSqKYHS7ugEYOnRosTz98ssvZZ7TXOsGKPH3XbZsGTqdjoceeqjM89ZE3ZTnM9nS3juWzFraerC+9l7aevOpF2tq762prQdp76W9r8T6UVama9euavr06cUeCwoKUnPmzDGZ/oUXXlBBQUHFHps2bZrq3r17leXxTiQmJipARURElJomPDxcASolJaX6MlZOr732murQoUO501tKvRR59tlnVYsWLZTBYDD5vLnWDaDWrVtn/N1gMCgfHx81f/5842M5OTnK09NTffrpp6WeZ8yYMWro0KHFHhsyZIgaN25cpee5LLeWx5T9+/crQMXExJSaZvny5crT07NyM1dBpsoyefJkNXLkyAqdx5LqZuTIkWrAgAFlpjGHulGq5Geypb93LI21tvVKWXZ7L229edaLUtbV3ltTW6+UtPelMZf6Mff23qpG5vPy8jh06BCDBw8u9vjgwYPZvXu3yWP27NlTIv2QIUM4ePAger2+yvJaUWlpaQDUrVv3tmk7duyIr68vAwcOJDw8vKqzVm7nzp3Dz8+PZs2aMW7cOKKiokpNayn1Atr/3apVq3j88cfR6XRlpjXXuikSHR1NQkJCsb+9o6Mjffv2LfU9BKXXV1nH1JS0tDR0Oh116tQpM11mZiYBAQE0btyY4cOHExkZWT0ZvI3t27fTsGFDWrduzdSpU0lMTCwzvaXUzZUrV9iwYQNPPPHEbdOaQ93c+plcG9475sKa23qw/PZe2nrzrJdbWftnlqW39SDtPZhH/Zh7e29Vnfnk5GQKCgrw9vYu9ri3tzcJCQkmj0lISDCZPj8/n+Tk5CrLa0UopXjuuefo1asXwcHBpabz9fVlyZIlrFmzhrVr1xIYGMjAgQPZsWNHNebWtG7duvHFF1+wadMmPvvsMxISEujRowdXr141md4S6qXIjz/+SGpqKlOmTCk1jTnXzc2K3icVeQ8VHVfRY2pCTk4Oc+bMYcKECXh4eJSaLigoiBUrVrB+/XpWr16Nk5MTPXv25Ny5c9WY25KGDRvGV199xbZt23j33Xc5cOAAAwYMIDc3t9RjLKVuVq5cibu7O6NGjSoznTnUjanPZGt/75gTa23rwfLbe2nrzbNeTLHmzyxLb+tB2nswj/qxhPbe7q6ONlO3XjFVSpV5FdVUelOP15SZM2fyxx9/sGvXrjLTBQYGEhgYaPw9LCyMuLg43nnnHfr06VPV2SzTsGHDjPdDQkIICwujRYsWrFy5kueee87kMeZeL0WWLl3KsGHD8PPzKzWNOdeNKRV9D93pMdVJr9czbtw4DAYDH3/8cZlpu3fvXizQTM+ePenUqRMffvghH3zwQVVntVRjx4413g8ODqZz584EBASwYcOGMhtFc68bgGXLlvHII4/cdi2cOdRNWZ/J1vjeMVfW1taD5bf30tabZ72Uxdo+s6yhrQdp78E86scS2nurGpmvX78+tra2Ja5wJCYmlrgSUsTHx8dkejs7O+rVq1dleS2vv/3tb6xfv57w8HAaN25c4eO7d+9uFlcYb+Xq6kpISEipeTP3eikSExPD1q1befLJJyt8rDnWTVHU4Yq8h4qOq+gx1Umv1zNmzBiio6PZsmVLmVfqTbGxsaFLly5mV1++vr4EBASUmS9zrxuAnTt3cubMmTt6H1V33ZT2mWyt7x1zZI1tPVhney9tvXnWC1jnZ5a1tvUg7T1Ie18aq+rMOzg4EBoaaow2WmTLli306NHD5DFhYWEl0m/evJnOnTtjb29fZXm9HaUUM2fOZO3atWzbto1mzZrd0XkiIyPx9fWt5NzdvdzcXE6dOlVq3sy1Xm61fPlyGjZsyP3331/hY82xbpo1a4aPj0+xv31eXh4RERGlvoeg9Poq65jqUtS4nzt3jq1bt97RF0SlFEeOHDG7+rp69SpxcXFl5suc66bI0qVLCQ0NpUOHDhU+trrq5nafydb43jFX1tTWg3W399LWm2e9gPV9ZllzWw/S3oO092Vl2Kp88803yt7eXi1dulSdPHlSzZo1S7m6uqqLFy8qpZSaM2eOmjhxojF9VFSUcnFxUbNnz1YnT55US5cuVfb29uqHH36oqSIopZSaMWOG8vT0VNu3b1eXL1823rKzs41pbi3L+++/r9atW6fOnj2rjh8/rubMmaMAtWbNmpooQjHPP/+82r59u4qKilJ79+5Vw4cPV+7u7hZXLzcrKChQ/v7+6sUXXyzxnDnXTUZGhoqMjFSRkZEKUO+9956KjIw0RnydP3++8vT0VGvXrlXHjh1T48ePV76+vio9Pd14jokTJxaLGv37778rW1tbNX/+fHXq1Ck1f/58ZWdnp/bu3Vuj5dHr9WrEiBGqcePG6siRI8XeS7m5uaWWZ+7cuWrjxo3qwoULKjIyUj322GPKzs5O7du3r8bKkpGRoZ5//nm1e/duFR0drcLDw1VYWJhq1KiRRdZNkbS0NOXi4qI++eQTk+cwl7opz2eypb13LJm1tPVKWVd7L229edWLNbX31tTW36480t5rpL0vH6vrzCul1EcffaQCAgKUg4OD6tSpU7HtXSZPnqz69u1bLP327dtVx44dlYODg2ratGmp/2TVCTB5W758uTHNrWVZsGCBatGihXJyclJeXl6qV69easOGDdWfeRPGjh2rfH19lb29vfLz81OjRo1SJ06cMD5vKfVys02bNilAnTlzpsRz5lw3RVvn3HqbPHmyUkrbcuO1115TPj4+ytHRUfXp00cdO3as2Dn69u1rTF/k+++/V4GBgcre3l4FBQVV25eXssoTHR1d6nspPDy81PLMmjVL+fv7KwcHB9WgQQM1ePBgtXv37hotS3Z2tho8eLBq0KCBsre3V/7+/mry5MkqNja22DkspW6KLF68WDk7O6vU1FST5zCXuinPZ7KlvXcsnTW09UpZV3svbb151Ys1tffW1NbfrjzS3mukvS8fXWGmhRBCCCGEEEIIYSGsas28EEIIIYQQQghRG0hnXgghhBBCCCGEsDDSmRdCCCGEEEIIISyMdOaFEEIIIYQQQggLI515IYQQQgghhBDCwkhnXgghhBBCCCGEsDDSmRdCCCGEEEIIISyMdOaFEEIIIYQQQggLI515IYQQQgghhBDCwkhnXgghhBBCCCGEsDDSmRdCCCGEEEIIISzM/wPaHri0rSz6CgAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "pars=res.x\n", + "\n", + "ode_est = common_models.FitzHugh([('a', pars[0]), ('b', pars[1]), ('c', pars[2])])\n", "\n", - "Then we can find both states as target at the same time.\n" + "x0_est = [pars[3], pars[4]]\n", + "ode_est.initial_values = (x0_est, t[0])\n", + "\n", + "solution_est = ode_est.integrate(t[1::])\n", + "\n", + "f, axarr = plt.subplots(1,2, layout='constrained', figsize=(10, 2.5))\n", + "\n", + "axarr[0].plot(t, solution[:,0], color='C0')\n", + "axarr[0].plot(t, solution_est[:,0], color='C1')\n", + "axarr[1].plot(t, solution[:,1], color='C0')\n", + "axarr[1].plot(t, solution_est[:,1], color='C1');" + ] + }, + { + "cell_type": "markdown", + "id": "af2b3afa", + "metadata": {}, + "source": [ + "Assume we know both states:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "869a5561", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH\n", + " success: True\n", + " status: 0\n", + " fun: 3.9102434290500006e-10\n", + " x: [ 2.000e-01 2.000e-01 3.000e+00 -1.000e+00 1.000e+00]\n", + " nit: 50\n", + " jac: [ 5.228e-04 8.604e-05 2.292e-04 -1.938e-04 1.487e-04]\n", + " nfev: 67\n", + " njev: 67\n", + " hess_inv: <5x5 LbfgsInvHessProduct with dtype=float64>\n" + ] + } + ], "source": [ - "objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::,:], ['V','R'])\n", + "objFH = SquareLoss(theta, ode,\n", + " t0=t[0], x0=x0,\n", + " t=t[1::], y=solution[1::,:],\n", + " state_name=['V','R'])\n", "\n", "res = scipy.optimize.minimize(fun=objFH.costIV, \n", " jac=objFH.sensitivityIV, \n", @@ -212,7 +289,31 @@ " bounds=boxBounds, \n", " method='L-BFGS-B')\n", "\n", - "print(res)\n" + "print(res)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2413973", + "metadata": {}, + "outputs": [], + "source": [ + "pars=res.x\n", + "\n", + "ode_est = common_models.FitzHugh([('a', pars[0]), ('b', pars[1]), ('c', pars[2])])\n", + "\n", + "x0_est = [pars[3], pars[4]]\n", + "ode_est.initial_values = (x0_est, t[0])\n", + "\n", + "solution_est = ode_est.integrate(t[1::])\n", + "\n", + "f, axarr = plt.subplots(1,2, layout='constrained', figsize=(10, 2.5))\n", + "\n", + "axarr[0].plot(t, solution[:,0], color='C0')\n", + "axarr[0].plot(t, solution_est[:,0], color='C1')\n", + "axarr[1].plot(t, solution[:,1], color='C0')\n", + "axarr[1].plot(t, solution_est[:,1], color='C1')" ] }, { @@ -220,20 +321,108 @@ "id": "3c045544", "metadata": {}, "source": [ - "\n", "See the difference between the two estimates with the latter method; both states\n", - "were used, yielding superior estimates. Note that only the forward\n", + "were used, yielding superior estimates.\n", + "Note that only the forward\n", "sensitivity method is implemented when estimating the initial value, and\n", "it is assumed that the starting condition for all the states are\n", "unknown.\n", "\n", "The choice of algorithm here is the **L-BFGS-B** which is a better\n", - "choice because the parameter space of the FitzHugh is rough (i.e. large\n", - "second derivative) as well as being multimodal. This means that the\n", + "choice because the parameter space of the FitzHugh is rough. This means that the\n", "Hessian is not guaranteed to be positive definite and approximation\n", "using $J^{\\top}J$ is poor, with $J$ being the Jacobian of the objective\n", "function." ] + }, + { + "cell_type": "markdown", + "id": "886bf54a", + "metadata": {}, + "source": [ + "## Obtaining good initial values for parameters via Function Interpolation\n", + "\n", + "When we want to fit the model to data, one of the necessary steps is to supply the optimization procedure a good set of initial guess for the parameters $\\theta$.\n", + "This may be a challenge when we do have a good understanding of the process we are trying to model.\n", + "\n", + "A method to obtain such initial guess based on the collocation is available in this package.\n", + "A restriction is that data must be present for all states.\n", + "Demonstrate with previous example." + ] + }, + { + "cell_type": "markdown", + "id": "5150a1d6", + "metadata": {}, + "source": [ + "Below, we try to find the initial guess without supplying any further\n", + "information. The underlying method fits a cubic spline against the\n", + "observation and tries to minimize the difference between the first\n", + "derivative of the spline and the function of the ode. Varying degree of\n", + "smoothness penalty is applied to the spline and the best set of\n", + "parameters is the ones that yields the smallest total error, combining\n", + "both the fit of the spline against data and the spline against the ode.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "fb377637", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0.20048258 0.19918548 2.98409032]\n" + ] + } + ], + "source": [ + "from pygom import get_init\n", + "\n", + "theta, sInfo = get_init(solution[1::,:], t[1::], ode, theta=None, full_output=True)\n", + "\n", + "print(theta)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "ab55101a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: Solution found.\n", + " success: True\n", + " status: 0\n", + " fun: 0.06821816133192726\n", + " x: 9.734744556902422e-05\n", + " nit: 30\n", + " nfev: 30\n" + ] + } + ], + "source": [ + "print(sInfo)" + ] + }, + { + "cell_type": "markdown", + "id": "f6b7bf0c", + "metadata": {}, + "source": [ + "\n", + "As seen above, we have obtained a very good guess of the parameters, in\n", + "fact almost the same as the generating process. The information\n", + "regarding the smoothing factor shows that the amount of penalty used is\n", + "small, which is expected given that we use the solution of the ode as\n", + "observations." + ] } ], "metadata": { @@ -243,8 +432,16 @@ "name": "python3" }, "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", "name": "python", - "version": "3.9.15" + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" }, "vscode": { "interpreter": { diff --git a/docs/notebooks/paramfit/gradient.ipynb b/docs/notebooks/paramfit/gradient.ipynb index 90369963..be41e055 100644 --- a/docs/notebooks/paramfit/gradient.ipynb +++ b/docs/notebooks/paramfit/gradient.ipynb @@ -77,7 +77,7 @@ "\n", "import copy, time, numpy\n", "\n", - "Iode = common_models.SIR()\n", + "ode = common_models.SIR()\n", "\n", "paramEval = [('beta',0.5), ('gamma',1.0/3.0) ]\n", "\n", diff --git a/docs/notebooks/sir.ipynb b/docs/notebooks/sir.ipynb index f90e3e31..0611b915 100644 --- a/docs/notebooks/sir.ipynb +++ b/docs/notebooks/sir.ipynb @@ -4,19 +4,35 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Motivating Example: SIR Model\n", + "# Defining an ODE system\n", "\n", - "## Defining the model\n", + "There are 2 ways to encapsulate an ODE system.\n", "\n", - "First, we are going to go through an SIR model to show the functionality\n", - "of the package. The SIR model is defined by the following equations\n", + "We first demonstrate how to encapsulate the relevant equations in a class which will eventually be used to solve them.\n", + "\n", + "One useful feature of PyGom is the ability to define the system in a variety of intuitive ways.\n", + "\n", + "In compartmental models, where the states represent counts of certain categories, the changes in these quantities\n", + "\n", + "## Example: SIR model\n", + "\n", + "Here we use a Susceptible-Infected-Removed epidemic model (an SIR model, for short) to demonstrate the different ways to specify a system.\n", + "The rates of change of each compartment are defined by the following equations\n", + "\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d} S}{\\mathrm{d} t} &= -\\beta SI \\\\\n", + "\\frac{\\mathrm{d} I}{\\mathrm{d} t} &= \\beta SI- \\gamma I \\\\\n", + "\\frac{\\mathrm{d} R}{\\mathrm{d} t} &= \\gamma I.\n", + "\\end{aligned}$$\n", + "\n", + "However, it is also true that this is the result of two transitions:\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dS}{dt} &= -\\beta SI \\\\\n", - "\\frac{dI}{dt} &= \\beta SI- \\gamma I \\\\\n", - "\\frac{dR}{dt} &= \\gamma I.\n", + "S \\rightarrow I &= \\beta SI \\\\\n", + "I \\rightarrow R &= \\gamma I\n", "\\end{aligned}$$\n", "\n", + "\n", "We can set this up as follows:" ] }, @@ -25,12 +41,12 @@ "id": "586834ab", "metadata": {}, "source": [ - "1. import the classes required to define the transitions" + "1. Import the classes required to define the transitions" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "4c80a36a", "metadata": {}, "outputs": [], @@ -43,12 +59,12 @@ "id": "0ec4c9d0", "metadata": {}, "source": [ - "2. define our states, in this case the population states of **S**usceptible, **I**nfected and **R**emoved" + "2. Define our states, in this case the population states of **S**usceptible, **I**nfected and **R**emoved" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "3ce016f2", "metadata": {}, "outputs": [], @@ -61,12 +77,12 @@ "id": "021a1927", "metadata": {}, "source": [ - "3. define the set of parameters for our model, here there are only two" + "3. Define the set of parameters for our model" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "441e2287", "metadata": {}, "outputs": [], @@ -79,33 +95,43 @@ "id": "dfd736b2", "metadata": {}, "source": [ - "4. specify the transitions of the modelled states; this will form our ODE system" + "4. \n", + " i. Specify the transitions of the modelled states; this will form our ODE system" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "b5f80ab0", "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'Transition' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[4], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m odeList \u001b[39m=\u001b[39m [\n\u001b[1;32m----> 2\u001b[0m Transition(origin\u001b[39m=\u001b[39m\u001b[39m'\u001b[39m\u001b[39mS\u001b[39m\u001b[39m'\u001b[39m, equation\u001b[39m=\u001b[39m\u001b[39m'\u001b[39m\u001b[39m-beta*S*I\u001b[39m\u001b[39m'\u001b[39m, transition_type\u001b[39m=\u001b[39mTransitionType\u001b[39m.\u001b[39mODE),\n\u001b[0;32m 3\u001b[0m Transition(origin\u001b[39m=\u001b[39m\u001b[39m'\u001b[39m\u001b[39mI\u001b[39m\u001b[39m'\u001b[39m,equation\u001b[39m=\u001b[39m\u001b[39m'\u001b[39m\u001b[39mbeta*S*I - gamma*I\u001b[39m\u001b[39m'\u001b[39m, transition_type\u001b[39m=\u001b[39mTransitionType\u001b[39m.\u001b[39mODE),\n\u001b[0;32m 4\u001b[0m Transition(origin\u001b[39m=\u001b[39m\u001b[39m'\u001b[39m\u001b[39mR\u001b[39m\u001b[39m'\u001b[39m, equation\u001b[39m=\u001b[39m\u001b[39m'\u001b[39m\u001b[39mgamma*I\u001b[39m\u001b[39m'\u001b[39m, transition_type\u001b[39m=\u001b[39mTransitionType\u001b[39m.\u001b[39mODE) \n\u001b[0;32m 5\u001b[0m ]\n", - "\u001b[1;31mNameError\u001b[0m: name 'Transition' is not defined" - ] - } - ], + "outputs": [], "source": [ "odeList = [\n", " Transition(origin='S', equation='-beta*S*I', transition_type=TransitionType.ODE),\n", " Transition(origin='I',equation='beta*S*I - gamma*I', transition_type=TransitionType.ODE),\n", " Transition(origin='R', equation='gamma*I', transition_type=TransitionType.ODE) \n", - " ]" + "]" + ] + }, + { + "cell_type": "markdown", + "id": "18c7fbac", + "metadata": {}, + "source": [ + "ii. Specify the transitions of the modelled states; this will form our ODE system" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a2761de1", + "metadata": {}, + "outputs": [], + "source": [ + "odeList2 = [\n", + " Transition(origin='S', destination='I', equation='beta*S*I', transition_type=TransitionType.T),\n", + " Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)\n", + "]" ] }, { @@ -124,7 +150,7 @@ "metadata": {}, "source": [ "\n", - "5. import the ode module" + "5. Depending on if we want to run deterministic or stochastic solver, we create a class. For this case let's try depterministic. We import the relevant class." ] }, { @@ -142,7 +168,7 @@ "id": "477d6f84", "metadata": {}, "source": [ - "6. initialize the model, which constructs our ODE system from all the information we have provided" + "6. And then initialize the model, which constructs our ODE system from all the information we have provided" ] }, { diff --git a/docs/notebooks/stochastic.ipynb b/docs/notebooks/stochastic.ipynb deleted file mode 100644 index f037f47b..00000000 --- a/docs/notebooks/stochastic.ipynb +++ /dev/null @@ -1,617 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Stochastic representation of ODEs\n", - "\n", - "There are multiple interpretations of the stochasticity of a deterministic\n", - "ODE. We have implemented two of the most common interpretations; when the\n", - "parameters are realizations of some underlying distribution, and when we\n", - "have a so called chemical master equation where each transition\n", - "represent a jump. Again, we use the standard SIR example as previously\n", - "seen in {doc}`sir`." - ] - }, - { - "cell_type": "markdown", - "id": "d945f972", - "metadata": {}, - "source": [ - "#TODO add comment about using a density or frequency formulation (use of population size) - currently unexplained" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "3f44792d", - "metadata": {}, - "outputs": [], - "source": [ - "from pygom import SimulateOde, Transition, TransitionType\n", - "\n", - "import matplotlib.pyplot as plt\n", - "\n", - "import numpy as np\n", - "\n", - "# initial conditions\n", - "Ix0 = [1, 1.27e-6, 0]\n", - "\n", - "# time period\n", - "t = np.linspace(0, 150, 100)\n", - "\n", - "stateList = ['S', 'I', 'R']\n", - "\n", - "paramList = ['beta', 'gamma']\n", - "\n", - "transitionList = [Transition(origin='S', destination='I', equation='beta*S*I', transition_type=TransitionType.T), \n", - " Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)]\n", - "\n", - "# create the ODEs\n", - "odeS = SimulateOde(stateList, paramList, transition=transitionList)\n", - "\n", - "# assign parameter values\n", - "odeS.parameters = [0.5, 1.0/3.0]\n", - "\n", - "# assign initial values\n", - "odeS.initial_values = (Ix0, t[0])\n", - "\n", - "# solve deterministic solution\n", - "solutionReference = odeS.integrate(t[1::], full_output=False)" - ] - }, - { - "cell_type": "markdown", - "id": "0e516f09", - "metadata": {}, - "source": [ - "\n", - "## Stochastic Parameters\n", - "\n", - "In our first implementation, we assume that the parameters follow some\n", - "underlying distribution. Given that both $\\beta$ and $\\gamma$ in our SIR\n", - "model has to be non-negative, it seems natural to use a Gamma\n", - "distribution. We make use of the familiar syntax from\n", - "[R](http://www.r-project.org/) to define our distribution.\n", - "Unfortunately, we have to define it via a tuple, where the first item is the\n", - "function handle (name) and the second the parameters. \n", - "\n", - "```{note}\n", - "The parameters can be defined as either a dictionary or as the same sequence\n", - "as [R](http://www.r-project.org/) (without specifying the arguments), which for the [Gamma distribution](https://stat.ethz.ch/R-manual/R-devel/library/stats/html/GammaDist.html) is the shape followed by the rate.\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "a3e9bc81", - "metadata": {}, - "outputs": [], - "source": [ - "from pygom.utilR import rgamma\n", - "\n", - "d = dict()\n", - "\n", - "# E(X) = 0.5 = shape * scale = shape / rate \n", - "d['beta'] = (rgamma,{'shape':100.0, 'rate':200.0})\n", - "\n", - "# E(X) = 1.0/3.0 = shape / rate\n", - "d['gamma'] = (rgamma,(100.0, 300.0))\n", - "\n", - "odeS.parameters = d\n", - "\n", - "Ymean, Yall = odeS.simulate_param(t[1::], 10, full_output=True)" - ] - }, - { - "cell_type": "markdown", - "id": "2221479d", - "metadata": {}, - "source": [ - "```{note}\n", - "Note that a message may be printed above where PyGOM is trying to connect to an\n", - "mpi backend, as our module has the capability to compute in parallel\n", - "using the IPython. We have simulated a total of 10 different solutions\n", - "using different parameters, the plots can be seen below.\n", - "```\n" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "8849566b", - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "f, axarr = plt.subplots(1,3, layout='constrained')\n", - "\n", - "#TODO tidy up plots\n", - "for solution in Yall: \n", - " axarr[0].plot(t, solution[:,0]) \n", - " axarr[1].plot(t, solution[:,1]) \n", - " axarr[2].plot(t, solution[:,2])\n", - "\n", - "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_title(state)\n", - "\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "1fd28659", - "metadata": {}, - "source": [ - "\n", - "We then see how the expected results, using the sample average of the\n", - "simulations\n", - "\n", - "$$\\tilde{x}(T) = \\mathbb{E}\\left[ \\int_{t_{0}}^{T} f(\\theta,x,t) dt \\right]$$\n", - "\n", - "differs from the reference solution\n", - "\n", - "$$\\hat{x}(T) = \\int_{t_{0}}^{T} f(\\mathbb{E}\\left[ \\theta \\right],x,t) dt$$ " - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "4e6f4164", - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAosAAAHrCAYAAACn9tfQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAACG5klEQVR4nO3de3xU9Zk/8M+ZSWYm9wu5DIFAQNCgIGAQiFKtmm6otUpFKqxblKX4W2usNV2ruIpWu6W1SvFCl9XWWrdSLa2lVi0tjaJVwh1UroKgXMLkSjK5zSUz5/fHzDmTSCaZy7nM5fN+vea16+TMzBmak3nmeb7P8xVEURRBRERERDQIg94nQERERESxi8EiEREREQXFYJGIiIiIgmKwSERERERBMVgkIiIioqAYLBIRERFRUAwWiYiIiCgoBotEREREFBSDRSIiIiIKisEiEREREQXFYJGC+vjjj3HTTTdh7NixsFgsGDVqFL7yla/gmWee0fvUiOLeiy++CEEQsHPnTr1PhShuSdeRdEtJScGoUaNw22234fTp03qfXsJI0fsEKDZt2bIFV111FcaMGYNly5bBarXi5MmT2Lp1K5566incddddep8iERERAODRRx/FuHHj4HA4sHXrVrz44ot4//33sW/fPlgsFr1PL+4xWKRB/fd//zdycnKwY8cO5ObmDvhZU1OTPidFREQ0iK9+9auYMWMGAODb3/42CgoK8NOf/hSvv/46vvnNb+p8dvGPZWga1KeffoqLLrronEARAIqKirQ/ISIiohB96UtfAuD7LKPoMVikQY0dOxa7du3Cvn379D4VIiKisHz22WcAgLy8PH1PJEEwWKRB/ed//id6enowbdo0XHbZZbjvvvvw97//HW63W+9TIyIiGqCjowMtLS04deoU/vjHP+KHP/whzGYzrrvuOr1PLSEwWKRBfeUrX0F9fT2uv/56fPjhh3j88cdRXV2NUaNG4fXXX9f79IiIiGRVVVUoLCxEaWkpbrrpJmRkZOD111/H6NGj9T61hMBgkYK69NJL8dprr+Hs2bPYvn07li9fjs7OTtx00004cOCA3qdHREQEAFizZg02bdqEP/zhD7j22mvR0tICs9ms92klDAaLNCyTyYRLL70UP/7xj/E///M/cLvdWL9+vd6nRUREBACYOXMmqqqqMH/+fLz++uuYPHky/vVf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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "f, axarr = plt.subplots(1,3, layout='constrained')\n", - "\n", - "for i in range(3): \n", - " axarr[i].plot(t, Ymean[:,i] - solutionReference[:,i])\n", - " axarr[i].set_title(stateList[i])\n", - "\n", - "plt.show()\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "ee4d496d", - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "data": { - "image/png": "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Jqnzk4QQnbNXJVsjo9l+vILBaXHEGSO7OckFhjglMGyUAhRveO+995g/fz5Lly5l0qRJPP/888yYMYP9+/eTmpra7vjevXvz8MMPM3ToUPR6PR9//DFz584lNTXVMT0aKjQaDeeffz7nn38+CxcupF+/fnz00UfMnz+fb775hj//+c/MmjULgKKiIo8VPhQWFnLq1CkyMzMB+Pbbb9FqtQwZMqTNcc1NTQwfnIvBoOf0iRNces70dmf27dvHmTNneOqpp8jOzgZgy5Yt7Y67+eabeeSRR9i6dSsffPABS5cudfxs7NixFBcXExERQU5OjtOv7cyZM+zfv59ly5Zx4YUXAsq0dGtDhgzh73//OyaTyRHcfvfdd22OGTt2LB9++CE5OTlERPguXJOq5BA1MC0WCzpMOvtieSlAEcJ99qnkfx+o4dpXNjJ20Vp+8/4Omi2uZ0A6JAUoXvXss89y9913M3fuXIYPH87SpUuJjo5m+fLlHR4/bdo0rrnmGoYNG8aAAQO47777GD16dLsP92C3adMmnnzySbZs2UJhYSErVqygrKyMYcOGATBo0CDeeust9u7dy6ZNm7jllluIivLMzj9Go5Hbb7+dHTt28NVXX/HLX/6SG264oe00MtDc3ERcbAy//NmdzJ8/nzfffJPDhw+zbds2XnzxRd58880OH79v377o9XpefPFFjhw5wqpVq1i0aFG743JycpgyZQp33nknFouFq666yvGz6dOnM3nyZGbPns1nn33GsWPH2LBhAw8//HCHQaaqV69eJCUl8dprr3Ho0CH++9//Mn/+/DbH3HzzzVitVn7605+yd+9ePv30U5555hmgJcN67733UlFRwU033cR3333H4cOH+fTTT5k7dy4Wewsfb5DAMEQNsq8zrNHYP3CkAEUIt1lMSmB4oMKKVgNNFhsfbD3B618f9cwTSC9DrzGbzWzdupXp06c77tNqtUyfPp2NGzd2e77NZmPdunXs37+fiy66qNPnsFqtWCwWxyUYxMfH8+WXXzJr1iwGDx7MI488wpIlS7j88ssBeP311zl79ixjx47l1ltv5Ze//GWHGVZ3DBw4kB/96EfMmjWLyy67jNGjR/PnP/+53XGWZqW59aO/+w2PPvooixcvZtiwYcycOZNPPvmE/v37d/j4KSkpvPHGG7z//vsMHz6cp556yhF4neuW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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "f, axarr = plt.subplots(1,3, layout='constrained', sharey=False)\n", - "\n", - "for i in range(3): \n", - " axarr[i].plot(t, Ymean[:,i], label='sample average')\n", - " axarr[i].plot(t, solutionReference[:,i], label='reference')\n", - " axarr[i].set_title(stateList[i])\n", - "\n", - "axarr[2].legend()\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "aa230d7f", - "metadata": {}, - "source": [ - "The difference between the deterministic reference and averaged solutions is relatively large, especially for the $S$ state. \n", - "We can decrease this difference as we increase the number of simulations, and also by using more sophisticated sampling methods for the generation of random\n", - "variables." - ] - }, - { - "cell_type": "markdown", - "id": "39d66f12", - "metadata": {}, - "source": [ - "```{tip}\n", - "In addition to using the built-in functions to represent stochasticity,\n", - "we can also use standard frozen distributions from scipy. Note that it\n", - "must be a frozen distribution as that is the only for the parameters of\n", - "the distributions to propagate through the model.\n", - "```\n" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "b8a806bc", - "metadata": {}, - "outputs": [], - "source": [ - "import scipy.stats as st\n", - "\n", - "d = dict()\n", - "\n", - "d['beta'] = st.gamma(a=100.0, scale=1.0/200.0)\n", - "\n", - "d['gamma'] = st.gamma(a=100.0, scale=1.0/300.0)\n", - "\n", - "odeS.parameters = d" - ] - }, - { - "cell_type": "markdown", - "id": "030d6487", - "metadata": {}, - "source": [ - "There may be scenarios where only some of the parameters are\n", - "stochastic. Let's say that the $\\gamma$ parameter is fixed at $1/3$,\n", - "then we can replace the distribution information with a scalar. A quick\n", - "visual inspection at the resulting plot suggests that the system of ODEs\n", - "potentially has less variation when compared to the case where both\n", - "parameters are stochastic." - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "fa0d6ee2", - "metadata": {}, - "outputs": [], - "source": [ - "d['gamma'] = 1.0/3.0\n", - "\n", - "odeS.parameters = d\n", - "\n", - "YmeanSingle, YallSingle = odeS.simulate_param(t[1::], 5, full_output=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "eb4e969a", - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "f, axarr = plt.subplots(1,3)\n", - "\n", - "for solution in YallSingle: \n", - " axarr[0].plot(t,solution[:,0]) \n", - " axarr[1].plot(t,solution[:,1]) \n", - " axarr[2].plot(t,solution[:,2])\n", - "\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "2f01a3d9", - "metadata": {}, - "source": [ - "## Continuous Markov Representation\n", - "\n", - "Another common method of introducing stochasticity into a set of ODEs is\n", - "by assuming each movement in the system is a result of a jump process.\n", - "More concretely, the probabilty of a move for transition $j$ is governed\n", - "by an exponential distribution such that\n", - "\n", - "$$\\Pr(\\text{process $j$ jump within time } \\tau) = \\lambda_{j} e^{-\\lambda_{j} \\tau},$$\n", - "\n", - "where $\\lambda_{j}$ is the rate of transition for process $j$ and $\\tau$\n", - "the time elapsed after current time $t$.\n", - "\n", - "Two of the commmon algorithms for the jump process have been\n", - "implemented for use during simulation; the reaction method [\\[Gillespie1977\\]]() and the $\\tau$-Leap method\n", - "[\\[Cao2006\\]](). The two change interactively depending on the size of the states." - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "a0a0bcbc", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "x0 = [2362206.0, 3.0, 0.0]\n", - "\n", - "stateList = ['S', 'I', 'R']\n", - "\n", - "paramList = ['beta', 'gamma', 'N']\n", - "\n", - "transitionList = [Transition(origin='S', destination='I', equation='beta*S*I/N', transition_type=TransitionType.T),\n", - " Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)\n", - " ]\n", - "\n", - "odeS = SimulateOde(stateList, paramList, transition=transitionList)\n", - "\n", - "odeS.parameters = [0.5, 1.0/3.0, x0[0]]\n", - "\n", - "odeS.initial_values = (x0, t[0])\n", - "\n", - "solutionReference = odeS.integrate(t[1::])\n", - "\n", - "simX, simT = odeS.simulate_jump(t[1:10], 10, full_output=True)\n", - "\n", - "f, axarr = plt.subplots(1, 3)\n", - "\n", - "for solution in simX: \n", - " axarr[0].plot(t[:9], solution[:,0])\n", - " axarr[1].plot(t[:9], solution[:,1]) \n", - " axarr[2].plot(t[:9], solution[:,2])\n", - "\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "e18e4fa7", - "metadata": {}, - "source": [ - "Above, we see 10 different simulations, again using the SIR model but\n", - "without standardization of the initial conditions (we include $N$ as a parameter in our model). \n", - "For demonstration purposes, we restrict our time\n", - "frame to be only the first 10 time points so that the individual changes or stochasticity\n", - "can be seen more clearly. If we use the same time frame as the one\n", - "used previously for the deterministic system (as shown below), the\n", - "trajectories are smoothed out and we no longer observe the *jumps*.\n", - "Looking at the raw trajectories of the ODEs below, we see that the\n", - "mean from a jump process is very different to the deterministic\n", - "solution. This occurs because the jump process above was able\n", - "to fully remove all the initial infected individuals before any new\n", - "ones occured." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "525a069b", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "simX,simT = odeS.simulate_jump(t, 5, full_output=True)\n", - "\n", - "simMean = np.mean(simX, axis=0)\n", - "\n", - "f, axarr = plt.subplots(1,3)\n", - "\n", - "for solution in simX: \n", - " axarr[0].plot(t, solution[:,0]) \n", - " axarr[1].plot(t, solution[:,1]) \n", - " axarr[2].plot(t, solution[:,2])\n", - "\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "fbef64f3", - "metadata": {}, - "source": [ - "\n", - "## Repeatable Simulation\n", - "\n", - "One of the possible uses of compartmental models is to generate\n", - "forecasts. Although most of the time the requirement would be to have\n", - "(at least point-wise) convergence in the limit, reproducibility is also\n", - "important. For both types of interpretation explained above, we have\n", - "given the package the capability to repeat the simulations by setting a\n", - "seed. When the assumption is that the parameters follows some sort of\n", - "distribution, we can set the seed which governs the global state of\n", - "the random number generator." - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "415cab81", - "metadata": {}, - "outputs": [], - "source": [ - "x0 = [2362206.0, 3.0, 0.0]\n", - "\n", - "odeS = SimulateOde(stateList, paramList, transition=transitionList)\n", - "\n", - "d = {'beta': st.gamma(a=100.0, scale=1.0/200.0), 'gamma':st.gamma(a=100.0, scale=1.0/300.0), 'N': x0[0]}\n", - "\n", - "odeS.parameters = d\n", - "\n", - "odeS.initial_values = (x0, t[0])\n", - "\n", - "Ymean, Yall = odeS.simulate_param(t[1::], 10, full_output=True)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "7a51e644", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Different in the simulations and the mean: (81103473.8935847, 52437230.37979218) \n", - "Different in the simulations and the mean using same seed: (0.0, 0.0) \n" - ] - } - ], - "source": [ - "\n", - "np.random.seed(1)\n", - "\n", - "Ymean1, Yall1 = odeS.simulate_param(t[1::], 10, full_output=True)\n", - "\n", - "np.random.seed(1)\n", - "\n", - "Ymean2, Yall2 = odeS.simulate_param(t[1::], 10, full_output=True)\n", - "\n", - "sim_diff = [np.linalg.norm(Yall[i] - yi) for i, yi in enumerate(Yall1)]\n", - "\n", - "sim_diff12 = [np.linalg.norm(Yall2[i] - yi) for i, yi in enumerate(Yall1)]\n", - "\n", - "print(\"Different in the simulations and the mean: (%s, %s) \" %(np.sum(sim_diff), np.sum(np.abs(Ymean1 - Ymean))))\n", - "\n", - "print(\"Different in the simulations and the mean using same seed: (%s, %s) \" % (np.sum(sim_diff12), np.sum(np.abs(Ymean2 - Ymean1))))" - ] - }, - { - "cell_type": "markdown", - "id": "e1fe54a8", - "metadata": {}, - "source": [ - "In the alternative interpretation, setting the global seed is\n", - "insufficient. Unlike simulation based on the parameters, where we can\n", - "pre-generate all the parameter values and send them off to individual\n", - "processes in the parallel backend, this is prohibitive here. In a\n", - "nutshell, the seed does not propagate when using a parallel backend\n", - "because each *integration* requires an unknown number of random samples.\n", - "Therefore, we have an additional flag **parallel** in the function\n", - "signature. By ensuring that the computation runs in serial, we can make\n", - "use of the global seed and generate identical runs." - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "d5a9e235", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Difference in simulation: 2534.4614923250074\n", - "Difference in simulation using same seed: 0.0\n" - ] - } - ], - "source": [ - "x0 = [2362206.0, 3.0, 0.0]\n", - "\n", - "odeS = SimulateOde(stateList, paramList, transition=transitionList)\n", - "\n", - "odeS.parameters = [0.5, 1.0/3.0, x0[0]]\n", - "\n", - "odeS.initial_values = (x0, t[0])\n", - "\n", - "simX, simT = odeS.simulate_jump(t[1:10], 10, parallel=False, full_output=True)\n", - "\n", - "np.random.seed(1)\n", - "\n", - "simX1, simT1 = odeS.simulate_jump(t[1:10], 10, parallel=False, full_output=True)\n", - "\n", - "np.random.seed(1)\n", - "\n", - "simX2, simT2 = odeS.simulate_jump(t[1:10], 10, parallel=False, full_output=True)\n", - "\n", - "sim_diff = [np.linalg.norm(simX[i] - x1) for i, x1 in enumerate(simX1)]\n", - "\n", - "sim_diff12 = [np.linalg.norm(simX2[i] - x1) for i, x1 in enumerate(simX1)]\n", - "\n", - "print(\"Difference in simulation: %s\" %np.sum(np.abs(sim_diff)))\n", - "\n", - "print(\"Difference in simulation using same seed: %s\" %np.sum(np.abs(sim_diff12)))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.9.15 ('sphinx-doc')", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.15" - }, - "vscode": { - "interpreter": { - "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/notebooks/transition.ipynb b/docs/notebooks/transition.ipynb index fc65bc5a..42d68d31 100644 --- a/docs/notebooks/transition.ipynb +++ b/docs/notebooks/transition.ipynb @@ -6,7 +6,6 @@ "source": [ "# Model set-up using the transition object\n", "\n", - "\n", "The most important part of setting up the model is to correctly define the set ODEs, which is based solely on the classes defined in `transition`. These transitions describe how members of one state can move into another state. We choose to define the models using transitions because it enables the computer to do our book-keeping, therefore reducing the error of, for example, including a flow out of one state, but forgetting to include it in the recipient state. (This does not apply to birth and death processes.) \n", "\n", "\n", @@ -30,7 +29,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "68d41d64", "metadata": {}, "outputs": [], @@ -57,7 +56,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "3b0801dd", "metadata": {}, "outputs": [], @@ -158,53 +157,24 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "id": "1e17eb7c", "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}0 & I S \\beta & 0\\\\0 & 0 & I \\gamma\\\\0 & 0 & 0\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[0, I*S*beta, 0],\n", - "[0, 0, I*gamma],\n", - "[0, 0, 0]])" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "modelTrans.get_transition_matrix()" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "id": "570ceed5", "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": "\n\n\n\n\n\n\n\n\nS\n\nS\n\n\n\nI\n\nI\n\n\n\nS->I\n\n\nβ*S*I\n\n\n\nR\n\nR\n\n\n\nI->R\n\n\nγ*I\n\n\n\n", - "text/plain": [ - "" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "# TODO why are two images produced? issue #75\n", - "modelTrans.get_transition_graph(show=False)" + "modelTrans.get_transition_graph(show=True)" ] }, { @@ -235,27 +205,10 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "id": "9f24cb0a", "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}- I S \\beta\\\\I S \\beta - I \\gamma\\\\I \\gamma\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[ -I*S*beta],\n", - "[I*S*beta - I*gamma],\n", - "[ I*gamma]])" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "birth1 = Transition(origin='S', equation='-beta*S*I', transition_type=TransitionType.B)\n", "\n", @@ -278,27 +231,10 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "id": "9a3b3758", "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}- I S \\beta\\\\I S \\beta - I \\gamma\\\\I \\gamma\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[ -I*S*beta],\n", - "[I*S*beta - I*gamma],\n", - "[ I*gamma]])" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "death1 = Transition(origin='S', equation='beta*S*I', transition_type=TransitionType.D)\n", "\n", @@ -333,27 +269,10 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": null, "id": "3a6a15ea", "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}B - I S \\beta - S \\mu\\\\I S \\beta - I \\gamma - I \\mu\\\\I \\gamma\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[ B - I*S*beta - S*mu],\n", - "[I*S*beta - I*gamma - I*mu],\n", - "[ I*gamma]])" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "modelBD2 = modelTrans\n", "\n", @@ -390,21 +309,10 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": null, "id": "ce5787f8", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "TransitionType.B = Birth process\n", - "TransitionType.D = Death process\n", - "TransitionType.T = Between states\n", - "TransitionType.ODE = ODE _equation\n" - ] - } - ], + "outputs": [], "source": [ "from pygom import transition\n", "\n", diff --git a/docs/notebooks/unroll/unrollBD.ipynb b/docs/notebooks/unroll/unrollBD.ipynb index 54b6f36d..b688db13 100644 --- a/docs/notebooks/unroll/unrollBD.ipynb +++ b/docs/notebooks/unroll/unrollBD.ipynb @@ -10,98 +10,182 @@ "birth and death processes.\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dS}{dt} &= -\\beta SI + B - \\mu S\\\\\n", - "\\frac{dI}{dt} &= \\beta SI - \\gamma I - \\mu I\\\\\n", - "\\frac{dR}{dt} &= \\gamma I\n", + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= -\\beta SI + B - \\mu S\\\\\n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= \\beta SI - \\gamma I - \\mu I\\\\\n", + "\\frac{\\mathrm{d}R}{\\mathrm{d}t} &= \\gamma I - \\mu R\n", "\\end{aligned}$$\n", "\n", - "which consists of two transitions and three birth and death process.\n", + "which consists of two transitions, one birth process and three death processes.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a17b8221", + "metadata": {}, + "outputs": [], + "source": [ + "digraph SIR_Model {rankdir=LR;\n", + " size=\"8\" node \\[shape = circle\\];\n", + " S -\\> I \\[ label = \"βSI\"\\];\n", + " I -\\> R \\[ label = \"γI\" \\];\n", + " B \\[height=0 margin=0 shape=plaintext width=0\\];\n", + " B -\\> S; \"S\\**2*μ\" \\[height=0 margin=0 shape=plaintext width=0\\];\n", + " S -\\> \"S\\**2*μ\"; \"I\\*μ\" \\[height=0 margin=0 shape=plaintext width=0\\];\n", + " I -\\> \"I\\*μ\";\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "416dd324", + "metadata": {}, + "source": [ "\n", - "digraph SIR_Model { \n", - "rankdir=LR; size=\"8\" node \\[shape = circle\\]; S -\\> I \\[ label = \"βSI\"\n", - "\\]; I -\\> R \\[ label = \"γI\" \\]; B \\[height=0 margin=0 shape=plaintext\n", - "width=0\\]; B -\\> S; \"S\\**2*μ\" \\[height=0 margin=0 shape=plaintext\n", - "width=0\\]; S -\\> \"S\\**2*μ\"; \"I\\*μ\" \\[height=0 margin=0 shape=plaintext\n", - "width=0\\]; I -\\> \"I\\*μ\";\n", + "Let's define this in terms of ODEs, and unroll it back to the individual\n", + "processes.\n", "\n", - "}\n", + "We can also assume standard mixing:\n", "\n", - "Let's define this in terms of ODEs, and unroll it back to the individual\n", - "processes." + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= -\\frac{\\beta SI}{N} + B N - \\mu S\\\\\n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= \\frac{\\beta SI}{N} - \\gamma I - \\mu I\\\\\n", + "\\frac{\\mathrm{d}R}{\\mathrm{d}t} &= \\gamma I - \\mu R \\\\\n", + "\\frac{\\mathrm{d}N}{\\mathrm{d}t} &= (B - \\mu) N\n", + "\\end{aligned}$$\n", + "\n", + "$N=S+I+R$ which means that we can get rid of one equation" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "eed075f5", "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}0 & I S \\beta & 0\\\\0 & 0 & I \\gamma\\\\0 & 0 & 0\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[0, I*S*beta, 0],\n", - "[0, 0, I*gamma],\n", - "[0, 0, 0]])" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from pygom import Transition, TransitionType, SimulateOde, common_models\n", "\n", "import matplotlib.pyplot as plt\n", "\n", - "stateList = ['S', 'I', 'R']\n", - "\n", + "stateList = ['S', 'I', 'R', 'N']\n", "paramList = ['beta', 'gamma', 'B', 'mu']\n", "\n", "odeList = [Transition(origin='S', equation='-beta*S*I + B - mu*S', transition_type=TransitionType.ODE),\n", " Transition(origin='I', equation='beta*S*I - gamma*I - mu*I', transition_type=TransitionType.ODE),\n", - " Transition(origin='R', equation='gamma*I', transition_type=TransitionType.ODE)]\n", + " Transition(origin='R', equation='gamma*I - mu*R', transition_type=TransitionType.ODE),\n", + " Transition(origin='N', equation='(B - mu)*N', transition_type=TransitionType.ODE)]\n", "\n", - "ode = SimulateOde(stateList, paramList, ode=odeList)\n", - "\n", - "ode2 = ode.get_unrolled_obj()\n", - "ode2.get_transition_matrix()" + "model = SimulateOde(stateList, paramList, ode=odeList)\n" + ] + }, + { + "cell_type": "markdown", + "id": "73ba18bb", + "metadata": {}, + "source": [ + "The transition matrix is empty" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8c6fc68a", + "metadata": {}, + "outputs": [], + "source": [ + "model.get_transition_matrix()" + ] + }, + { + "cell_type": "markdown", + "id": "2d52621b", + "metadata": {}, + "source": [ + "Upon calculation, we get:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "738249fa", + "metadata": {}, + "outputs": [], + "source": [ + "model = model.get_unrolled_obj()\n", + "model.get_transition_matrix()" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "1759120d", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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c+fO5fbbb8fLy6vbX8irqqpYuXIln332GU1NTVx11VXMnj2b0NDQM5qK2pU5Zta0t7djNptpb2/ngw8+wGw24+HhIeeSFBQUUFJSIq+V48gJSUpKIjExkR49euDh4XFSEGo2m1m8eDGPPPKInCzr7e1NUFAQkydP5uabb6Zfv35/+h5ZtmwZ7777LmFhYdx7770MGDCgw+rNlwPHTLWqqioefvhhNm3axPLlyxkwYMCfvg9FgCIIwmXF0e1fWlrKkiVL+M9//kO/fv145513iIqK6nY9Jn/m8OHDLF26lJUrVxITE8OiRYtISUlBrVY7u2ln5MRp2I7iYlarVa4Xc+DAAQ4dOsT+/fupqalBoVDg5+dHTEwMvXv3Ji0tjbS0NOLi4s44odlqtbJlyxZGjRqFWq1Gq9UyY8YM5s6dS69evc44wLPb7SxdupT3338fHx8fHn/8cQYMGNBtXvvz5Th3VVVVPPvssyxbtozly5czceLEMxoyFQGKIAiXDce3uT179vDSSy+xdu1a5s+fz9///ne5TsmlqKmpic2bN/PUU09RWlrKBx98wLhx4y7IDKRzdaoF7gBaWlooLi5m79697N69m6ysLPbu3UtNTQ0uLi7ExcWRkpJCnz596N27N3369CE4OPi8coYcJe8DAgJIS0vj5ZdfJj09Ha1We9b7slqtfPPNN7z66quYTCaeffZZJk+e3KVe+wvBEZwcO3aMxx9/nHXr1vH2229z4403nvFxiwBFEITLhtVq5fvvv+eVV16htraWF198kauuugrgkr9YSJJEcXExjz76KN9++y3vv/8+N998c5c5bkmSaGpqYv/+/ezbt4/9+/ezf/9+srOz5Vk1YWFh9OnTh9TUVIYMGcLgwYNPm9dxvsclSRI//PADEydO7FA99lz2I0kSu3bt4uWXX+4QFLu4uHSZ17+zmUwm1q1bx7PPPktdXR0ffvghV1xxxVkdrwhQBEG4LDi629999128vb155plnSE9P7/a5JmfK8fFtMplYuHAhb775Jp988glXX331RR9ysNlsmEwmjh07xs6dO8nIyGDv3r1kZ2djs9kICAggKSmJ3r1707NnT/r06UN8fDze3t4dqvE6LnYX4iLvCCw64zkc+yovL2fJkiW89NJL9OnThw8//JAePXpcckHK/v37ef/991m1ahUpKSm8+OKLJCUl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jBkzmDt3LgaDAVdX10viveDIASkvL2fNmjV88sknWK1WHnzwQW666SZnN++c2O12GhsbOXr0KIcOHZJvubm5tLS04OrqKvecRkVFER8fT69evdDr9XLvquMmvpx0fSJAEc6LJEm0t7djMpnYvHkzq1atYsuWLVgsFoYOHcq1114rF+ly5oeB1WqlqqqKdevW8cUXX7Bp0yYCAgKYPn06N9xwA1FRUbi7u1+2gYqjPL3VapVvbW1tHDp0iN27d7N//3727dtHaWkpVqsVvV5PYmKiXF10yJAhJ61+3NVJkkRjYyPvv/8+ixYtIjExkWeffZa+ffvKiwt2p+M5kdVqpbW1lU2bNrF06VJ27dpFeno6f//73+ndu7ezm9fpTCYTeXl57N+/nz179pCVlUVubi4NDQ2oVCoiIyPp2bMnPXv2JDk5meTkZLln5cSFJrvzOb8UiQBFOGeObzOff/45H330EdnZ2SQkJHDDDTdw9dVXd9kVUSVJIjs7m48++oj//ve/2Gw2pk6dyq233kq/fv3knJdLmSMgcdwsFgs1NTXs3buXjIwMMjIy2L59O21tbQQEBNCrVy969+5Namoq6enp5zxU0xXZbDb27dvH/fffz549e7jllluYN2+ePITUnb5p2+127HY7WVlZvPrqq/zyyy9ER0dz5513ct111+Hp6ensJl40ra2tlJSUkJWVxf79++VKuHV1dahUKnnYNzU1lX79+pGcnExoaKgcpDiSsR068z1w4npV3en9dbGJAEU4a463wZo1a/jb3/5GQUEBw4cP54477mD06NHd6nWuq6tj+fLlfPDBB5SVlTF69GjuvfdeRowYAVwa+Qin+rMtKytj//79ZGZmkpmZyd69eykqKkKpVBIdHc2QIUMYOnQogwYNIjExEY1Gc0m8FqfjuGB8+OGH/O///i91dXVMmTKF2bNnM2DAALnwXFd7DX5/bnft2sXzzz/PmjVriIqKYt68eUydOrXDopCXu7KyMnbs2EFGRgb79u3jwIEDlJeXA6DX6+nVqxcpKSn07duXfv36kZSUdMovLOfzXrBarezfv5/c3FymT58uFl88DRGgCGdFkiRKS0uZM2cO69atY+rUqTzyyCP07t1bzgvoTn9kjgtTQ0MDn332GR9++CGlpaVcc801/OMf/+j2H+yO3pGsrCy2bt3K9u3b2bJlCxUV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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/svg+xml": "\n\n\n\n\n\n\n\n\nS\n\nS\n\n\n\nI\n\nI\n\n\n\nS->I\n\n\nI*S*β\n\n\n\nS*μ\nS*μ\n\n\n\nS->S*μ\n\n\n\n\n\nR\n\nR\n\n\n\nI->R\n\n\nI*γ\n\n\n\nI*μ\nI*μ\n\n\n\nI->I*μ\n\n\n\n\n\nB\nB\n\n\n\nB->S\n\n\n\n\n\n", - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], + "source": [ + "#model.get_transition_graph()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14d00308", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import Transition, TransitionType, SimulateOde, common_models\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "stateList = ['S', 'I', 'R', 'U']\n", + "paramList = ['beta', 'gamma', 'B', 'mu']\n", + "odeList = [Transition(origin='S', equation='-beta*S*I/(S+I+R) + B*(S+I+R) - mu*S', transition_type=TransitionType.ODE),\n", + " Transition(origin='I', equation='beta*S*I/(S+I+R) - gamma*I - mu*I', transition_type=TransitionType.ODE),\n", + " Transition(origin='R', equation='gamma*I - mu*R', transition_type=TransitionType.ODE),\n", + " Transition(origin='U', equation='(mu-B)*(S+I+R)', transition_type=TransitionType.ODE)]\n", + "\n", + "model = SimulateOde(stateList, paramList, ode=odeList)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9d064b4", + "metadata": {}, + "outputs": [], + "source": [ + "model.get_ode_eqn()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65f1a19a", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "model = model.get_unrolled_obj()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec11e160", + "metadata": {}, + "outputs": [], + "source": [ + "model.get_transition_matrix()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2be9c993", + "metadata": {}, + "outputs": [], "source": [ - "ode2.get_transition_graph()\n" + "model.get_ode_eqn()" ] } ], @@ -121,7 +205,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.15" + "version": "3.12.2" }, "vscode": { "interpreter": { diff --git a/docs/notebooks/unroll/unrollHard.ipynb b/docs/notebooks/unroll/unrollHard.ipynb index f178daa7..68557980 100644 --- a/docs/notebooks/unroll/unrollHard.ipynb +++ b/docs/notebooks/unroll/unrollHard.ipynb @@ -6,31 +6,50 @@ "source": [ "# Hard Problem\n", "\n", - "Now we turn to a harder problem that does not have a one to one mapping\n", - "between all the transitions and the terms in the ODEs. We use the model\n", - "in {doc}`Influenza_SLIARN`, defined by" - ] - }, - { - "cell_type": "markdown", - "id": "2f468e1e", - "metadata": {}, - "source": [ + "Now we turn to a harder problem that does not have a one to one mapping between all the transitions and the terms in the ODEs.\n", + "\n", + "We use a **S**usceptible, **L**atent, **I**nfective, **A**symptomatic and **R**emoved model.\n", + "\n", + "In this model, **S**usceptible individuals may be infected and enter a **L**atent phase after which they are capable of onward transmission as members of the **I**nfective or **A**symptomatic classes. Those in the **A** class have infectivity reduced by a factor $\\delta$ relative to the **I** class. These states are populated by the outflow of **L**atent individuals, where a fraction $p$ proceed to the **I**nfective group and the remainder instead become **A**symptomatic, both at a rate $\\kappa$. All **A**symptomatics eventually become **R**emoved, whereas a fraction, $1-f$, of **I**nfectives go on to die, thus reducing the total living population, **N**.\n", + "\n", + "The equations are as follows:\n", + "\n", + "under mass action $\\beta(N) \\propto N$\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= -\\beta S (I + \\delta A) \\\\ \n", + "\\frac{\\mathrm{d}L}{\\mathrm{d}t} &= \\beta S (I + \\delta A) - \\kappa L \\\\ \n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= p \\kappa L - \\alpha I \\\\\n", + "\\frac{\\mathrm{d}A}{\\mathrm{d}t} &= (1 - p) \\kappa L - \\eta A \\\\\n", + "\\frac{\\mathrm{d}R}{\\mathrm{d}t} &= f \\alpha I + \\eta A \\\\\n", + "\\frac{\\mathrm{d}N}{\\mathrm{d}t} &= -(1 - f) \\alpha I.\n", + "\\end{aligned}$$\n", + "\n", + "where $N+D=N_0$, assuming we start when deaths are zero.\n", + "\n", + "under standard incidence $\\beta(N) = \\text{const}$\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= -\\beta S \\frac{(I + \\delta A)}{N} \\\\ \n", + "\\frac{\\mathrm{d}L}{\\mathrm{d}t} &= \\beta S \\frac{(I + \\delta A)}{N} - \\kappa L \\\\ \n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= p \\kappa L - \\alpha I \\\\\n", + "\\frac{\\mathrm{d}A}{\\mathrm{d}t} &= (1 - p) \\kappa L - \\eta A \\\\\n", + "\\frac{\\mathrm{d}R}{\\mathrm{d}t} &= f \\alpha I + \\eta A \\\\\n", + "\\frac{\\mathrm{d}N}{\\mathrm{d}t} &= -(1 - f) \\alpha I.\n", + "\\end{aligned}$$\n", + "\n", + "We see the difficulty for finding the transitions:\n", + "\n", + "The outflow of state **L**, $\\kappa L$, is composed of two transitions, one to **I** and the other to **A** but the ode of **L** only reflects the total flow going out of the state.\n", + "\n", + "Also confusing things is the fact that the total number of living individuals **N** is not a distinct category, rather $N=S+L+I+A+R$ and thus it doesn't make sense to think of any of our groups flowing into it since they are a subset of it. We must instead identify how the leave the system, in this case **D**ead, so we replace the last equation with:\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dS}{dt} &= -S \\beta (I + \\delta A) \\\\ \n", - "\\frac{dL}{dt} &= S \\beta (I + \\delta A) - \\kappa L \\\\ \n", - "\\frac{dI}{dt} &= p \\kappa L - \\alpha I \\\\\n", - "\\frac{dA}{dt} &= (1 - p) \\kappa L - \\eta A \\\\\n", - "\\frac{dR}{dt} &= f \\alpha I + \\eta A \\\\\n", - "\\frac{dN}{dt} &= -(1 - f) \\alpha I.\n", + "\\frac{\\mathrm{d}D}{\\mathrm{d}t} &= (1 - f) \\alpha I.\n", "\\end{aligned}$$\n", + "and substitute N from the above equations\n", + "\n", + "The combination $S+L+I+A+R+D$ is constant, so all the flows on the LHS must add to zero and we have a closed system.\n", "\n", - "The outflow of state **L**, $\\kappa L$, is composed of two transitions,\n", - "one to **I** and the other to **A** but the ode of **L** only reflects\n", - "the total flow going out of the state. The same can be said for state **I**,\n", - "where the flow $\\alpha I$ goes to both **R** and **N**. Graphically, it\n", - "is a rather simple process as shown below." + "TODO: Is this a necessary condition? If so, we could add a quick error message if sum!=0" ] }, { @@ -47,19 +66,6 @@ "}" ] }, - { - "cell_type": "markdown", - "id": "db8a91f0", - "metadata": {}, - "source": [ - "\n", - "We slightly change the model by introducing a new state **D** to convert\n", - "it into a closed system. The combination of state **D** and **N** is a\n", - "constant, the total population. So we can remove **N** and this new\n", - "system consist of six transitions. We define them explicitly as ODEs and\n", - "unroll them into transitions.\n" - ] - }, { "cell_type": "code", "execution_count": 1, @@ -90,19 +96,16 @@ "from pygom import SimulateOde, Transition, TransitionType\n", "\n", "stateList = ['S', 'L', 'I', 'A', 'R', 'D']\n", - "\n", - "paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'epsilon', 'N']\n", - "\n", - "odeList = [Transition(origin='S', equation='- beta*S/N*(I + delta*A)', transition_type=TransitionType.ODE), \n", - " Transition(origin='L', equation='beta*S/N*(I + delta*A) - kappa*L', transition_type=TransitionType.ODE),\n", + "paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'epsilon']\n", + "odeList = [Transition(origin='S', equation='- beta*S*(I + delta*A)', transition_type=TransitionType.ODE), \n", + " Transition(origin='L', equation='beta*S*(I + delta*A) - kappa*L', transition_type=TransitionType.ODE),\n", " Transition(origin='I', equation='p*kappa*L - alpha*I', transition_type=TransitionType.ODE),\n", - " Transition(origin='A', equation='(1 - p)*kappa* L - epsilon*A', transition_type=TransitionType.ODE),\n", + " Transition(origin='A', equation='(1 - p)*kappa*L - epsilon*A', transition_type=TransitionType.ODE),\n", " Transition(origin='R', equation='f*alpha*I + epsilon*A', transition_type=TransitionType.ODE), \n", " Transition(origin='D', equation='(1 - f)*alpha*I', transition_type=TransitionType.ODE)]\n", - "\n", - "ode = SimulateOde(stateList, paramList, ode=odeList)\n", - "\n", - "ode.get_transition_matrix()" + "model = SimulateOde(stateList, paramList, ode=odeList)\n", + "#model.get_transition_matrix()\n", + "model.get_ode_eqn()" ] }, { @@ -132,9 +135,8 @@ } ], "source": [ - "ode2 = ode.get_unrolled_obj()\n", - "\n", - "ode2.get_transition_matrix()" + "model = model.get_unrolled_obj()\n", + "model.get_transition_matrix()" ] }, { @@ -164,7 +166,70 @@ } ], "source": [ - "ode2.get_ode_eqn()" + "model.get_ode_eqn()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1369c63a", + "metadata": {}, + "outputs": [], + "source": [ + "# Lets see what happens with standard\n", + "\n", + "#stateList = ['S', 'L', 'I', 'A', 'R', 'N']\n", + "#paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'epsilon']\n", + "#odeList = [Transition(origin='S', equation='-beta*S/N*(I + delta*A)', transition_type=TransitionType.ODE), \n", + "# Transition(origin='L', equation='beta*S/N*(I + delta*A) - kappa*L', transition_type=TransitionType.ODE),\n", + "# Transition(origin='I', equation='p*kappa*L - alpha*I', transition_type=TransitionType.ODE),\n", + "# Transition(origin='A', equation='(1 - p)*kappa*L - epsilon*A', transition_type=TransitionType.ODE),\n", + "# Transition(origin='R', equation='f*alpha*I + epsilon*A', transition_type=TransitionType.ODE), \n", + "# Transition(origin='N', equation='-(1 - f)*alpha*I', transition_type=TransitionType.ODE)]\n", + "#model = SimulateOde(stateList, paramList, ode=odeList)\n", + "#model.get_transition_matrix()\n", + "\n", + "stateList = ['S', 'L', 'I', 'A', 'R', 'D']\n", + "paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'epsilon', 'tot']\n", + "odeList = [Transition(origin='S', equation='- (beta*S/(tot-D))*(I + delta*A)', transition_type=TransitionType.ODE), \n", + " Transition(origin='L', equation='(beta*S/(tot-D))*(I + delta*A) - kappa*L', transition_type=TransitionType.ODE),\n", + " Transition(origin='I', equation='p*kappa*L - alpha*I', transition_type=TransitionType.ODE),\n", + " Transition(origin='A', equation='(1 - p)*kappa*L - epsilon*A', transition_type=TransitionType.ODE),\n", + " Transition(origin='R', equation='f*alpha*I + epsilon*A', transition_type=TransitionType.ODE), \n", + " Transition(origin='D', equation='(1 - f)*alpha*I', transition_type=TransitionType.ODE)]\n", + "model = SimulateOde(stateList, paramList, ode=odeList)\n", + "model.get_transition_matrix()\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21730a6c", + "metadata": {}, + "outputs": [], + "source": [ + "model = model.get_unrolled_obj()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "712c2776", + "metadata": {}, + "outputs": [], + "source": [ + "model.get_transition_matrix()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24e88360", + "metadata": {}, + "outputs": [], + "source": [ + "model.get_ode_eqn()" ] }, { @@ -193,7 +258,98 @@ }, { "data": { - "image/svg+xml": "\n\n\n\n\n\n\n\n\nS\n\nS\n\n\n\nL\n\nL\n\n\n\nS->L\n\n\nA*S*β*δ/N + I*S*β/N\n\n\n\nI\n\nI\n\n\n\nL->I\n\n\nL*κ*p\n\n\n\nA\n\nA\n\n\n\nL->A\n\n\n-L*κ*p + L*κ\n\n\n\nR\n\nR\n\n\n\nI->R\n\n\nI*α*f\n\n\n\nD\n\nD\n\n\n\nI->D\n\n\n-I*α*f + I*α\n\n\n\nA->R\n\n\nA*ε\n\n\n\n", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "S\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "L\n", + "\n", + "L\n", + "\n", + "\n", + "\n", + "S->L\n", + "\n", + "\n", + "A*S*β*δ/N + I*S*β/N\n", + "\n", + "\n", + "\n", + "I\n", + "\n", + "I\n", + "\n", + "\n", + "\n", + "L->I\n", + "\n", + "\n", + "L*κ*p\n", + "\n", + "\n", + "\n", + "A\n", + "\n", + "A\n", + "\n", + "\n", + "\n", + "L->A\n", + "\n", + "\n", + "-L*κ*p + L*κ\n", + "\n", + "\n", + "\n", + "R\n", + "\n", + "R\n", + "\n", + "\n", + "\n", + "I->R\n", + "\n", + "\n", + "I*α*f\n", + "\n", + "\n", + "\n", + "D\n", + "\n", + "D\n", + "\n", + "\n", + "\n", + "I->D\n", + "\n", + "\n", + "-I*α*f + I*α\n", + "\n", + "\n", + "\n", + "A->R\n", + "\n", + "\n", + "A*ε\n", + "\n", + "\n", + "\n" + ], "text/plain": [ "" ] @@ -204,7 +360,7 @@ } ], "source": [ - "ode2.get_transition_graph()" + "model.get_transition_graph()" ] }, { diff --git a/pygom/model/_tau_leap.c b/pygom/model/_tau_leap.c index b6af6e0a..de05a573 100644 --- a/pygom/model/_tau_leap.c +++ b/pygom/model/_tau_leap.c @@ -1,22 +1,61 @@ -/* Generated by Cython 0.29.33 */ +/* Generated by Cython 3.0.10 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [ + "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\arrayobject.h", + "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\arrayscalars.h", + "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\ndarrayobject.h", + "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\ndarraytypes.h", + "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\ufuncobject.h" + ], + "include_dirs": [ + "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include" + ], + "name": "pygom.model._tau_leap", + "sources": [ + "pygom/model/_tau_leap.pyx" + ] + }, + "module_name": "pygom.model._tau_leap" +} +END: Cython Metadata */ #ifndef PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN #endif /* PY_SSIZE_T_CLEAN */ +#if defined(CYTHON_LIMITED_API) && 0 + #ifndef Py_LIMITED_API + #if CYTHON_LIMITED_API+0 > 0x03030000 + #define Py_LIMITED_API CYTHON_LIMITED_API + #else + #define Py_LIMITED_API 0x03030000 + #endif + #endif +#endif + #include "Python.h" #ifndef Py_PYTHON_H #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.6+ or Python 3.3+. +#elif PY_VERSION_HEX < 0x02070000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.7+ or Python 3.3+. +#else +#if defined(CYTHON_LIMITED_API) && CYTHON_LIMITED_API +#define __PYX_EXTRA_ABI_MODULE_NAME "limited" #else -#define CYTHON_ABI "0_29_33" -#define CYTHON_HEX_VERSION 0x001D21F0 -#define CYTHON_FUTURE_DIVISION 0 +#define __PYX_EXTRA_ABI_MODULE_NAME "" +#endif +#define CYTHON_ABI "3_0_10" __PYX_EXTRA_ABI_MODULE_NAME +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." +#define CYTHON_HEX_VERSION 0x03000AF0 +#define CYTHON_FUTURE_DIVISION 1 #include #ifndef offsetof #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) #endif -#if !defined(WIN32) && !defined(MS_WINDOWS) +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) #ifndef __stdcall #define __stdcall #endif @@ -35,9 +74,7 @@ #endif #define __PYX_COMMA , #ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif + #define HAVE_LONG_LONG #endif #ifndef PY_LONG_LONG #define PY_LONG_LONG LONG_LONG @@ -45,13 +82,19 @@ #ifndef Py_HUGE_VAL #define Py_HUGE_VAL HUGE_VAL #endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 #define CYTHON_COMPILING_IN_NOGIL 0 #undef CYTHON_USE_TYPE_SLOTS #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 #undef CYTHON_USE_PYTYPE_LOOKUP #define CYTHON_USE_PYTYPE_LOOKUP 0 #if PY_VERSION_HEX < 0x03050000 @@ -76,10 +119,19 @@ #define CYTHON_UNPACK_METHODS 0 #undef CYTHON_FAST_THREAD_STATE #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 #undef CYTHON_FAST_PYCALL #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 #undef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 0 #undef CYTHON_USE_DICT_VERSIONS @@ -89,44 +141,125 @@ #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 #endif -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 #define CYTHON_COMPILING_IN_NOGIL 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1 && PYPY_VERSION_NUM >= 0x07030C00) + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_CLINE_IN_TRACEBACK + #define CYTHON_CLINE_IN_TRACEBACK 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 #undef CYTHON_USE_PYTYPE_LOOKUP #define CYTHON_USE_PYTYPE_LOOKUP 0 #undef CYTHON_USE_ASYNC_SLOTS #define CYTHON_USE_ASYNC_SLOTS 0 #undef CYTHON_USE_PYLIST_INTERNALS #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 #undef CYTHON_USE_PYLONG_INTERNALS #define CYTHON_USE_PYLONG_INTERNALS 0 #ifndef CYTHON_AVOID_BORROWED_REFS #define CYTHON_AVOID_BORROWED_REFS 0 #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 #undef CYTHON_FAST_THREAD_STATE #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 #undef CYTHON_FAST_PYCALL #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif #undef CYTHON_PEP489_MULTI_PHASE_INIT #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 1 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif #undef CYTHON_USE_DICT_VERSIONS #define CYTHON_USE_DICT_VERSIONS 0 #undef CYTHON_USE_EXC_INFO_STACK @@ -134,19 +267,28 @@ #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 #endif -#elif defined(PY_NOGIL) + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 +#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL) #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 #define CYTHON_COMPILING_IN_NOGIL 1 #ifndef CYTHON_USE_TYPE_SLOTS #define CYTHON_USE_TYPE_SLOTS 1 #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif #undef CYTHON_USE_PYTYPE_LOOKUP #define CYTHON_USE_PYTYPE_LOOKUP 0 #ifndef CYTHON_USE_ASYNC_SLOTS #define CYTHON_USE_ASYNC_SLOTS 1 #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #endif #undef CYTHON_USE_PYLIST_INTERNALS #define CYTHON_USE_PYLIST_INTERNALS 0 #ifndef CYTHON_USE_UNICODE_INTERNALS @@ -154,8 +296,6 @@ #endif #undef CYTHON_USE_UNICODE_WRITER #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 #ifndef CYTHON_AVOID_BORROWED_REFS #define CYTHON_AVOID_BORROWED_REFS 0 #endif @@ -167,11 +307,22 @@ #endif #undef CYTHON_FAST_THREAD_STATE #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 1 + #endif #undef CYTHON_FAST_PYCALL #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif #ifndef CYTHON_PEP489_MULTI_PHASE_INIT #define CYTHON_PEP489_MULTI_PHASE_INIT 1 #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif #ifndef CYTHON_USE_TP_FINALIZE #define CYTHON_USE_TP_FINALIZE 1 #endif @@ -179,18 +330,25 @@ #define CYTHON_USE_DICT_VERSIONS 0 #undef CYTHON_USE_EXC_INFO_STACK #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #endif #else #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 #define CYTHON_COMPILING_IN_NOGIL 0 #ifndef CYTHON_USE_TYPE_SLOTS #define CYTHON_USE_TYPE_SLOTS 1 #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP #define CYTHON_USE_PYTYPE_LOOKUP 1 #endif #if PY_MAJOR_VERSION < 3 @@ -199,10 +357,7 @@ #elif !defined(CYTHON_USE_ASYNC_SLOTS) #define CYTHON_USE_ASYNC_SLOTS 1 #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) + #ifndef CYTHON_USE_PYLONG_INTERNALS #define CYTHON_USE_PYLONG_INTERNALS 1 #endif #ifndef CYTHON_USE_PYLIST_INTERNALS @@ -226,37 +381,62 @@ #ifndef CYTHON_UNPACK_METHODS #define CYTHON_UNPACK_METHODS 1 #endif - #if PY_VERSION_HEX >= 0x030B00A4 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #elif !defined(CYTHON_FAST_THREAD_STATE) + #ifndef CYTHON_FAST_THREAD_STATE #define CYTHON_FAST_THREAD_STATE 1 #endif + #ifndef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1) + #endif #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL (PY_VERSION_HEX < 0x030A0000) + #define CYTHON_FAST_PYCALL 1 #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #if PY_VERSION_HEX < 0x030400a1 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #elif !defined(CYTHON_USE_TP_FINALIZE) + #define CYTHON_USE_TP_FINALIZE 1 #endif - #ifndef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #if PY_VERSION_HEX < 0x030600B1 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5) #endif - #if PY_VERSION_HEX >= 0x030B00A4 + #if PY_VERSION_HEX < 0x030700A3 #undef CYTHON_USE_EXC_INFO_STACK #define CYTHON_USE_EXC_INFO_STACK 0 #elif !defined(CYTHON_USE_EXC_INFO_STACK) - #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #define CYTHON_USE_EXC_INFO_STACK 1 #endif #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 1 + #endif #endif #if !defined(CYTHON_FAST_PYCCALL) #define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) #endif +#if !defined(CYTHON_VECTORCALL) +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1) +#endif +#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1) #if CYTHON_USE_PYLONG_INTERNALS #if PY_MAJOR_VERSION < 3 #include "longintrepr.h" @@ -285,6 +465,17 @@ #define CYTHON_RESTRICT #endif #endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif #ifndef CYTHON_UNUSED # if defined(__GNUC__) # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) @@ -298,13 +489,16 @@ # define CYTHON_UNUSED # endif #endif -#ifndef CYTHON_MAYBE_UNUSED_VAR +#ifndef CYTHON_UNUSED_VAR # if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } + template void CYTHON_UNUSED_VAR( const T& ) { } # else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) +# define CYTHON_UNUSED_VAR(x) (void)(x) # endif #endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif #ifndef CYTHON_NCP_UNUSED # if CYTHON_COMPILING_IN_CPYTHON # define CYTHON_NCP_UNUSED @@ -312,28 +506,59 @@ # define CYTHON_NCP_UNUSED CYTHON_UNUSED # endif #endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif #define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) #ifdef _MSC_VER #ifndef _MSC_STDINT_H_ #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + #endif + #endif + #if _MSC_VER < 1300 + #ifdef _WIN64 + typedef unsigned long long __pyx_uintptr_t; + #else + typedef unsigned int __pyx_uintptr_t; + #endif + #else + #ifdef _WIN64 + typedef unsigned __int64 __pyx_uintptr_t; #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; + typedef unsigned __int32 __pyx_uintptr_t; #endif #endif #else - #include + #include + typedef uintptr_t __pyx_uintptr_t; #endif #ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif #endif #endif #ifndef CYTHON_FALLTHROUGH @@ -343,13 +568,26 @@ #define CYTHON_FALLTHROUGH #endif #endif - #if defined(__clang__ ) && defined(__apple_build_version__) + #if defined(__clang__) && defined(__apple_build_version__) #if __apple_build_version__ < 7000000 #undef CYTHON_FALLTHROUGH #define CYTHON_FALLTHROUGH #endif #endif #endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) #ifndef CYTHON_INLINE #if defined(__clang__) @@ -365,85 +603,145 @@ #endif #endif -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif #define __PYX_BUILD_PY_SSIZE_T "n" #define CYTHON_FORMAT_SSIZE_T "z" #if PY_MAJOR_VERSION < 3 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #define __Pyx_DefaultClassType PyClass_Type + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #else #define __Pyx_BUILTIN_MODULE_NAME "builtins" #define __Pyx_DefaultClassType PyType_Type -#if PY_VERSION_HEX >= 0x030B00A1 - static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int k, int l, int s, int f, +#if CYTHON_COMPILING_IN_LIMITED_API + static CYTHON_INLINE PyObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, PyObject *code, PyObject *c, PyObject* n, PyObject *v, PyObject *fv, PyObject *cell, PyObject* fn, PyObject *name, int fline, PyObject *lnos) { - PyObject *kwds=NULL, *argcount=NULL, *posonlyargcount=NULL, *kwonlyargcount=NULL; - PyObject *nlocals=NULL, *stacksize=NULL, *flags=NULL, *replace=NULL, *call_result=NULL, *empty=NULL; - const char *fn_cstr=NULL; - const char *name_cstr=NULL; - PyCodeObject* co=NULL; + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030B0000 + PyObject *version_info; + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); - if (!(kwds=PyDict_New())) goto end; - if (!(argcount=PyLong_FromLong(a))) goto end; - if (PyDict_SetItemString(kwds, "co_argcount", argcount) != 0) goto end; - if (!(posonlyargcount=PyLong_FromLong(0))) goto end; - if (PyDict_SetItemString(kwds, "co_posonlyargcount", posonlyargcount) != 0) goto end; - if (!(kwonlyargcount=PyLong_FromLong(k))) goto end; - if (PyDict_SetItemString(kwds, "co_kwonlyargcount", kwonlyargcount) != 0) goto end; - if (!(nlocals=PyLong_FromLong(l))) goto end; - if (PyDict_SetItemString(kwds, "co_nlocals", nlocals) != 0) goto end; - if (!(stacksize=PyLong_FromLong(s))) goto end; - if (PyDict_SetItemString(kwds, "co_stacksize", stacksize) != 0) goto end; - if (!(flags=PyLong_FromLong(f))) goto end; - if (PyDict_SetItemString(kwds, "co_flags", flags) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_code", code) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_consts", c) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_names", n) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_varnames", v) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_freevars", fv) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_cellvars", cell) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_linetable", lnos) != 0) goto end; - if (!(fn_cstr=PyUnicode_AsUTF8AndSize(fn, NULL))) goto end; - if (!(name_cstr=PyUnicode_AsUTF8AndSize(name, NULL))) goto end; - if (!(co = PyCode_NewEmpty(fn_cstr, name_cstr, fline))) goto end; - if (!(replace = PyObject_GetAttrString((PyObject*)co, "replace"))) goto cleanup_code_too; - if (!(empty = PyTuple_New(0))) goto cleanup_code_too; // unfortunately __pyx_empty_tuple isn't available here - if (!(call_result = PyObject_Call(replace, empty, kwds))) goto cleanup_code_too; - Py_XDECREF((PyObject*)co); - co = (PyCodeObject*)call_result; - call_result = NULL; - if (0) { - cleanup_code_too: - Py_XDECREF((PyObject*)co); - co = NULL; + #if __PYX_LIMITED_VERSION_HEX >= 0x030B0000 + minor_version = 11; + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); } - end: - Py_XDECREF(kwds); - Py_XDECREF(argcount); - Py_XDECREF(posonlyargcount); - Py_XDECREF(kwonlyargcount); - Py_XDECREF(nlocals); - Py_XDECREF(stacksize); - Py_XDECREF(replace); - Py_XDECREF(call_result); - Py_XDECREF(empty); + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); if (type) { PyErr_Restore(type, value, traceback); } - return co; + return result; } + #ifndef CO_OPTIMIZED + #define CO_OPTIMIZED 0x0001 + #endif + #ifndef CO_NEWLOCALS + #define CO_NEWLOCALS 0x0002 + #endif + #ifndef CO_VARARGS + #define CO_VARARGS 0x0004 + #endif + #ifndef CO_VARKEYWORDS + #define CO_VARKEYWORDS 0x0008 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x0200 + #endif + #ifndef CO_GENERATOR + #define CO_GENERATOR 0x0020 + #endif + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x0080 + #endif +#elif PY_VERSION_HEX >= 0x030B0000 + static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + PyObject *empty_bytes = PyBytes_FromStringAndSize("", 0); + if (!empty_bytes) return NULL; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, empty_bytes); + Py_DECREF(empty_bytes); + return result; + } +#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #else - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #endif - #define __Pyx_DefaultClassType PyType_Type +#endif +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 +#endif +#ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 #endif #ifndef Py_TPFLAGS_CHECKTYPES #define Py_TPFLAGS_CHECKTYPES 0 @@ -457,6 +755,12 @@ #ifndef Py_TPFLAGS_HAVE_FINALIZE #define Py_TPFLAGS_HAVE_FINALIZE 0 #endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif #ifndef METH_STACKLESS #define METH_STACKLESS 0 #endif @@ -468,34 +772,89 @@ typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames); #else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords + #if PY_VERSION_HEX >= 0x030d00A4 + # define __Pyx_PyCFunctionFast PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords + #else + # define __Pyx_PyCFunctionFast _PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords + #endif +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#elif CYTHON_BACKPORT_VECTORCALL + typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(((size_t)(n)) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_MAJOR_VERSION >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) #endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void *cfunc) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if __PYX_LIMITED_VERSION_HEX < 0x030900B1 + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); #else -#define __Pyx_PyFastCFunction_Check(func) 0 + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 #endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) #define PyObject_Malloc(s) PyMem_Malloc(s) #define PyObject_Free(p) PyMem_Free(p) #define PyObject_Realloc(p) PyMem_Realloc(p) #endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 - #define PyMem_RawMalloc(n) PyMem_Malloc(n) - #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) - #define PyMem_RawFree(p) PyMem_Free(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) #else #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) #endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() #elif PY_VERSION_HEX >= 0x03060000 #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() #elif PY_VERSION_HEX >= 0x03000000 @@ -503,6 +862,22 @@ #else #define __Pyx_PyThreadState_Current _PyThreadState_Current #endif +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE(obj), name, func_ctype) +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) +#endif #if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) #include "pythread.h" #define Py_tss_NEEDS_INIT 0 @@ -533,7 +908,29 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { return PyThread_get_key_value(*key); } #endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#if PY_MAJOR_VERSION < 3 + #if CYTHON_COMPILING_IN_PYPY + #if PYPY_VERSION_NUM < 0x07030600 + #if defined(__cplusplus) && __cplusplus >= 201402L + [[deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")]] + #elif defined(__GNUC__) || defined(__clang__) + __attribute__ ((__deprecated__("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6"))) + #elif defined(_MSC_VER) + __declspec(deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")) + #endif + static CYTHON_INLINE int PyGILState_Check(void) { + return 0; + } + #else // PYPY_VERSION_NUM < 0x07030600 + #endif // PYPY_VERSION_NUM < 0x07030600 + #else + static CYTHON_INLINE int PyGILState_Check(void) { + PyThreadState * tstate = _PyThreadState_Current; + return tstate && (tstate == PyGILState_GetThisThreadState()); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 || defined(_PyDict_NewPresized) #define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) #else #define __Pyx_PyDict_NewPresized(n) PyDict_New() @@ -545,12 +942,69 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) #endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX > 0x030600B4 && PY_VERSION_HEX < 0x030d0000 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000) +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) + #define __Pyx_PyObject_GetIterNextFunc(obj) (Py_TYPE(obj)->tp_iternext) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) + #define __Pyx_PyObject_GetIterNextFunc(obj) PyIter_Next +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyObject_GenericSetAttr((PyObject*)tp, k, v) +#else + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyDict_SetItem(tp->tp_dict, k, v) +#endif +#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000 +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} #else -#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) #endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) +#if CYTHON_COMPILING_IN_LIMITED_API + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GetLength(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) #define CYTHON_PEP393_ENABLED 1 #if PY_VERSION_HEX >= 0x030C0000 #define __Pyx_PyUnicode_READY(op) (0) @@ -561,10 +1015,10 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) #if PY_VERSION_HEX >= 0x030C0000 #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) #else @@ -582,11 +1036,11 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #define __Pyx_PyUnicode_READY(op) (0) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535U : 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((int)sizeof(Py_UNICODE)) #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = (Py_UNICODE) ch) #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) #endif #if CYTHON_COMPILING_IN_PYPY @@ -597,14 +1051,20 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) #endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) || (PY_MAJOR_VERSION == 2 && PYPY_VERSION_NUM < 0x07030500) + #undef PyUnicode_Contains + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif #endif #define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) #define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) @@ -633,8 +1093,14 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) #endif +#if CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif #ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) #endif #if PY_VERSION_HEX >= 0x030900A4 #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) @@ -644,15 +1110,42 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) #endif #if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) #else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) +#endif +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static CYTHON_INLINE PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } #endif #if PY_MAJOR_VERSION >= 3 #define PyIntObject PyLongObject #define PyInt_Type PyLong_Type #define PyInt_Check(op) PyLong_Check(op) #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define __Pyx_Py3Int_Check(op) PyLong_Check(op) + #define __Pyx_Py3Int_CheckExact(op) PyLong_CheckExact(op) #define PyInt_FromString PyLong_FromString #define PyInt_FromUnicode PyLong_FromUnicode #define PyInt_FromLong PyLong_FromLong @@ -664,6 +1157,9 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask #define PyNumber_Int PyNumber_Long +#else + #define __Pyx_Py3Int_Check(op) (PyLong_Check(op) || PyInt_Check(op)) + #define __Pyx_Py3Int_CheckExact(op) (PyLong_CheckExact(op) || PyInt_CheckExact(op)) #endif #if PY_MAJOR_VERSION >= 3 #define PyBoolObject PyLongObject @@ -681,11 +1177,6 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t #endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif #if CYTHON_USE_ASYNC_SLOTS #if PY_VERSION_HEX >= 0x030500B1 #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods @@ -726,11 +1217,20 @@ static CYTHON_INLINE float __PYX_NAN() { #endif #define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } #define __PYX_ERR(f_index, lineno, Ln_error) \ { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } -#ifndef __PYX_EXTERN_C +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else #ifdef __cplusplus #define __PYX_EXTERN_C extern "C" #else @@ -743,18 +1243,17 @@ static CYTHON_INLINE float __PYX_NAN() { /* Early includes */ #include #include + + /* Using NumPy API declarations from "numpy/__init__.cython-30.pxd" */ + #include "numpy/arrayobject.h" #include "numpy/ndarrayobject.h" #include "numpy/ndarraytypes.h" #include "numpy/arrayscalars.h" #include "numpy/ufuncobject.h" - - /* NumPy API declarations from "numpy/__init__.pxd" */ - #include #include "pythread.h" #include -#include "pystate.h" #ifdef _OPENMP #include #endif /* _OPENMP */ @@ -803,9 +1302,10 @@ static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { #else #define __Pyx_sst_abs(value) ((value<0) ? -value : value) #endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); #define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) #define __Pyx_PyBytes_FromString PyBytes_FromString #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize @@ -823,9 +1323,9 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) @@ -833,13 +1333,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); #define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) #define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) #define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) #define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode #define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) @@ -863,11 +1357,57 @@ static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); #else #define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) #endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +#include +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; PyObject* default_encoding = NULL; PyObject* ascii_chars_u = NULL; PyObject* ascii_chars_b = NULL; @@ -885,7 +1425,7 @@ static int __Pyx_init_sys_getdefaultencoding_params(void) { char ascii_chars[128]; int c; for (c = 0; c < 128; c++) { - ascii_chars[c] = c; + ascii_chars[c] = (char) c; } __Pyx_sys_getdefaultencoding_not_ascii = 1; ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); @@ -915,6 +1455,7 @@ static int __Pyx_init_sys_getdefaultencoding_params(void) { #else #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#include static char* __PYX_DEFAULT_STRING_ENCODING; static int __Pyx_init_sys_getdefaultencoding_params(void) { PyObject* sys; @@ -950,23 +1491,19 @@ static int __Pyx_init_sys_getdefaultencoding_params(void) { #endif /* __GNUC__ */ static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } +#if !CYTHON_USE_MODULE_STATE static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime = NULL; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; +#endif static int __pyx_lineno; static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; +static const char * __pyx_cfilenm = __FILE__; static const char *__pyx_filename; /* Header.proto */ #if !defined(CYTHON_CCOMPLEX) #if defined(__cplusplus) #define CYTHON_CCOMPLEX 1 - #elif defined(_Complex_I) + #elif (defined(_Complex_I) && !defined(_MSC_VER)) || ((defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_COMPLEX__) && !defined(_MSC_VER)) #define CYTHON_CCOMPLEX 1 #else #define CYTHON_CCOMPLEX 0 @@ -984,15 +1521,28 @@ static const char *__pyx_filename; #define _Complex_I 1.0fj #endif +/* #### Code section: filename_table ### */ static const char *__pyx_f[] = { - "pygom/model/_tau_leap.pyx", - "__init__.pxd", - "stringsource", + "pygom\\\\model\\\\_tau_leap.pyx", + "", + "__init__.cython-30.pxd", "type.pxd", }; +/* #### Code section: utility_code_proto_before_types ### */ +/* ForceInitThreads.proto */ +#ifndef __PYX_FORCE_INIT_THREADS + #define __PYX_FORCE_INIT_THREADS 0 +#endif + +/* NoFastGil.proto */ +#define __Pyx_PyGILState_Ensure PyGILState_Ensure +#define __Pyx_PyGILState_Release PyGILState_Release +#define __Pyx_FastGIL_Remember() +#define __Pyx_FastGIL_Forget() +#define __Pyx_FastGilFuncInit() + /* BufferFormatStructs.proto */ -#define IS_UNSIGNED(type) (((type) -1) > 0) struct __Pyx_StructField_; #define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) typedef struct { @@ -1027,17 +1577,6 @@ typedef struct { char is_valid_array; } __Pyx_BufFmt_Context; -/* MemviewSliceStruct.proto */ -struct __pyx_memoryview_obj; -typedef struct { - struct __pyx_memoryview_obj *memview; - char *data; - Py_ssize_t shape[8]; - Py_ssize_t strides[8]; - Py_ssize_t suboffsets[8]; -} __Pyx_memviewslice; -#define __Pyx_MemoryView_Len(m) (m.shape[0]) - /* Atomics.proto */ #include #ifndef CYTHON_ATOMICS @@ -1045,7 +1584,44 @@ typedef struct { #endif #define __PYX_CYTHON_ATOMICS_ENABLED() CYTHON_ATOMICS #define __pyx_atomic_int_type int -#if CYTHON_ATOMICS && (__GNUC__ >= 5 || (__GNUC__ == 4 &&\ +#define __pyx_nonatomic_int_type int +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__)) + #include +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ + (defined(_MSC_VER) && _MSC_VER >= 1700))) + #include +#endif +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type atomic_int + #define __pyx_atomic_incr_aligned(value) atomic_fetch_add_explicit(value, 1, memory_order_relaxed) + #define __pyx_atomic_decr_aligned(value) atomic_fetch_sub_explicit(value, 1, memory_order_acq_rel) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C atomics" + #endif +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ +\ + (defined(_MSC_VER) && _MSC_VER >= 1700)) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type std::atomic_int + #define __pyx_atomic_incr_aligned(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_relaxed) + #define __pyx_atomic_decr_aligned(value) std::atomic_fetch_sub_explicit(value, 1, std::memory_order_acq_rel) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C++ atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C++ atomics" + #endif +#elif CYTHON_ATOMICS && (__GNUC__ >= 5 || (__GNUC__ == 4 &&\ (__GNUC_MINOR__ > 1 ||\ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 2)))) #define __pyx_atomic_incr_aligned(value) __sync_fetch_and_add(value, 1) @@ -1053,10 +1629,12 @@ typedef struct { #ifdef __PYX_DEBUG_ATOMICS #warning "Using GNU atomics" #endif -#elif CYTHON_ATOMICS && defined(_MSC_VER) && CYTHON_COMPILING_IN_NOGIL +#elif CYTHON_ATOMICS && defined(_MSC_VER) #include #undef __pyx_atomic_int_type #define __pyx_atomic_int_type long + #undef __pyx_nonatomic_int_type + #define __pyx_nonatomic_int_type long #pragma intrinsic (_InterlockedExchangeAdd) #define __pyx_atomic_incr_aligned(value) _InterlockedExchangeAdd(value, 1) #define __pyx_atomic_decr_aligned(value) _InterlockedExchangeAdd(value, -1) @@ -1070,7 +1648,6 @@ typedef struct { #warning "Not using atomics" #endif #endif -typedef volatile __pyx_atomic_int_type __pyx_atomic_int; #if CYTHON_ATOMICS #define __pyx_add_acquisition_count(memview)\ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview)) @@ -1083,20 +1660,20 @@ typedef volatile __pyx_atomic_int_type __pyx_atomic_int; __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock) #endif -/* ForceInitThreads.proto */ -#ifndef __PYX_FORCE_INIT_THREADS - #define __PYX_FORCE_INIT_THREADS 0 -#endif - -/* NoFastGil.proto */ -#define __Pyx_PyGILState_Ensure PyGILState_Ensure -#define __Pyx_PyGILState_Release PyGILState_Release -#define __Pyx_FastGIL_Remember() -#define __Pyx_FastGIL_Forget() -#define __Pyx_FastGilFuncInit() +/* MemviewSliceStruct.proto */ +struct __pyx_memoryview_obj; +typedef struct { + struct __pyx_memoryview_obj *memview; + char *data; + Py_ssize_t shape[8]; + Py_ssize_t strides[8]; + Py_ssize_t suboffsets[8]; +} __Pyx_memviewslice; +#define __Pyx_MemoryView_Len(m) (m.shape[0]) +/* #### Code section: numeric_typedefs ### */ -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":689 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":730 * # in Cython to enable them only on the right systems. * * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< @@ -1105,7 +1682,7 @@ typedef volatile __pyx_atomic_int_type __pyx_atomic_int; */ typedef npy_int8 __pyx_t_5numpy_int8_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":690 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":731 * * ctypedef npy_int8 int8_t * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< @@ -1114,7 +1691,7 @@ typedef npy_int8 __pyx_t_5numpy_int8_t; */ typedef npy_int16 __pyx_t_5numpy_int16_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":691 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":732 * ctypedef npy_int8 int8_t * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< @@ -1123,7 +1700,7 @@ typedef npy_int16 __pyx_t_5numpy_int16_t; */ typedef npy_int32 __pyx_t_5numpy_int32_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":692 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":733 * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< @@ -1132,7 +1709,7 @@ typedef npy_int32 __pyx_t_5numpy_int32_t; */ typedef npy_int64 __pyx_t_5numpy_int64_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":696 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":737 * #ctypedef npy_int128 int128_t * * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< @@ -1141,7 +1718,7 @@ typedef npy_int64 __pyx_t_5numpy_int64_t; */ typedef npy_uint8 __pyx_t_5numpy_uint8_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":697 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":738 * * ctypedef npy_uint8 uint8_t * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< @@ -1150,7 +1727,7 @@ typedef npy_uint8 __pyx_t_5numpy_uint8_t; */ typedef npy_uint16 __pyx_t_5numpy_uint16_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":698 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":739 * ctypedef npy_uint8 uint8_t * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< @@ -1159,7 +1736,7 @@ typedef npy_uint16 __pyx_t_5numpy_uint16_t; */ typedef npy_uint32 __pyx_t_5numpy_uint32_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":699 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":740 * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< @@ -1168,7 +1745,7 @@ typedef npy_uint32 __pyx_t_5numpy_uint32_t; */ typedef npy_uint64 __pyx_t_5numpy_uint64_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":703 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":744 * #ctypedef npy_uint128 uint128_t * * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< @@ -1177,7 +1754,7 @@ typedef npy_uint64 __pyx_t_5numpy_uint64_t; */ typedef npy_float32 __pyx_t_5numpy_float32_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":704 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":745 * * ctypedef npy_float32 float32_t * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< @@ -1186,61 +1763,43 @@ typedef npy_float32 __pyx_t_5numpy_float32_t; */ typedef npy_float64 __pyx_t_5numpy_float64_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":713 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":754 * # The int types are mapped a bit surprising -- * # numpy.int corresponds to 'l' and numpy.long to 'q' * ctypedef npy_long int_t # <<<<<<<<<<<<<< - * ctypedef npy_longlong long_t * ctypedef npy_longlong longlong_t + * */ typedef npy_long __pyx_t_5numpy_int_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":714 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":755 * # numpy.int corresponds to 'l' and numpy.long to 'q' * ctypedef npy_long int_t - * ctypedef npy_longlong long_t # <<<<<<<<<<<<<< - * ctypedef npy_longlong longlong_t - * - */ -typedef npy_longlong __pyx_t_5numpy_long_t; - -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":715 - * ctypedef npy_long int_t - * ctypedef npy_longlong long_t * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< * * ctypedef npy_ulong uint_t */ typedef npy_longlong __pyx_t_5numpy_longlong_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":717 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":757 * ctypedef npy_longlong longlong_t * * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< - * ctypedef npy_ulonglong ulong_t * ctypedef npy_ulonglong ulonglong_t + * */ typedef npy_ulong __pyx_t_5numpy_uint_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":718 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":758 * * ctypedef npy_ulong uint_t - * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< - * ctypedef npy_ulonglong ulonglong_t - * - */ -typedef npy_ulonglong __pyx_t_5numpy_ulong_t; - -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":719 - * ctypedef npy_ulong uint_t - * ctypedef npy_ulonglong ulong_t * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< * * ctypedef npy_intp intp_t */ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":721 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":760 * ctypedef npy_ulonglong ulonglong_t * * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< @@ -1249,7 +1808,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; */ typedef npy_intp __pyx_t_5numpy_intp_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":722 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":761 * * ctypedef npy_intp intp_t * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< @@ -1258,7 +1817,7 @@ typedef npy_intp __pyx_t_5numpy_intp_t; */ typedef npy_uintp __pyx_t_5numpy_uintp_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":724 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":763 * ctypedef npy_uintp uintp_t * * ctypedef npy_double float_t # <<<<<<<<<<<<<< @@ -1267,7 +1826,7 @@ typedef npy_uintp __pyx_t_5numpy_uintp_t; */ typedef npy_double __pyx_t_5numpy_float_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":725 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":764 * * ctypedef npy_double float_t * ctypedef npy_double double_t # <<<<<<<<<<<<<< @@ -1276,7 +1835,7 @@ typedef npy_double __pyx_t_5numpy_float_t; */ typedef npy_double __pyx_t_5numpy_double_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":726 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":765 * ctypedef npy_double float_t * ctypedef npy_double double_t * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< @@ -1284,8 +1843,9 @@ typedef npy_double __pyx_t_5numpy_double_t; * ctypedef npy_cfloat cfloat_t */ typedef npy_longdouble __pyx_t_5numpy_longdouble_t; +/* #### Code section: complex_type_declarations ### */ /* Declarations.proto */ -#if CYTHON_CCOMPLEX +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) #ifdef __cplusplus typedef ::std::complex< float > __pyx_t_float_complex; #else @@ -1297,7 +1857,7 @@ typedef npy_longdouble __pyx_t_5numpy_longdouble_t; static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); /* Declarations.proto */ -#if CYTHON_CCOMPLEX +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) #ifdef __cplusplus typedef ::std::complex< double > __pyx_t_double_complex; #else @@ -1308,6 +1868,7 @@ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(floa #endif static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); +/* #### Code section: type_declarations ### */ /*--- Type declarations ---*/ struct __pyx_array_obj; @@ -1315,7 +1876,7 @@ struct __pyx_MemviewEnum_obj; struct __pyx_memoryview_obj; struct __pyx_memoryviewslice_obj; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":728 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":767 * ctypedef npy_longdouble longdouble_t * * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< @@ -1324,7 +1885,7 @@ struct __pyx_memoryviewslice_obj; */ typedef npy_cfloat __pyx_t_5numpy_cfloat_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":729 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":768 * * ctypedef npy_cfloat cfloat_t * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< @@ -1333,7 +1894,7 @@ typedef npy_cfloat __pyx_t_5numpy_cfloat_t; */ typedef npy_cdouble __pyx_t_5numpy_cdouble_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":730 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":769 * ctypedef npy_cfloat cfloat_t * ctypedef npy_cdouble cdouble_t * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< @@ -1342,7 +1903,7 @@ typedef npy_cdouble __pyx_t_5numpy_cdouble_t; */ typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":732 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":771 * ctypedef npy_clongdouble clongdouble_t * * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< @@ -1362,9 +1923,9 @@ struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_kn; /* "scipy/special/cython_special.pxd":8 * double * - * cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) nogil # <<<<<<<<<<<<<< - * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) nogil - * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) nogil + * cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) noexcept nogil # <<<<<<<<<<<<<< + * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) noexcept nogil + * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) noexcept nogil */ struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_jn { int __pyx_n; @@ -1377,10 +1938,10 @@ struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_jn /* "scipy/special/cython_special.pxd":9 * - * cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) nogil - * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) nogil # <<<<<<<<<<<<<< - * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) nogil - * cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) nogil + * cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) noexcept nogil + * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) noexcept nogil # <<<<<<<<<<<<<< + * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) noexcept nogil + * cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) noexcept nogil */ struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_yn { int __pyx_n; @@ -1392,10 +1953,10 @@ struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_yn }; /* "scipy/special/cython_special.pxd":10 - * cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) nogil - * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) nogil - * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) nogil # <<<<<<<<<<<<<< - * cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) nogil + * cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) noexcept nogil + * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) noexcept nogil + * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) noexcept nogil # <<<<<<<<<<<<<< + * cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) noexcept nogil * */ struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_in { @@ -1408,9 +1969,9 @@ struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_in }; /* "scipy/special/cython_special.pxd":11 - * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) nogil - * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) nogil - * cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) nogil # <<<<<<<<<<<<<< + * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) noexcept nogil + * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) noexcept nogil + * cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) noexcept nogil # <<<<<<<<<<<<<< * * ctypedef fused Dd_number_t: */ @@ -1423,8 +1984,8 @@ struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_kn int derivative; }; -/* "View.MemoryView":106 - * +/* "View.MemoryView":114 + * @cython.collection_type("sequence") * @cname("__pyx_array") * cdef class array: # <<<<<<<<<<<<<< * @@ -1448,7 +2009,7 @@ struct __pyx_array_obj { }; -/* "View.MemoryView":280 +/* "View.MemoryView":302 * * @cname('__pyx_MemviewEnum') * cdef class Enum(object): # <<<<<<<<<<<<<< @@ -1461,10 +2022,10 @@ struct __pyx_MemviewEnum_obj { }; -/* "View.MemoryView":331 +/* "View.MemoryView":337 * * @cname('__pyx_memoryview') - * cdef class memoryview(object): # <<<<<<<<<<<<<< + * cdef class memoryview: # <<<<<<<<<<<<<< * * cdef object obj */ @@ -1475,8 +2036,7 @@ struct __pyx_memoryview_obj { PyObject *_size; PyObject *_array_interface; PyThread_type_lock lock; - __pyx_atomic_int acquisition_count[2]; - __pyx_atomic_int *acquisition_count_aligned_p; + __pyx_atomic_int_type acquisition_count; Py_buffer view; int flags; int dtype_is_object; @@ -1484,8 +2044,8 @@ struct __pyx_memoryview_obj { }; -/* "View.MemoryView":967 - * +/* "View.MemoryView":952 + * @cython.collection_type("sequence") * @cname('__pyx_memoryviewslice') * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<< * "Internal class for passing memoryview slices to Python" @@ -1501,8 +2061,8 @@ struct __pyx_memoryviewslice_obj { -/* "View.MemoryView":106 - * +/* "View.MemoryView":114 + * @cython.collection_type("sequence") * @cname("__pyx_array") * cdef class array: # <<<<<<<<<<<<<< * @@ -1515,10 +2075,10 @@ struct __pyx_vtabstruct_array { static struct __pyx_vtabstruct_array *__pyx_vtabptr_array; -/* "View.MemoryView":331 +/* "View.MemoryView":337 * * @cname('__pyx_memoryview') - * cdef class memoryview(object): # <<<<<<<<<<<<<< + * cdef class memoryview: # <<<<<<<<<<<<<< * * cdef object obj */ @@ -1531,12 +2091,13 @@ struct __pyx_vtabstruct_memoryview { PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *); PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *); PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *); + PyObject *(*_get_base)(struct __pyx_memoryview_obj *); }; static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview; -/* "View.MemoryView":967 - * +/* "View.MemoryView":952 + * @cython.collection_type("sequence") * @cname('__pyx_memoryviewslice') * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<< * "Internal class for passing memoryview slices to Python" @@ -1547,6 +2108,7 @@ struct __pyx_vtabstruct__memoryviewslice { struct __pyx_vtabstruct_memoryview __pyx_base; }; static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice; +/* #### Code section: utility_code_proto ### */ /* --- Runtime support code (head) --- */ /* Refnanny.proto */ @@ -1555,11 +2117,11 @@ static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice; #endif #if CYTHON_REFNANNY typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); void (*FinishContext)(void**); } __Pyx_RefNannyAPIStruct; static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; @@ -1569,28 +2131,40 @@ static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice; #define __Pyx_RefNannySetupContext(name, acquire_gil)\ if (acquire_gil) {\ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ PyGILState_Release(__pyx_gilstate_save);\ } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ } #else #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__)) + #define __Pyx_RefNannyFinishContextNogil() __Pyx_RefNannyFinishContext() #endif + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } #define __Pyx_RefNannyFinishContext()\ __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) #else #define __Pyx_RefNannyDeclarations #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() #define __Pyx_RefNannyFinishContext() #define __Pyx_INCREF(r) Py_INCREF(r) #define __Pyx_DECREF(r) Py_DECREF(r) @@ -1601,6 +2175,10 @@ static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice; #define __Pyx_XGOTREF(r) #define __Pyx_XGIVEREF(r) #endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) #define __Pyx_XDECREF_SET(r, v) do {\ PyObject *tmp = (PyObject *) r;\ r = v; __Pyx_XDECREF(tmp);\ @@ -1612,6 +2190,57 @@ static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice; #define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) #define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + /* PyObjectGetAttrStr.proto */ #if CYTHON_USE_TYPE_SLOTS static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); @@ -1619,9 +2248,76 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject #define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) #endif +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + /* GetBuiltinName.proto */ static PyObject *__Pyx_GetBuiltinName(PyObject *name); +/* TupleAndListFromArray.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto */ +#include + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_VARARGS(args, i) PySequence_GetItem(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i) +#else + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GetItem(args, i) +#endif +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_NewRef_VARARGS(arg) __Pyx_NewRef(arg) + #define __Pyx_Arg_XDECREF_VARARGS(arg) Py_XDECREF(arg) +#else + #define __Pyx_Arg_NewRef_VARARGS(arg) arg + #define __Pyx_Arg_XDECREF_VARARGS(arg) +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_Arg_FASTCALL(args, i) args[i] + #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif + #define __Pyx_Arg_NewRef_FASTCALL(arg) arg /* no-op, __Pyx_Arg_FASTCALL is direct and this needs + to have the same reference counting */ + #define __Pyx_Arg_XDECREF_FASTCALL(arg) +#else + #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS + #define __Pyx_Arg_NewRef_FASTCALL(arg) __Pyx_Arg_NewRef_VARARGS(arg) + #define __Pyx_Arg_XDECREF_FASTCALL(arg) __Pyx_Arg_XDECREF_VARARGS(arg) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start) +#else +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + /* RaiseArgTupleInvalid.proto */ static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); @@ -1630,120 +2326,53 @@ static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name); /* ArgTypeTest.proto */ #define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ - ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 :\ + ((likely(__Pyx_IS_TYPE(obj, type) | (none_allowed && (obj == Py_None)))) ? 1 :\ __Pyx__ArgTypeTest(obj, type, name, exact)) static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); -/* IsLittleEndian.proto */ -static CYTHON_INLINE int __Pyx_Is_Little_Endian(void); - -/* BufferFormatCheck.proto */ -static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); -static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, - __Pyx_BufFmt_StackElem* stack, - __Pyx_TypeInfo* type); - -/* BufferGetAndValidate.proto */ -#define __Pyx_GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)\ - ((obj == Py_None || obj == NULL) ?\ - (__Pyx_ZeroBuffer(buf), 0) :\ - __Pyx__GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)) -static int __Pyx__GetBufferAndValidate(Py_buffer* buf, PyObject* obj, - __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); -static void __Pyx_ZeroBuffer(Py_buffer* buf); -static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); -static Py_ssize_t __Pyx_minusones[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static Py_ssize_t __Pyx_zeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* GetModuleGlobalName.proto */ -#if CYTHON_USE_DICT_VERSIONS -#define __Pyx_GetModuleGlobalName(var, name) do {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ - (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ - __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} while(0) -#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ - PY_UINT64_T __pyx_dict_version;\ - PyObject *__pyx_dict_cached_value;\ - (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} while(0) -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); -#else -#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) -#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); -#endif - -/* PyCFunctionFastCall.proto */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); -#else -#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) -#endif +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /* PyFunctionFastCall.proto */ #if CYTHON_FAST_PYCALL +#if !CYTHON_VECTORCALL #define __Pyx_PyFunction_FastCall(func, args, nargs)\ __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -#if 1 || PY_VERSION_HEX < 0x030600B1 static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#else -#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) #endif #define __Pyx_BUILD_ASSERT_EXPR(cond)\ (sizeof(char [1 - 2*!(cond)]) - 1) #ifndef Py_MEMBER_SIZE #define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) #endif -#if CYTHON_FAST_PYCALL - static size_t __pyx_pyframe_localsplus_offset = 0; +#if !CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03080000 #include "frameobject.h" -#if PY_VERSION_HEX >= 0x030b00a6 +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API #ifndef Py_BUILD_CORE #define Py_BUILD_CORE 1 #endif #include "internal/pycore_frame.h" #endif + #define __Pxy_PyFrame_Initialize_Offsets() + #define __Pyx_PyFrame_GetLocalsplus(frame) ((frame)->f_localsplus) +#else + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" #define __Pxy_PyFrame_Initialize_Offsets()\ ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) #define __Pyx_PyFrame_GetLocalsplus(frame)\ (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif // CYTHON_FAST_PYCALL +#endif +#endif #endif /* PyObjectCall.proto */ @@ -1753,122 +2382,36 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg #define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) #endif -/* PyObjectCall2Args.proto */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); - /* PyObjectCallMethO.proto */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); #endif -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); +/* PyObjectFastCall.proto */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs); -/* MemviewSliceInit.proto */ -#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d -#define __Pyx_MEMVIEW_DIRECT 1 -#define __Pyx_MEMVIEW_PTR 2 -#define __Pyx_MEMVIEW_FULL 4 -#define __Pyx_MEMVIEW_CONTIG 8 -#define __Pyx_MEMVIEW_STRIDED 16 -#define __Pyx_MEMVIEW_FOLLOW 32 -#define __Pyx_IS_C_CONTIG 1 -#define __Pyx_IS_F_CONTIG 2 -static int __Pyx_init_memviewslice( - struct __pyx_memoryview_obj *memview, - int ndim, - __Pyx_memviewslice *memviewslice, - int memview_is_new_reference); -static CYTHON_INLINE int __pyx_add_acquisition_count_locked( - __pyx_atomic_int *acquisition_count, PyThread_type_lock lock); -static CYTHON_INLINE int __pyx_sub_acquisition_count_locked( - __pyx_atomic_int *acquisition_count, PyThread_type_lock lock); -#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p) -#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview)) -#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__) -#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__) -static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int); -static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int); - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* GetTopmostException.proto */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); -#endif - -/* SaveResetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -#else -#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) -#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) -#endif - -/* PyErrExceptionMatches.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); -#else -#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) -#endif +/* RaiseUnexpectedTypeError.proto */ +static int __Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj); -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +/* GCCDiagnostics.proto */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC #endif -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); +/* BuildPyUnicode.proto */ +static PyObject* __Pyx_PyUnicode_BuildFromAscii(Py_ssize_t ulength, char* chars, int clength, + int prepend_sign, char padding_char); -/* IncludeStringH.proto */ -#include +/* CIntToPyUnicode.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_int(int value, Py_ssize_t width, char padding_char, char format_char); -/* BytesEquals.proto */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); +/* CIntToPyUnicode.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_Py_ssize_t(Py_ssize_t value, Py_ssize_t width, char padding_char, char format_char); -/* UnicodeEquals.proto */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); +/* JoinPyUnicode.proto */ +static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength, + Py_UCS4 max_char); /* StrEquals.proto */ #if PY_MAJOR_VERSION >= 3 @@ -1877,14 +2420,29 @@ static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int #define __Pyx_PyString_Equals __Pyx_PyBytes_Equals #endif -/* DivInt[Py_ssize_t].proto */ -static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); - -/* UnaryNegOverflows.proto */ -#define UNARY_NEG_WOULD_OVERFLOW(x)\ - (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x))) +/* PyObjectFormatSimple.proto */ +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + PyObject_Format(s, f)) +#elif PY_MAJOR_VERSION < 3 + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + likely(PyString_CheckExact(s)) ? PyUnicode_FromEncodedObject(s, NULL, "strict") :\ + PyObject_Format(s, f)) +#elif CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + likely(PyLong_CheckExact(s)) ? PyLong_Type.tp_repr(s) :\ + likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_repr(s) :\ + PyObject_Format(s, f)) +#else + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + PyObject_Format(s, f)) +#endif -static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ +CYTHON_UNUSED static int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *); /*proto*/ /* GetAttr.proto */ static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); @@ -1911,36 +2469,107 @@ static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, int wraparound, int boundscheck); +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + /* ObjectGetItem.proto */ #if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key); +static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key); #else #define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) #endif -/* decode_c_string_utf16.proto */ -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = 0; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16LE(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = -1; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16BE(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = 1; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} +/* KeywordStringCheck.proto */ +static int __Pyx_CheckKeywordStrings(PyObject *kw, const char* function_name, int kw_allowed); + +/* DivInt[Py_ssize_t].proto */ +static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); -/* decode_c_string.proto */ -static CYTHON_INLINE PyObject* __Pyx_decode_c_string( - const char* cstring, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); +/* UnaryNegOverflows.proto */ +#define __Pyx_UNARY_NEG_WOULD_OVERFLOW(x)\ + (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x))) /* GetAttr3.proto */ static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) do {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* AssertionsEnabled.proto */ +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define __Pyx_init_assertions_enabled() (0) + #define __pyx_assertions_enabled() (1) +#elif CYTHON_COMPILING_IN_LIMITED_API || (CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030C0000) + static int __pyx_assertions_enabled_flag; + #define __pyx_assertions_enabled() (__pyx_assertions_enabled_flag) + static int __Pyx_init_assertions_enabled(void) { + PyObject *builtins, *debug, *debug_str; + int flag; + builtins = PyEval_GetBuiltins(); + if (!builtins) goto bad; + debug_str = PyUnicode_FromStringAndSize("__debug__", 9); + if (!debug_str) goto bad; + debug = PyObject_GetItem(builtins, debug_str); + Py_DECREF(debug_str); + if (!debug) goto bad; + flag = PyObject_IsTrue(debug); + Py_DECREF(debug); + if (flag == -1) goto bad; + __pyx_assertions_enabled_flag = flag; + return 0; + bad: + __pyx_assertions_enabled_flag = 1; + return -1; + } +#else + #define __Pyx_init_assertions_enabled() (0) + #define __pyx_assertions_enabled() (!Py_OptimizeFlag) +#endif + /* RaiseTooManyValuesToUnpack.proto */ static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); @@ -1953,6 +2582,30 @@ static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); /* ExtTypeTest.proto */ static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + /* SwapException.proto */ #if CYTHON_FAST_THREAD_STATE #define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) @@ -1964,20 +2617,30 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, /* Import.proto */ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); +/* ImportDottedModule.proto */ +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple); +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple); +#endif + /* FastTypeChecks.proto */ #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); #else #define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) #define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) #define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) #endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) #define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) -static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ +CYTHON_UNUSED static int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ /* ListCompAppend.proto */ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { @@ -1985,7 +2648,11 @@ static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { Py_ssize_t len = Py_SIZE(list); if (likely(L->allocated > len)) { Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else PyList_SET_ITEM(list, len, x); + #endif __Pyx_SET_SIZE(list, len + 1); return 0; } @@ -1995,45 +2662,21 @@ static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { #define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) #endif -/* PyIntBinop.proto */ -#if !CYTHON_COMPILING_IN_PYPY -static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); -#else -#define __Pyx_PyInt_AddObjC(op1, op2, intval, inplace, zerodivision_check)\ - (inplace ? PyNumber_InPlaceAdd(op1, op2) : PyNumber_Add(op1, op2)) -#endif - -/* ListExtend.proto */ -static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) { -#if CYTHON_COMPILING_IN_CPYTHON - PyObject* none = _PyList_Extend((PyListObject*)L, v); - if (unlikely(!none)) - return -1; - Py_DECREF(none); - return 0; -#else - return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v); -#endif -} - -/* ListAppend.proto */ -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { - PyListObject* L = (PyListObject*) list; - Py_ssize_t len = Py_SIZE(list); - if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { - Py_INCREF(x); - PyList_SET_ITEM(list, len, x); - __Pyx_SET_SIZE(list, len + 1); - return 0; - } - return PyList_Append(list, x); -} -#else -#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) -#endif +/* PySequenceMultiply.proto */ +#define __Pyx_PySequence_Multiply_Left(mul, seq) __Pyx_PySequence_Multiply(seq, mul) +static CYTHON_INLINE PyObject* __Pyx_PySequence_Multiply(PyObject *seq, Py_ssize_t mul); -/* None.proto */ +/* SetItemInt.proto */ +#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) :\ + __Pyx_SetItemInt_Generic(o, to_py_func(i), v))) +static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v); +static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, + int is_list, int wraparound, int boundscheck); + +/* RaiseUnboundLocalError.proto */ static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname); /* DivInt[long].proto */ @@ -2049,7 +2692,32 @@ static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* s static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); /* HasAttr.proto */ +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 +#define __Pyx_HasAttr(o, n) PyObject_HasAttrWithError(o, n) +#else static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); +#endif + +/* IsLittleEndian.proto */ +static CYTHON_INLINE int __Pyx_Is_Little_Endian(void); + +/* BufferFormatCheck.proto */ +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type); + +/* BufferGetAndValidate.proto */ +#define __Pyx_GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)\ + ((obj == Py_None || obj == NULL) ?\ + (__Pyx_ZeroBuffer(buf), 0) :\ + __Pyx__GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)) +static int __Pyx__GetBufferAndValidate(Py_buffer* buf, PyObject* obj, + __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); +static void __Pyx_ZeroBuffer(Py_buffer* buf); +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); +static Py_ssize_t __Pyx_minusones[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; +static Py_ssize_t __Pyx_zeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; /* PyObject_GenericGetAttrNoDict.proto */ #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 @@ -2065,36 +2733,217 @@ static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_nam #define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr #endif +/* IncludeStructmemberH.proto */ +#include + +/* FixUpExtensionType.proto */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); +#endif + +/* PyObjectCallNoArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); + +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + +/* PyObjectCallMethod0.proto */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); + +/* ValidateBasesTuple.proto */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases); +#endif + +/* PyType_Ready.proto */ +CYTHON_UNUSED static int __Pyx_PyType_Ready(PyTypeObject *t); + /* SetVTable.proto */ -static int __Pyx_SetVtable(PyObject *dict, void *vtable); +static int __Pyx_SetVtable(PyTypeObject* typeptr , void* vtable); -/* PyObjectGetAttrStrNoError.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); +/* GetVTable.proto */ +static void* __Pyx_GetVtable(PyTypeObject *type); + +/* MergeVTables.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_MergeVtables(PyTypeObject *type); +#endif /* SetupReduce.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API static int __Pyx_setup_reduce(PyObject* type_obj); +#endif /* TypeImport.proto */ -#ifndef __PYX_HAVE_RT_ImportType_proto -#define __PYX_HAVE_RT_ImportType_proto -enum __Pyx_ImportType_CheckSize { - __Pyx_ImportType_CheckSize_Error = 0, - __Pyx_ImportType_CheckSize_Warn = 1, - __Pyx_ImportType_CheckSize_Ignore = 2 +#ifndef __PYX_HAVE_RT_ImportType_proto_3_0_10 +#define __PYX_HAVE_RT_ImportType_proto_3_0_10 +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#include +#endif +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || __cplusplus >= 201103L +#define __PYX_GET_STRUCT_ALIGNMENT_3_0_10(s) alignof(s) +#else +#define __PYX_GET_STRUCT_ALIGNMENT_3_0_10(s) sizeof(void*) +#endif +enum __Pyx_ImportType_CheckSize_3_0_10 { + __Pyx_ImportType_CheckSize_Error_3_0_10 = 0, + __Pyx_ImportType_CheckSize_Warn_3_0_10 = 1, + __Pyx_ImportType_CheckSize_Ignore_3_0_10 = 2 }; -static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); +static PyTypeObject *__Pyx_ImportType_3_0_10(PyObject* module, const char *module_name, const char *class_name, size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_3_0_10 check_size); #endif -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +/* FetchSharedCythonModule.proto */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto */ +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); #else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases); +#endif + +/* PyMethodNew.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *typesModule=NULL, *methodType=NULL, *result=NULL; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + typesModule = PyImport_ImportModule("types"); + if (!typesModule) return NULL; + methodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + if (!methodType) return NULL; + result = PyObject_CallFunctionObjArgs(methodType, func, self, NULL); + Py_DECREF(methodType); + return result; +} +#elif PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#else + #define __Pyx_PyMethod_New PyMethod_New #endif -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; +/* PyVectorcallFastCallDict.proto */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_BACKPORT_VECTORCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif + PyObject *func_dict; + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + void *defaults; + int defaults_pyobjects; + size_t defaults_size; + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, + size_t size, + int pyobjects); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_BACKPORT_VECTORCALL +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API +typedef struct { + PyCodeObject* code_object; int code_line; } __Pyx_CodeObjectCacheEntry; struct __Pyx_CodeObjectCache { @@ -2106,6 +2955,7 @@ static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); static PyCodeObject *__pyx_find_code_object(int code_line); static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); +#endif /* AddTraceback.proto */ static void __Pyx_AddTraceback(const char *funcname, int c_line, @@ -2142,9 +2992,6 @@ static int __pyx_slices_overlap(__Pyx_memviewslice *slice1, __Pyx_memviewslice *slice2, int ndim, size_t itemsize); -/* Capsule.proto */ -static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig); - /* TypeInfoCompare.proto */ static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b); @@ -2165,11 +3012,6 @@ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_dou /* ObjectToMemviewSlice.proto */ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int64_t(PyObject *, int writable_flag); -/* GCCDiagnostics.proto */ -#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -#define __Pyx_HAS_GCC_DIAGNOSTIC -#endif - /* RealImag.proto */ #if CYTHON_CCOMPLEX #ifdef __cplusplus @@ -2193,7 +3035,7 @@ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_n #endif /* Arithmetic.proto */ -#if CYTHON_CCOMPLEX +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) #define __Pyx_c_eq_float(a, b) ((a)==(b)) #define __Pyx_c_sum_float(a, b) ((a)+(b)) #define __Pyx_c_diff_float(a, b) ((a)-(b)) @@ -2231,7 +3073,7 @@ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_n #endif /* Arithmetic.proto */ -#if CYTHON_CCOMPLEX +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) #define __Pyx_c_eq_double(a, b) ((a)==(b)) #define __Pyx_c_sum_double(a, b) ((a)+(b)) #define __Pyx_c_diff_double(a, b) ((a)-(b)) @@ -2275,6 +3117,31 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, size_t sizeof_dtype, int contig_flag, int dtype_is_object); +/* MemviewSliceInit.proto */ +#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d +#define __Pyx_MEMVIEW_DIRECT 1 +#define __Pyx_MEMVIEW_PTR 2 +#define __Pyx_MEMVIEW_FULL 4 +#define __Pyx_MEMVIEW_CONTIG 8 +#define __Pyx_MEMVIEW_STRIDED 16 +#define __Pyx_MEMVIEW_FOLLOW 32 +#define __Pyx_IS_C_CONTIG 1 +#define __Pyx_IS_F_CONTIG 2 +static int __Pyx_init_memviewslice( + struct __pyx_memoryview_obj *memview, + int ndim, + __Pyx_memviewslice *memviewslice, + int memview_is_new_reference); +static CYTHON_INLINE int __pyx_add_acquisition_count_locked( + __pyx_atomic_int_type *acquisition_count, PyThread_type_lock lock); +static CYTHON_INLINE int __pyx_sub_acquisition_count_locked( + __pyx_atomic_int_type *acquisition_count, PyThread_type_lock lock); +#define __pyx_get_slice_count_pointer(memview) (&memview->acquisition_count) +#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__) +#define __PYX_XCLEAR_MEMVIEW(slice, have_gil) __Pyx_XCLEAR_MEMVIEW(slice, have_gil, __LINE__) +static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int); +static CYTHON_INLINE void __Pyx_XCLEAR_MEMVIEW(__Pyx_memviewslice *, int, int); + /* CIntToPy.proto */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_npy_int64(npy_int64 value); @@ -2296,15 +3163,30 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); /* CIntFromPy.proto */ static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *); +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +static __Pyx_TypeName __Pyx_PyType_GetName(PyTypeObject* tp); +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#else +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + /* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); +static unsigned long __Pyx_get_runtime_version(void); +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); /* FunctionImport.proto */ -static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); +static int __Pyx_ImportFunction_3_0_10(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /* InitStrings.proto */ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); +/* #### Code section: module_declarations ### */ static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *__pyx_v_self); /* proto*/ static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/ static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/ @@ -2313,61 +3195,49 @@ static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memor static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/ static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/ static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/ +static PyObject *__pyx_memoryview__get_base(struct __pyx_memoryview_obj *__pyx_v_self); /* proto*/ static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/ static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/ +static PyObject *__pyx_memoryviewslice__get_base(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto*/ +static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__pyx_v_self); /* proto*/ -/* Module declarations from 'cpython.buffer' */ - -/* Module declarations from 'libc.string' */ +/* Module declarations from "libc.string" */ -/* Module declarations from 'libc.stdio' */ +/* Module declarations from "libc.stdio" */ -/* Module declarations from '__builtin__' */ +/* Module declarations from "__builtin__" */ -/* Module declarations from 'cpython.type' */ -static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; +/* Module declarations from "cpython.type" */ -/* Module declarations from 'cpython' */ +/* Module declarations from "cpython" */ -/* Module declarations from 'cpython.object' */ +/* Module declarations from "cpython.object" */ -/* Module declarations from 'cpython.ref' */ +/* Module declarations from "cpython.ref" */ -/* Module declarations from 'cpython.mem' */ +/* Module declarations from "numpy" */ -/* Module declarations from 'numpy' */ +/* Module declarations from "numpy" */ -/* Module declarations from 'numpy' */ -static PyTypeObject *__pyx_ptype_5numpy_dtype = 0; -static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0; -static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0; -static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0; -static PyTypeObject *__pyx_ptype_5numpy_generic = 0; -static PyTypeObject *__pyx_ptype_5numpy_number = 0; -static PyTypeObject *__pyx_ptype_5numpy_integer = 0; -static PyTypeObject *__pyx_ptype_5numpy_signedinteger = 0; -static PyTypeObject *__pyx_ptype_5numpy_unsignedinteger = 0; -static PyTypeObject *__pyx_ptype_5numpy_inexact = 0; -static PyTypeObject *__pyx_ptype_5numpy_floating = 0; -static PyTypeObject *__pyx_ptype_5numpy_complexfloating = 0; -static PyTypeObject *__pyx_ptype_5numpy_flexible = 0; -static PyTypeObject *__pyx_ptype_5numpy_character = 0; -static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0; - -/* Module declarations from 'scipy.special.cython_special' */ +/* Module declarations from "scipy.special.cython_special" */ static double (*__pyx_f_5scipy_7special_14cython_special_pdtr)(double, double, int __pyx_skip_dispatch); /*proto*/ -/* Module declarations from 'libc.math' */ +/* Module declarations from "libc.math" */ + +/* Module declarations from "cython.view" */ -/* Module declarations from 'cython.view' */ +/* Module declarations from "cython.dataclasses" */ -/* Module declarations from 'cython' */ +/* Module declarations from "cython" */ -/* Module declarations from 'pygom.model._tau_leap' */ -static PyTypeObject *__pyx_array_type = 0; -static PyTypeObject *__pyx_MemviewEnum_type = 0; -static PyTypeObject *__pyx_memoryview_type = 0; -static PyTypeObject *__pyx_memoryviewslice_type = 0; +/* Module declarations from "pygom.model._tau_leap" */ +static PyObject *__pyx_collections_abc_Sequence = 0; static PyObject *generic = 0; static PyObject *strided = 0; static PyObject *indirect = 0; @@ -2375,12 +3245,12 @@ static PyObject *contiguous = 0; static PyObject *indirect_contiguous = 0; static int __pyx_memoryview_thread_locks_used; static PyThread_type_lock __pyx_memoryview_thread_locks[8]; +static int __pyx_array_allocate_buffer(struct __pyx_array_obj *); /*proto*/ static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/ -static void *__pyx_align_pointer(void *, size_t); /*proto*/ static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/ static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/ static PyObject *_unellipsify(PyObject *, int); /*proto*/ -static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/ +static int assert_direct_dimensions(Py_ssize_t *, int); /*proto*/ static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/ static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/ static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/ @@ -2398,8 +3268,9 @@ static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /* static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/ static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/ static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/ -static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/ -static int __pyx_memoryview_err(PyObject *, char *); /*proto*/ +static int __pyx_memoryview_err_dim(PyObject *, PyObject *, int); /*proto*/ +static int __pyx_memoryview_err(PyObject *, PyObject *); /*proto*/ +static int __pyx_memoryview_err_no_memory(void); /*proto*/ static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/ static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/ static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/ @@ -2408,34 +3279,51 @@ static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/ static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/ static PyObject *__pyx_unpickle_Enum__set_state(struct __pyx_MemviewEnum_obj *, PyObject *); /*proto*/ +/* #### Code section: typeinfo ### */ static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t = { "float64_t", NULL, sizeof(__pyx_t_5numpy_float64_t), { 0 }, 0, 'R', 0, 0 }; -static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t = { "int64_t", NULL, sizeof(__pyx_t_5numpy_int64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int64_t), 0 }; +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t = { "int64_t", NULL, sizeof(__pyx_t_5numpy_int64_t), { 0 }, 0, __PYX_IS_UNSIGNED(__pyx_t_5numpy_int64_t) ? 'U' : 'I', __PYX_IS_UNSIGNED(__pyx_t_5numpy_int64_t), 0 }; static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 }; +/* #### Code section: before_global_var ### */ #define __Pyx_MODULE_NAME "pygom.model._tau_leap" extern int __pyx_module_is_main_pygom__model___tau_leap; int __pyx_module_is_main_pygom__model___tau_leap = 0; -/* Implementation of 'pygom.model._tau_leap' */ +/* Implementation of "pygom.model._tau_leap" */ +/* #### Code section: global_var ### */ static PyObject *__pyx_builtin_range; -static PyObject *__pyx_builtin_ImportError; +static PyObject *__pyx_builtin___import__; static PyObject *__pyx_builtin_ValueError; static PyObject *__pyx_builtin_MemoryError; static PyObject *__pyx_builtin_enumerate; static PyObject *__pyx_builtin_TypeError; +static PyObject *__pyx_builtin_AssertionError; static PyObject *__pyx_builtin_Ellipsis; static PyObject *__pyx_builtin_id; static PyObject *__pyx_builtin_IndexError; +static PyObject *__pyx_builtin_ImportError; +/* #### Code section: string_decls ### */ +static const char __pyx_k_[] = ": "; static const char __pyx_k_O[] = "O"; static const char __pyx_k_c[] = "c"; static const char __pyx_k_i[] = "i"; static const char __pyx_k_j[] = "j"; static const char __pyx_k_x[] = "x"; +static const char __pyx_k__2[] = "."; +static const char __pyx_k__3[] = "*"; +static const char __pyx_k__6[] = "'"; +static const char __pyx_k__7[] = ")"; +static const char __pyx_k_gc[] = "gc"; static const char __pyx_k_id[] = "id"; static const char __pyx_k_mu[] = "mu"; static const char __pyx_k_np[] = "np"; +static const char __pyx_k__24[] = "?"; +static const char __pyx_k_abc[] = "abc"; +static const char __pyx_k_and[] = " and "; +static const char __pyx_k_got[] = " (got "; static const char __pyx_k_new[] = "__new__"; static const char __pyx_k_obj[] = "obj"; static const char __pyx_k_sum[] = "sum"; +static const char __pyx_k_sys[] = "sys"; static const char __pyx_k_base[] = "base"; static const char __pyx_k_dict[] = "__dict__"; static const char __pyx_k_main[] = "__main__"; @@ -2445,6 +3333,7 @@ static const char __pyx_k_ndim[] = "ndim"; static const char __pyx_k_pack[] = "pack"; static const char __pyx_k_safe[] = "safe"; static const char __pyx_k_size[] = "size"; +static const char __pyx_k_spec[] = "__spec__"; static const char __pyx_k_step[] = "step"; static const char __pyx_k_stop[] = "stop"; static const char __pyx_k_test[] = "__test__"; @@ -2453,11 +3342,13 @@ static const char __pyx_k_class[] = "__class__"; static const char __pyx_k_count[] = "count"; static const char __pyx_k_error[] = "error"; static const char __pyx_k_flags[] = "flags"; +static const char __pyx_k_index[] = "index"; static const char __pyx_k_numpy[] = "numpy"; static const char __pyx_k_range[] = "range"; static const char __pyx_k_rates[] = "rates"; static const char __pyx_k_shape[] = "shape"; static const char __pyx_k_start[] = "start"; +static const char __pyx_k_enable[] = "enable"; static const char __pyx_k_encode[] = "encode"; static const char __pyx_k_format[] = "format"; static const char __pyx_k_import[] = "__import__"; @@ -2469,6 +3360,7 @@ static const char __pyx_k_unpack[] = "unpack"; static const char __pyx_k_update[] = "update"; static const char __pyx_k_x_view[] = "x_view"; static const char __pyx_k_cdf_val[] = "cdf_val"; +static const char __pyx_k_disable[] = "disable"; static const char __pyx_k_epsilon[] = "epsilon"; static const char __pyx_k_fortran[] = "fortran"; static const char __pyx_k_max_cdf[] = "max_cdf"; @@ -2476,12 +3368,15 @@ static const char __pyx_k_memview[] = "memview"; static const char __pyx_k_n_rates[] = "n_rates"; static const char __pyx_k_new_cdf[] = "new_cdf"; static const char __pyx_k_Ellipsis[] = "Ellipsis"; +static const char __pyx_k_Sequence[] = "Sequence"; static const char __pyx_k_getstate[] = "__getstate__"; static const char __pyx_k_itemsize[] = "itemsize"; static const char __pyx_k_pyx_type[] = "__pyx_type"; +static const char __pyx_k_register[] = "register"; static const char __pyx_k_setstate[] = "__setstate__"; static const char __pyx_k_TypeError[] = "TypeError"; static const char __pyx_k_enumerate[] = "enumerate"; +static const char __pyx_k_isenabled[] = "isenabled"; static const char __pyx_k_pyx_state[] = "__pyx_state"; static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; static const char __pyx_k_tau_scale[] = "tau_scale"; @@ -2494,164 +3389,62 @@ static const char __pyx_k_total_rate[] = "total_rate"; static const char __pyx_k_ImportError[] = "ImportError"; static const char __pyx_k_MemoryError[] = "MemoryError"; static const char __pyx_k_PickleError[] = "PickleError"; +static const char __pyx_k_collections[] = "collections"; static const char __pyx_k_n_reactants[] = "n_reactants"; +static const char __pyx_k_initializing[] = "_initializing"; +static const char __pyx_k_is_coroutine[] = "_is_coroutine"; static const char __pyx_k_pyx_checksum[] = "__pyx_checksum"; static const char __pyx_k_reactant_mat[] = "reactant_mat"; -static const char __pyx_k_stringsource[] = "stringsource"; -static const char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer"; +static const char __pyx_k_stringsource[] = ""; +static const char __pyx_k_version_info[] = "version_info"; +static const char __pyx_k_class_getitem[] = "__class_getitem__"; static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; +static const char __pyx_k_AssertionError[] = "AssertionError"; static const char __pyx_k_View_MemoryView[] = "View.MemoryView"; static const char __pyx_k_allocate_buffer[] = "allocate_buffer"; +static const char __pyx_k_collections_abc[] = "collections.abc"; static const char __pyx_k_dtype_is_object[] = "dtype_is_object"; static const char __pyx_k_pyx_PickleError[] = "__pyx_PickleError"; static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; static const char __pyx_k_pyx_unpickle_Enum[] = "__pyx_unpickle_Enum"; static const char __pyx_k_reactant_mat_view[] = "reactant_mat_view"; +static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines"; static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; static const char __pyx_k_strided_and_direct[] = ""; static const char __pyx_k_strided_and_indirect[] = ""; +static const char __pyx_k_Invalid_shape_in_axis[] = "Invalid shape in axis "; static const char __pyx_k_contiguous_and_direct[] = ""; static const char __pyx_k_pygom_model__tau_leap[] = "pygom.model._tau_leap"; +static const char __pyx_k_Cannot_index_with_type[] = "Cannot index with type '"; static const char __pyx_k_MemoryView_of_r_object[] = ""; static const char __pyx_k_MemoryView_of_r_at_0x_x[] = ""; static const char __pyx_k_contiguous_and_indirect[] = ""; static const char __pyx_k_cy_test_tau_leap_safety[] = "_cy_test_tau_leap_safety"; -static const char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'"; -static const char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d."; -static const char __pyx_k_pygom_model__tau_leap_pyx[] = "pygom/model/_tau_leap.pyx"; +static const char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct"; +static const char __pyx_k_pygom_model__tau_leap_pyx[] = "pygom\\model\\_tau_leap.pyx"; +static const char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)"; +static const char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)"; static const char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array"; static const char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data."; static const char __pyx_k_strided_and_direct_or_indirect[] = ""; static const char __pyx_k_numpy_core_multiarray_failed_to[] = "numpy.core.multiarray failed to import"; +static const char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced"; static const char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides"; static const char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory."; static const char __pyx_k_Cannot_assign_to_read_only_memor[] = "Cannot assign to read-only memoryview"; static const char __pyx_k_Cannot_create_writable_memory_vi[] = "Cannot create writable memory view from read-only memoryview"; +static const char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions"; static const char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array"; -static const char __pyx_k_Incompatible_checksums_0x_x_vs_0[] = "Incompatible checksums (0x%x vs (0xb068931, 0x82a3537, 0x6ae9995) = (name))"; +static const char __pyx_k_Incompatible_checksums_0x_x_vs_0[] = "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))"; static const char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported"; -static const char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s"; -static const char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)"; +static const char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got "; +static const char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis "; static const char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object"; -static const char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)"; +static const char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension "; static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; static const char __pyx_k_numpy_core_umath_failed_to_impor[] = "numpy.core.umath failed to import"; static const char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides."; -static PyObject *__pyx_n_s_ASCII; -static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri; -static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is; -static PyObject *__pyx_kp_s_Cannot_assign_to_read_only_memor; -static PyObject *__pyx_kp_s_Cannot_create_writable_memory_vi; -static PyObject *__pyx_kp_s_Cannot_index_with_type_s; -static PyObject *__pyx_n_s_Ellipsis; -static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr; -static PyObject *__pyx_n_s_ImportError; -static PyObject *__pyx_kp_s_Incompatible_checksums_0x_x_vs_0; -static PyObject *__pyx_n_s_IndexError; -static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte; -static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr; -static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d; -static PyObject *__pyx_n_s_MemoryError; -static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x; -static PyObject *__pyx_kp_s_MemoryView_of_r_object; -static PyObject *__pyx_n_b_O; -static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a; -static PyObject *__pyx_n_s_PickleError; -static PyObject *__pyx_n_s_TypeError; -static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object; -static PyObject *__pyx_n_s_ValueError; -static PyObject *__pyx_n_s_View_MemoryView; -static PyObject *__pyx_n_s_allocate_buffer; -static PyObject *__pyx_n_s_base; -static PyObject *__pyx_n_s_c; -static PyObject *__pyx_n_u_c; -static PyObject *__pyx_n_s_cdf_val; -static PyObject *__pyx_n_s_class; -static PyObject *__pyx_n_s_cline_in_traceback; -static PyObject *__pyx_kp_s_contiguous_and_direct; -static PyObject *__pyx_kp_s_contiguous_and_indirect; -static PyObject *__pyx_n_s_count; -static PyObject *__pyx_n_s_cy_test_tau_leap_safety; -static PyObject *__pyx_n_s_dict; -static PyObject *__pyx_n_s_dtype_is_object; -static PyObject *__pyx_n_s_encode; -static PyObject *__pyx_n_s_enumerate; -static PyObject *__pyx_n_s_epsilon; -static PyObject *__pyx_n_s_error; -static PyObject *__pyx_n_s_flags; -static PyObject *__pyx_n_s_format; -static PyObject *__pyx_n_s_fortran; -static PyObject *__pyx_n_u_fortran; -static PyObject *__pyx_n_s_getstate; -static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi; -static PyObject *__pyx_n_s_i; -static PyObject *__pyx_n_s_id; -static PyObject *__pyx_n_s_import; -static PyObject *__pyx_n_s_itemsize; -static PyObject *__pyx_kp_s_itemsize_0_for_cython_array; -static PyObject *__pyx_n_s_j; -static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_max_cdf; -static PyObject *__pyx_n_s_memview; -static PyObject *__pyx_n_s_mode; -static PyObject *__pyx_n_s_mu; -static PyObject *__pyx_n_s_n_rates; -static PyObject *__pyx_n_s_n_reactants; -static PyObject *__pyx_n_s_name; -static PyObject *__pyx_n_s_name_2; -static PyObject *__pyx_n_s_ndim; -static PyObject *__pyx_n_s_new; -static PyObject *__pyx_n_s_new_cdf; -static PyObject *__pyx_kp_s_no_default___reduce___due_to_non; -static PyObject *__pyx_n_s_np; -static PyObject *__pyx_n_s_numpy; -static PyObject *__pyx_kp_s_numpy_core_multiarray_failed_to; -static PyObject *__pyx_kp_s_numpy_core_umath_failed_to_impor; -static PyObject *__pyx_n_s_obj; -static PyObject *__pyx_n_s_pack; -static PyObject *__pyx_n_s_pickle; -static PyObject *__pyx_n_s_pygom_model__tau_leap; -static PyObject *__pyx_kp_s_pygom_model__tau_leap_pyx; -static PyObject *__pyx_n_s_pyx_PickleError; -static PyObject *__pyx_n_s_pyx_checksum; -static PyObject *__pyx_n_s_pyx_getbuffer; -static PyObject *__pyx_n_s_pyx_result; -static PyObject *__pyx_n_s_pyx_state; -static PyObject *__pyx_n_s_pyx_type; -static PyObject *__pyx_n_s_pyx_unpickle_Enum; -static PyObject *__pyx_n_s_pyx_vtable; -static PyObject *__pyx_n_s_range; -static PyObject *__pyx_n_s_rates; -static PyObject *__pyx_n_s_rates_view; -static PyObject *__pyx_n_s_reactant_mat; -static PyObject *__pyx_n_s_reactant_mat_view; -static PyObject *__pyx_n_s_reduce; -static PyObject *__pyx_n_s_reduce_cython; -static PyObject *__pyx_n_s_reduce_ex; -static PyObject *__pyx_n_s_safe; -static PyObject *__pyx_n_s_setstate; -static PyObject *__pyx_n_s_setstate_cython; -static PyObject *__pyx_n_s_shape; -static PyObject *__pyx_n_s_size; -static PyObject *__pyx_n_s_start; -static PyObject *__pyx_n_s_step; -static PyObject *__pyx_n_s_stop; -static PyObject *__pyx_kp_s_strided_and_direct; -static PyObject *__pyx_kp_s_strided_and_direct_or_indirect; -static PyObject *__pyx_kp_s_strided_and_indirect; -static PyObject *__pyx_kp_s_stringsource; -static PyObject *__pyx_n_s_struct; -static PyObject *__pyx_n_s_sum; -static PyObject *__pyx_n_s_tau_scale; -static PyObject *__pyx_n_s_test; -static PyObject *__pyx_n_s_total_rate; -static PyObject *__pyx_kp_s_unable_to_allocate_array_data; -static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str; -static PyObject *__pyx_n_s_unpack; -static PyObject *__pyx_n_s_update; -static PyObject *__pyx_n_s_x; -static PyObject *__pyx_n_s_x_view; -static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_x, PyArrayObject *__pyx_v_reactant_mat, PyArrayObject *__pyx_v_rates, double __pyx_v_tau_scale, double __pyx_v_epsilon); /* proto */ +/* #### Code section: decls ### */ static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */ static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ static void __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */ @@ -2690,2903 +3483,3660 @@ static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22 static PyObject *__pyx_pf___pyx_memoryview___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf___pyx_memoryview_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ static void __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf___pyx_memoryviewslice___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf___pyx_memoryviewslice_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView___pyx_unpickle_Enum(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state); /* proto */ +static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_x, PyArrayObject *__pyx_v_reactant_mat, PyArrayObject *__pyx_v_rates, double __pyx_v_tau_scale, double __pyx_v_epsilon); /* proto */ static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_int_0; -static PyObject *__pyx_int_1; -static PyObject *__pyx_int_112105877; -static PyObject *__pyx_int_136983863; -static PyObject *__pyx_int_184977713; -static PyObject *__pyx_int_neg_1; -static PyObject *__pyx_tuple_; -static PyObject *__pyx_tuple__2; -static PyObject *__pyx_tuple__3; -static PyObject *__pyx_tuple__4; -static PyObject *__pyx_tuple__5; -static PyObject *__pyx_tuple__6; -static PyObject *__pyx_tuple__7; -static PyObject *__pyx_tuple__8; -static PyObject *__pyx_tuple__9; -static PyObject *__pyx_slice__17; -static PyObject *__pyx_tuple__10; -static PyObject *__pyx_tuple__11; -static PyObject *__pyx_tuple__12; -static PyObject *__pyx_tuple__13; -static PyObject *__pyx_tuple__14; -static PyObject *__pyx_tuple__15; -static PyObject *__pyx_tuple__16; -static PyObject *__pyx_tuple__18; -static PyObject *__pyx_tuple__19; -static PyObject *__pyx_tuple__20; -static PyObject *__pyx_tuple__21; -static PyObject *__pyx_tuple__22; -static PyObject *__pyx_tuple__24; -static PyObject *__pyx_tuple__25; -static PyObject *__pyx_tuple__26; -static PyObject *__pyx_tuple__27; -static PyObject *__pyx_tuple__28; -static PyObject *__pyx_tuple__29; -static PyObject *__pyx_codeobj__23; -static PyObject *__pyx_codeobj__30; -/* Late includes */ - -/* "pygom/model/_tau_leap.pyx":11 - * @cython.wraparound(False) # Deactivate negative indexing. - * @cython.cdivision(True) # Deactivate the div 0 error checking - * def _cy_test_tau_leap_safety(np.ndarray[np.float64_t] x, # <<<<<<<<<<<<<< - * np.ndarray[np.int64_t, ndim=2] reactant_mat, - * np.ndarray[np.float64_t] rates, +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + #ifdef __Pyx_CyFunction_USED + PyTypeObject *__pyx_CyFunctionType; + #endif + #ifdef __Pyx_FusedFunction_USED + PyTypeObject *__pyx_FusedFunctionType; + #endif + #ifdef __Pyx_Generator_USED + PyTypeObject *__pyx_GeneratorType; + #endif + #ifdef __Pyx_IterableCoroutine_USED + PyTypeObject *__pyx_IterableCoroutineType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineAwaitType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineType; + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + PyTypeObject *__pyx_ptype_7cpython_4type_type; + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + PyTypeObject *__pyx_ptype_5numpy_dtype; + PyTypeObject *__pyx_ptype_5numpy_flatiter; + PyTypeObject *__pyx_ptype_5numpy_broadcast; + PyTypeObject *__pyx_ptype_5numpy_ndarray; + PyTypeObject *__pyx_ptype_5numpy_generic; + PyTypeObject *__pyx_ptype_5numpy_number; + PyTypeObject *__pyx_ptype_5numpy_integer; + PyTypeObject *__pyx_ptype_5numpy_signedinteger; + PyTypeObject *__pyx_ptype_5numpy_unsignedinteger; + PyTypeObject *__pyx_ptype_5numpy_inexact; + PyTypeObject *__pyx_ptype_5numpy_floating; + PyTypeObject *__pyx_ptype_5numpy_complexfloating; + PyTypeObject *__pyx_ptype_5numpy_flexible; + PyTypeObject *__pyx_ptype_5numpy_character; + PyTypeObject *__pyx_ptype_5numpy_ufunc; + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + PyObject *__pyx_type___pyx_array; + PyObject *__pyx_type___pyx_MemviewEnum; + PyObject *__pyx_type___pyx_memoryview; + PyObject *__pyx_type___pyx_memoryviewslice; + #endif + PyTypeObject *__pyx_array_type; + PyTypeObject *__pyx_MemviewEnum_type; + PyTypeObject *__pyx_memoryview_type; + PyTypeObject *__pyx_memoryviewslice_type; + PyObject *__pyx_kp_u_; + PyObject *__pyx_n_s_ASCII; + PyObject *__pyx_kp_s_All_dimensions_preceding_dimensi; + PyObject *__pyx_n_s_AssertionError; + PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri; + PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is; + PyObject *__pyx_kp_s_Cannot_assign_to_read_only_memor; + PyObject *__pyx_kp_s_Cannot_create_writable_memory_vi; + PyObject *__pyx_kp_u_Cannot_index_with_type; + PyObject *__pyx_kp_s_Cannot_transpose_memoryview_with; + PyObject *__pyx_kp_s_Dimension_d_is_not_direct; + PyObject *__pyx_n_s_Ellipsis; + PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr; + PyObject *__pyx_n_s_ImportError; + PyObject *__pyx_kp_s_Incompatible_checksums_0x_x_vs_0; + PyObject *__pyx_n_s_IndexError; + PyObject *__pyx_kp_s_Index_out_of_bounds_axis_d; + PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte; + PyObject *__pyx_kp_u_Invalid_mode_expected_c_or_fortr; + PyObject *__pyx_kp_u_Invalid_shape_in_axis; + PyObject *__pyx_n_s_MemoryError; + PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x; + PyObject *__pyx_kp_s_MemoryView_of_r_object; + PyObject *__pyx_n_b_O; + PyObject *__pyx_kp_u_Out_of_bounds_on_buffer_access_a; + PyObject *__pyx_n_s_PickleError; + PyObject *__pyx_n_s_Sequence; + PyObject *__pyx_kp_s_Step_may_not_be_zero_axis_d; + PyObject *__pyx_n_s_TypeError; + PyObject *__pyx_kp_s_Unable_to_convert_item_to_object; + PyObject *__pyx_n_s_ValueError; + PyObject *__pyx_n_s_View_MemoryView; + PyObject *__pyx_kp_u__2; + PyObject *__pyx_n_s__24; + PyObject *__pyx_n_s__3; + PyObject *__pyx_kp_u__6; + PyObject *__pyx_kp_u__7; + PyObject *__pyx_n_s_abc; + PyObject *__pyx_n_s_allocate_buffer; + PyObject *__pyx_kp_u_and; + PyObject *__pyx_n_s_asyncio_coroutines; + PyObject *__pyx_n_s_base; + PyObject *__pyx_n_s_c; + PyObject *__pyx_n_u_c; + PyObject *__pyx_n_s_cdf_val; + PyObject *__pyx_n_s_class; + PyObject *__pyx_n_s_class_getitem; + PyObject *__pyx_n_s_cline_in_traceback; + PyObject *__pyx_n_s_collections; + PyObject *__pyx_kp_s_collections_abc; + PyObject *__pyx_kp_s_contiguous_and_direct; + PyObject *__pyx_kp_s_contiguous_and_indirect; + PyObject *__pyx_n_s_count; + PyObject *__pyx_n_s_cy_test_tau_leap_safety; + PyObject *__pyx_n_s_dict; + PyObject *__pyx_kp_u_disable; + PyObject *__pyx_n_s_dtype_is_object; + PyObject *__pyx_kp_u_enable; + PyObject *__pyx_n_s_encode; + PyObject *__pyx_n_s_enumerate; + PyObject *__pyx_n_s_epsilon; + PyObject *__pyx_n_s_error; + PyObject *__pyx_n_s_flags; + PyObject *__pyx_n_s_format; + PyObject *__pyx_n_s_fortran; + PyObject *__pyx_n_u_fortran; + PyObject *__pyx_kp_u_gc; + PyObject *__pyx_n_s_getstate; + PyObject *__pyx_kp_u_got; + PyObject *__pyx_kp_u_got_differing_extents_in_dimensi; + PyObject *__pyx_n_s_i; + PyObject *__pyx_n_s_id; + PyObject *__pyx_n_s_import; + PyObject *__pyx_n_s_index; + PyObject *__pyx_n_s_initializing; + PyObject *__pyx_n_s_is_coroutine; + PyObject *__pyx_kp_u_isenabled; + PyObject *__pyx_n_s_itemsize; + PyObject *__pyx_kp_s_itemsize_0_for_cython_array; + PyObject *__pyx_n_s_j; + PyObject *__pyx_n_s_main; + PyObject *__pyx_n_s_max_cdf; + PyObject *__pyx_n_s_memview; + PyObject *__pyx_n_s_mode; + PyObject *__pyx_n_s_mu; + PyObject *__pyx_n_s_n_rates; + PyObject *__pyx_n_s_n_reactants; + PyObject *__pyx_n_s_name; + PyObject *__pyx_n_s_name_2; + PyObject *__pyx_n_s_ndim; + PyObject *__pyx_n_s_new; + PyObject *__pyx_n_s_new_cdf; + PyObject *__pyx_kp_s_no_default___reduce___due_to_non; + PyObject *__pyx_n_s_np; + PyObject *__pyx_n_s_numpy; + PyObject *__pyx_kp_s_numpy_core_multiarray_failed_to; + PyObject *__pyx_kp_s_numpy_core_umath_failed_to_impor; + PyObject *__pyx_n_s_obj; + PyObject *__pyx_n_s_pack; + PyObject *__pyx_n_s_pickle; + PyObject *__pyx_n_s_pygom_model__tau_leap; + PyObject *__pyx_kp_s_pygom_model__tau_leap_pyx; + PyObject *__pyx_n_s_pyx_PickleError; + PyObject *__pyx_n_s_pyx_checksum; + PyObject *__pyx_n_s_pyx_result; + PyObject *__pyx_n_s_pyx_state; + PyObject *__pyx_n_s_pyx_type; + PyObject *__pyx_n_s_pyx_unpickle_Enum; + PyObject *__pyx_n_s_pyx_vtable; + PyObject *__pyx_n_s_range; + PyObject *__pyx_n_s_rates; + PyObject *__pyx_n_s_rates_view; + PyObject *__pyx_n_s_reactant_mat; + PyObject *__pyx_n_s_reactant_mat_view; + PyObject *__pyx_n_s_reduce; + PyObject *__pyx_n_s_reduce_cython; + PyObject *__pyx_n_s_reduce_ex; + PyObject *__pyx_n_s_register; + PyObject *__pyx_n_s_safe; + PyObject *__pyx_n_s_setstate; + PyObject *__pyx_n_s_setstate_cython; + PyObject *__pyx_n_s_shape; + PyObject *__pyx_n_s_size; + PyObject *__pyx_n_s_spec; + PyObject *__pyx_n_s_start; + PyObject *__pyx_n_s_step; + PyObject *__pyx_n_s_stop; + PyObject *__pyx_kp_s_strided_and_direct; + PyObject *__pyx_kp_s_strided_and_direct_or_indirect; + PyObject *__pyx_kp_s_strided_and_indirect; + PyObject *__pyx_kp_s_stringsource; + PyObject *__pyx_n_s_struct; + PyObject *__pyx_n_s_sum; + PyObject *__pyx_n_s_sys; + PyObject *__pyx_n_s_tau_scale; + PyObject *__pyx_n_s_test; + PyObject *__pyx_n_s_total_rate; + PyObject *__pyx_kp_s_unable_to_allocate_array_data; + PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str; + PyObject *__pyx_n_s_unpack; + PyObject *__pyx_n_s_update; + PyObject *__pyx_n_s_version_info; + PyObject *__pyx_n_s_x; + PyObject *__pyx_n_s_x_view; + PyObject *__pyx_int_0; + PyObject *__pyx_int_1; + PyObject *__pyx_int_3; + PyObject *__pyx_int_112105877; + PyObject *__pyx_int_136983863; + PyObject *__pyx_int_184977713; + PyObject *__pyx_int_neg_1; + PyObject *__pyx_slice__5; + PyObject *__pyx_tuple__4; + PyObject *__pyx_tuple__8; + PyObject *__pyx_tuple__9; + PyObject *__pyx_tuple__10; + PyObject *__pyx_tuple__11; + PyObject *__pyx_tuple__12; + PyObject *__pyx_tuple__13; + PyObject *__pyx_tuple__14; + PyObject *__pyx_tuple__15; + PyObject *__pyx_tuple__16; + PyObject *__pyx_tuple__17; + PyObject *__pyx_tuple__18; + PyObject *__pyx_tuple__19; + PyObject *__pyx_tuple__20; + PyObject *__pyx_tuple__22; + PyObject *__pyx_codeobj__21; + PyObject *__pyx_codeobj__23; +} __pyx_mstate; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { + extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate(o) ((__pyx_mstate *)__Pyx_PyModule_GetState(o)) + +#define __pyx_mstate_global (__pyx_mstate(PyState_FindModule(&__pyx_moduledef))) + +#define __pyx_m (PyState_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstate __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstate *__pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_clear(PyObject *m) { + __pyx_mstate *clear_module_state = __pyx_mstate(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_CLEAR(clear_module_state->__pyx_FusedFunctionType); + #endif + Py_CLEAR(clear_module_state->__pyx_ptype_7cpython_4type_type); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_dtype); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_flatiter); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_broadcast); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_ndarray); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_generic); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_number); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_integer); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_signedinteger); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_unsignedinteger); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_inexact); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_floating); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_complexfloating); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_flexible); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_character); + Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_ufunc); + Py_CLEAR(clear_module_state->__pyx_array_type); + Py_CLEAR(clear_module_state->__pyx_type___pyx_array); + Py_CLEAR(clear_module_state->__pyx_MemviewEnum_type); + Py_CLEAR(clear_module_state->__pyx_type___pyx_MemviewEnum); + Py_CLEAR(clear_module_state->__pyx_memoryview_type); + Py_CLEAR(clear_module_state->__pyx_type___pyx_memoryview); + Py_CLEAR(clear_module_state->__pyx_memoryviewslice_type); + Py_CLEAR(clear_module_state->__pyx_type___pyx_memoryviewslice); + Py_CLEAR(clear_module_state->__pyx_kp_u_); + Py_CLEAR(clear_module_state->__pyx_n_s_ASCII); + Py_CLEAR(clear_module_state->__pyx_kp_s_All_dimensions_preceding_dimensi); + Py_CLEAR(clear_module_state->__pyx_n_s_AssertionError); + Py_CLEAR(clear_module_state->__pyx_kp_s_Buffer_view_does_not_expose_stri); + Py_CLEAR(clear_module_state->__pyx_kp_s_Can_only_create_a_buffer_that_is); + Py_CLEAR(clear_module_state->__pyx_kp_s_Cannot_assign_to_read_only_memor); + Py_CLEAR(clear_module_state->__pyx_kp_s_Cannot_create_writable_memory_vi); + Py_CLEAR(clear_module_state->__pyx_kp_u_Cannot_index_with_type); + Py_CLEAR(clear_module_state->__pyx_kp_s_Cannot_transpose_memoryview_with); + Py_CLEAR(clear_module_state->__pyx_kp_s_Dimension_d_is_not_direct); + Py_CLEAR(clear_module_state->__pyx_n_s_Ellipsis); + Py_CLEAR(clear_module_state->__pyx_kp_s_Empty_shape_tuple_for_cython_arr); + Py_CLEAR(clear_module_state->__pyx_n_s_ImportError); + Py_CLEAR(clear_module_state->__pyx_kp_s_Incompatible_checksums_0x_x_vs_0); + Py_CLEAR(clear_module_state->__pyx_n_s_IndexError); + Py_CLEAR(clear_module_state->__pyx_kp_s_Index_out_of_bounds_axis_d); + Py_CLEAR(clear_module_state->__pyx_kp_s_Indirect_dimensions_not_supporte); + Py_CLEAR(clear_module_state->__pyx_kp_u_Invalid_mode_expected_c_or_fortr); + Py_CLEAR(clear_module_state->__pyx_kp_u_Invalid_shape_in_axis); + Py_CLEAR(clear_module_state->__pyx_n_s_MemoryError); + Py_CLEAR(clear_module_state->__pyx_kp_s_MemoryView_of_r_at_0x_x); + Py_CLEAR(clear_module_state->__pyx_kp_s_MemoryView_of_r_object); + Py_CLEAR(clear_module_state->__pyx_n_b_O); + Py_CLEAR(clear_module_state->__pyx_kp_u_Out_of_bounds_on_buffer_access_a); + Py_CLEAR(clear_module_state->__pyx_n_s_PickleError); + Py_CLEAR(clear_module_state->__pyx_n_s_Sequence); + Py_CLEAR(clear_module_state->__pyx_kp_s_Step_may_not_be_zero_axis_d); + Py_CLEAR(clear_module_state->__pyx_n_s_TypeError); + Py_CLEAR(clear_module_state->__pyx_kp_s_Unable_to_convert_item_to_object); + Py_CLEAR(clear_module_state->__pyx_n_s_ValueError); + Py_CLEAR(clear_module_state->__pyx_n_s_View_MemoryView); + Py_CLEAR(clear_module_state->__pyx_kp_u__2); + Py_CLEAR(clear_module_state->__pyx_n_s__24); + Py_CLEAR(clear_module_state->__pyx_n_s__3); + Py_CLEAR(clear_module_state->__pyx_kp_u__6); + Py_CLEAR(clear_module_state->__pyx_kp_u__7); + Py_CLEAR(clear_module_state->__pyx_n_s_abc); + Py_CLEAR(clear_module_state->__pyx_n_s_allocate_buffer); + Py_CLEAR(clear_module_state->__pyx_kp_u_and); + Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines); + Py_CLEAR(clear_module_state->__pyx_n_s_base); + Py_CLEAR(clear_module_state->__pyx_n_s_c); + Py_CLEAR(clear_module_state->__pyx_n_u_c); + Py_CLEAR(clear_module_state->__pyx_n_s_cdf_val); + Py_CLEAR(clear_module_state->__pyx_n_s_class); + Py_CLEAR(clear_module_state->__pyx_n_s_class_getitem); + Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback); + Py_CLEAR(clear_module_state->__pyx_n_s_collections); + Py_CLEAR(clear_module_state->__pyx_kp_s_collections_abc); + Py_CLEAR(clear_module_state->__pyx_kp_s_contiguous_and_direct); + Py_CLEAR(clear_module_state->__pyx_kp_s_contiguous_and_indirect); + Py_CLEAR(clear_module_state->__pyx_n_s_count); + Py_CLEAR(clear_module_state->__pyx_n_s_cy_test_tau_leap_safety); + Py_CLEAR(clear_module_state->__pyx_n_s_dict); + Py_CLEAR(clear_module_state->__pyx_kp_u_disable); + Py_CLEAR(clear_module_state->__pyx_n_s_dtype_is_object); + Py_CLEAR(clear_module_state->__pyx_kp_u_enable); + Py_CLEAR(clear_module_state->__pyx_n_s_encode); + Py_CLEAR(clear_module_state->__pyx_n_s_enumerate); + Py_CLEAR(clear_module_state->__pyx_n_s_epsilon); + Py_CLEAR(clear_module_state->__pyx_n_s_error); + Py_CLEAR(clear_module_state->__pyx_n_s_flags); + Py_CLEAR(clear_module_state->__pyx_n_s_format); + Py_CLEAR(clear_module_state->__pyx_n_s_fortran); + Py_CLEAR(clear_module_state->__pyx_n_u_fortran); + Py_CLEAR(clear_module_state->__pyx_kp_u_gc); + Py_CLEAR(clear_module_state->__pyx_n_s_getstate); + Py_CLEAR(clear_module_state->__pyx_kp_u_got); + Py_CLEAR(clear_module_state->__pyx_kp_u_got_differing_extents_in_dimensi); + Py_CLEAR(clear_module_state->__pyx_n_s_i); + Py_CLEAR(clear_module_state->__pyx_n_s_id); + Py_CLEAR(clear_module_state->__pyx_n_s_import); + Py_CLEAR(clear_module_state->__pyx_n_s_index); + Py_CLEAR(clear_module_state->__pyx_n_s_initializing); + Py_CLEAR(clear_module_state->__pyx_n_s_is_coroutine); + Py_CLEAR(clear_module_state->__pyx_kp_u_isenabled); + Py_CLEAR(clear_module_state->__pyx_n_s_itemsize); + Py_CLEAR(clear_module_state->__pyx_kp_s_itemsize_0_for_cython_array); + Py_CLEAR(clear_module_state->__pyx_n_s_j); + Py_CLEAR(clear_module_state->__pyx_n_s_main); + Py_CLEAR(clear_module_state->__pyx_n_s_max_cdf); + Py_CLEAR(clear_module_state->__pyx_n_s_memview); + Py_CLEAR(clear_module_state->__pyx_n_s_mode); + Py_CLEAR(clear_module_state->__pyx_n_s_mu); + Py_CLEAR(clear_module_state->__pyx_n_s_n_rates); + Py_CLEAR(clear_module_state->__pyx_n_s_n_reactants); + Py_CLEAR(clear_module_state->__pyx_n_s_name); + Py_CLEAR(clear_module_state->__pyx_n_s_name_2); + Py_CLEAR(clear_module_state->__pyx_n_s_ndim); + Py_CLEAR(clear_module_state->__pyx_n_s_new); + Py_CLEAR(clear_module_state->__pyx_n_s_new_cdf); + Py_CLEAR(clear_module_state->__pyx_kp_s_no_default___reduce___due_to_non); + Py_CLEAR(clear_module_state->__pyx_n_s_np); + Py_CLEAR(clear_module_state->__pyx_n_s_numpy); + Py_CLEAR(clear_module_state->__pyx_kp_s_numpy_core_multiarray_failed_to); + Py_CLEAR(clear_module_state->__pyx_kp_s_numpy_core_umath_failed_to_impor); + Py_CLEAR(clear_module_state->__pyx_n_s_obj); + Py_CLEAR(clear_module_state->__pyx_n_s_pack); + Py_CLEAR(clear_module_state->__pyx_n_s_pickle); + Py_CLEAR(clear_module_state->__pyx_n_s_pygom_model__tau_leap); + Py_CLEAR(clear_module_state->__pyx_kp_s_pygom_model__tau_leap_pyx); + Py_CLEAR(clear_module_state->__pyx_n_s_pyx_PickleError); + Py_CLEAR(clear_module_state->__pyx_n_s_pyx_checksum); + Py_CLEAR(clear_module_state->__pyx_n_s_pyx_result); + Py_CLEAR(clear_module_state->__pyx_n_s_pyx_state); + Py_CLEAR(clear_module_state->__pyx_n_s_pyx_type); + Py_CLEAR(clear_module_state->__pyx_n_s_pyx_unpickle_Enum); + Py_CLEAR(clear_module_state->__pyx_n_s_pyx_vtable); + Py_CLEAR(clear_module_state->__pyx_n_s_range); + Py_CLEAR(clear_module_state->__pyx_n_s_rates); + Py_CLEAR(clear_module_state->__pyx_n_s_rates_view); + Py_CLEAR(clear_module_state->__pyx_n_s_reactant_mat); + Py_CLEAR(clear_module_state->__pyx_n_s_reactant_mat_view); + Py_CLEAR(clear_module_state->__pyx_n_s_reduce); + Py_CLEAR(clear_module_state->__pyx_n_s_reduce_cython); + Py_CLEAR(clear_module_state->__pyx_n_s_reduce_ex); + Py_CLEAR(clear_module_state->__pyx_n_s_register); + Py_CLEAR(clear_module_state->__pyx_n_s_safe); + Py_CLEAR(clear_module_state->__pyx_n_s_setstate); + Py_CLEAR(clear_module_state->__pyx_n_s_setstate_cython); + Py_CLEAR(clear_module_state->__pyx_n_s_shape); + Py_CLEAR(clear_module_state->__pyx_n_s_size); + Py_CLEAR(clear_module_state->__pyx_n_s_spec); + Py_CLEAR(clear_module_state->__pyx_n_s_start); + Py_CLEAR(clear_module_state->__pyx_n_s_step); + Py_CLEAR(clear_module_state->__pyx_n_s_stop); + Py_CLEAR(clear_module_state->__pyx_kp_s_strided_and_direct); + Py_CLEAR(clear_module_state->__pyx_kp_s_strided_and_direct_or_indirect); + Py_CLEAR(clear_module_state->__pyx_kp_s_strided_and_indirect); + Py_CLEAR(clear_module_state->__pyx_kp_s_stringsource); + Py_CLEAR(clear_module_state->__pyx_n_s_struct); + Py_CLEAR(clear_module_state->__pyx_n_s_sum); + Py_CLEAR(clear_module_state->__pyx_n_s_sys); + Py_CLEAR(clear_module_state->__pyx_n_s_tau_scale); + Py_CLEAR(clear_module_state->__pyx_n_s_test); + Py_CLEAR(clear_module_state->__pyx_n_s_total_rate); + Py_CLEAR(clear_module_state->__pyx_kp_s_unable_to_allocate_array_data); + Py_CLEAR(clear_module_state->__pyx_kp_s_unable_to_allocate_shape_and_str); + Py_CLEAR(clear_module_state->__pyx_n_s_unpack); + Py_CLEAR(clear_module_state->__pyx_n_s_update); + Py_CLEAR(clear_module_state->__pyx_n_s_version_info); + Py_CLEAR(clear_module_state->__pyx_n_s_x); + Py_CLEAR(clear_module_state->__pyx_n_s_x_view); + Py_CLEAR(clear_module_state->__pyx_int_0); + Py_CLEAR(clear_module_state->__pyx_int_1); + Py_CLEAR(clear_module_state->__pyx_int_3); + Py_CLEAR(clear_module_state->__pyx_int_112105877); + Py_CLEAR(clear_module_state->__pyx_int_136983863); + Py_CLEAR(clear_module_state->__pyx_int_184977713); + Py_CLEAR(clear_module_state->__pyx_int_neg_1); + Py_CLEAR(clear_module_state->__pyx_slice__5); + Py_CLEAR(clear_module_state->__pyx_tuple__4); + Py_CLEAR(clear_module_state->__pyx_tuple__8); + Py_CLEAR(clear_module_state->__pyx_tuple__9); + Py_CLEAR(clear_module_state->__pyx_tuple__10); + Py_CLEAR(clear_module_state->__pyx_tuple__11); + Py_CLEAR(clear_module_state->__pyx_tuple__12); + Py_CLEAR(clear_module_state->__pyx_tuple__13); + Py_CLEAR(clear_module_state->__pyx_tuple__14); + Py_CLEAR(clear_module_state->__pyx_tuple__15); + Py_CLEAR(clear_module_state->__pyx_tuple__16); + Py_CLEAR(clear_module_state->__pyx_tuple__17); + Py_CLEAR(clear_module_state->__pyx_tuple__18); + Py_CLEAR(clear_module_state->__pyx_tuple__19); + Py_CLEAR(clear_module_state->__pyx_tuple__20); + Py_CLEAR(clear_module_state->__pyx_tuple__22); + Py_CLEAR(clear_module_state->__pyx_codeobj__21); + Py_CLEAR(clear_module_state->__pyx_codeobj__23); + return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstate *traverse_module_state = __pyx_mstate(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + Py_VISIT(traverse_module_state->__pyx_empty_tuple); + Py_VISIT(traverse_module_state->__pyx_empty_bytes); + Py_VISIT(traverse_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_VISIT(traverse_module_state->__pyx_FusedFunctionType); + #endif + Py_VISIT(traverse_module_state->__pyx_ptype_7cpython_4type_type); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_dtype); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_flatiter); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_broadcast); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_ndarray); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_generic); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_number); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_integer); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_signedinteger); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_unsignedinteger); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_inexact); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_floating); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_complexfloating); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_flexible); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_character); + Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_ufunc); + Py_VISIT(traverse_module_state->__pyx_array_type); + Py_VISIT(traverse_module_state->__pyx_type___pyx_array); + Py_VISIT(traverse_module_state->__pyx_MemviewEnum_type); + Py_VISIT(traverse_module_state->__pyx_type___pyx_MemviewEnum); + Py_VISIT(traverse_module_state->__pyx_memoryview_type); + Py_VISIT(traverse_module_state->__pyx_type___pyx_memoryview); + Py_VISIT(traverse_module_state->__pyx_memoryviewslice_type); + Py_VISIT(traverse_module_state->__pyx_type___pyx_memoryviewslice); + Py_VISIT(traverse_module_state->__pyx_kp_u_); + Py_VISIT(traverse_module_state->__pyx_n_s_ASCII); + Py_VISIT(traverse_module_state->__pyx_kp_s_All_dimensions_preceding_dimensi); + Py_VISIT(traverse_module_state->__pyx_n_s_AssertionError); + Py_VISIT(traverse_module_state->__pyx_kp_s_Buffer_view_does_not_expose_stri); + Py_VISIT(traverse_module_state->__pyx_kp_s_Can_only_create_a_buffer_that_is); + Py_VISIT(traverse_module_state->__pyx_kp_s_Cannot_assign_to_read_only_memor); + Py_VISIT(traverse_module_state->__pyx_kp_s_Cannot_create_writable_memory_vi); + Py_VISIT(traverse_module_state->__pyx_kp_u_Cannot_index_with_type); + Py_VISIT(traverse_module_state->__pyx_kp_s_Cannot_transpose_memoryview_with); + Py_VISIT(traverse_module_state->__pyx_kp_s_Dimension_d_is_not_direct); + Py_VISIT(traverse_module_state->__pyx_n_s_Ellipsis); + Py_VISIT(traverse_module_state->__pyx_kp_s_Empty_shape_tuple_for_cython_arr); + Py_VISIT(traverse_module_state->__pyx_n_s_ImportError); + Py_VISIT(traverse_module_state->__pyx_kp_s_Incompatible_checksums_0x_x_vs_0); + Py_VISIT(traverse_module_state->__pyx_n_s_IndexError); + Py_VISIT(traverse_module_state->__pyx_kp_s_Index_out_of_bounds_axis_d); + Py_VISIT(traverse_module_state->__pyx_kp_s_Indirect_dimensions_not_supporte); + Py_VISIT(traverse_module_state->__pyx_kp_u_Invalid_mode_expected_c_or_fortr); + Py_VISIT(traverse_module_state->__pyx_kp_u_Invalid_shape_in_axis); + Py_VISIT(traverse_module_state->__pyx_n_s_MemoryError); + Py_VISIT(traverse_module_state->__pyx_kp_s_MemoryView_of_r_at_0x_x); + Py_VISIT(traverse_module_state->__pyx_kp_s_MemoryView_of_r_object); + Py_VISIT(traverse_module_state->__pyx_n_b_O); + Py_VISIT(traverse_module_state->__pyx_kp_u_Out_of_bounds_on_buffer_access_a); + Py_VISIT(traverse_module_state->__pyx_n_s_PickleError); + Py_VISIT(traverse_module_state->__pyx_n_s_Sequence); + Py_VISIT(traverse_module_state->__pyx_kp_s_Step_may_not_be_zero_axis_d); + Py_VISIT(traverse_module_state->__pyx_n_s_TypeError); + Py_VISIT(traverse_module_state->__pyx_kp_s_Unable_to_convert_item_to_object); + Py_VISIT(traverse_module_state->__pyx_n_s_ValueError); + Py_VISIT(traverse_module_state->__pyx_n_s_View_MemoryView); + Py_VISIT(traverse_module_state->__pyx_kp_u__2); + Py_VISIT(traverse_module_state->__pyx_n_s__24); + Py_VISIT(traverse_module_state->__pyx_n_s__3); + Py_VISIT(traverse_module_state->__pyx_kp_u__6); + Py_VISIT(traverse_module_state->__pyx_kp_u__7); + Py_VISIT(traverse_module_state->__pyx_n_s_abc); + Py_VISIT(traverse_module_state->__pyx_n_s_allocate_buffer); + Py_VISIT(traverse_module_state->__pyx_kp_u_and); + Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines); + Py_VISIT(traverse_module_state->__pyx_n_s_base); + Py_VISIT(traverse_module_state->__pyx_n_s_c); + Py_VISIT(traverse_module_state->__pyx_n_u_c); + Py_VISIT(traverse_module_state->__pyx_n_s_cdf_val); + Py_VISIT(traverse_module_state->__pyx_n_s_class); + Py_VISIT(traverse_module_state->__pyx_n_s_class_getitem); + Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback); + Py_VISIT(traverse_module_state->__pyx_n_s_collections); + Py_VISIT(traverse_module_state->__pyx_kp_s_collections_abc); + Py_VISIT(traverse_module_state->__pyx_kp_s_contiguous_and_direct); + Py_VISIT(traverse_module_state->__pyx_kp_s_contiguous_and_indirect); + Py_VISIT(traverse_module_state->__pyx_n_s_count); + Py_VISIT(traverse_module_state->__pyx_n_s_cy_test_tau_leap_safety); + Py_VISIT(traverse_module_state->__pyx_n_s_dict); + Py_VISIT(traverse_module_state->__pyx_kp_u_disable); + Py_VISIT(traverse_module_state->__pyx_n_s_dtype_is_object); + Py_VISIT(traverse_module_state->__pyx_kp_u_enable); + Py_VISIT(traverse_module_state->__pyx_n_s_encode); + Py_VISIT(traverse_module_state->__pyx_n_s_enumerate); + Py_VISIT(traverse_module_state->__pyx_n_s_epsilon); + Py_VISIT(traverse_module_state->__pyx_n_s_error); + Py_VISIT(traverse_module_state->__pyx_n_s_flags); + Py_VISIT(traverse_module_state->__pyx_n_s_format); + Py_VISIT(traverse_module_state->__pyx_n_s_fortran); + Py_VISIT(traverse_module_state->__pyx_n_u_fortran); + Py_VISIT(traverse_module_state->__pyx_kp_u_gc); + Py_VISIT(traverse_module_state->__pyx_n_s_getstate); + Py_VISIT(traverse_module_state->__pyx_kp_u_got); + Py_VISIT(traverse_module_state->__pyx_kp_u_got_differing_extents_in_dimensi); + Py_VISIT(traverse_module_state->__pyx_n_s_i); + Py_VISIT(traverse_module_state->__pyx_n_s_id); + Py_VISIT(traverse_module_state->__pyx_n_s_import); + Py_VISIT(traverse_module_state->__pyx_n_s_index); + Py_VISIT(traverse_module_state->__pyx_n_s_initializing); + Py_VISIT(traverse_module_state->__pyx_n_s_is_coroutine); + Py_VISIT(traverse_module_state->__pyx_kp_u_isenabled); + Py_VISIT(traverse_module_state->__pyx_n_s_itemsize); + Py_VISIT(traverse_module_state->__pyx_kp_s_itemsize_0_for_cython_array); + Py_VISIT(traverse_module_state->__pyx_n_s_j); + Py_VISIT(traverse_module_state->__pyx_n_s_main); + Py_VISIT(traverse_module_state->__pyx_n_s_max_cdf); + Py_VISIT(traverse_module_state->__pyx_n_s_memview); + Py_VISIT(traverse_module_state->__pyx_n_s_mode); + Py_VISIT(traverse_module_state->__pyx_n_s_mu); + Py_VISIT(traverse_module_state->__pyx_n_s_n_rates); + Py_VISIT(traverse_module_state->__pyx_n_s_n_reactants); + Py_VISIT(traverse_module_state->__pyx_n_s_name); + Py_VISIT(traverse_module_state->__pyx_n_s_name_2); + Py_VISIT(traverse_module_state->__pyx_n_s_ndim); + Py_VISIT(traverse_module_state->__pyx_n_s_new); + Py_VISIT(traverse_module_state->__pyx_n_s_new_cdf); + Py_VISIT(traverse_module_state->__pyx_kp_s_no_default___reduce___due_to_non); + Py_VISIT(traverse_module_state->__pyx_n_s_np); + Py_VISIT(traverse_module_state->__pyx_n_s_numpy); + Py_VISIT(traverse_module_state->__pyx_kp_s_numpy_core_multiarray_failed_to); + Py_VISIT(traverse_module_state->__pyx_kp_s_numpy_core_umath_failed_to_impor); + Py_VISIT(traverse_module_state->__pyx_n_s_obj); + Py_VISIT(traverse_module_state->__pyx_n_s_pack); + Py_VISIT(traverse_module_state->__pyx_n_s_pickle); + Py_VISIT(traverse_module_state->__pyx_n_s_pygom_model__tau_leap); + Py_VISIT(traverse_module_state->__pyx_kp_s_pygom_model__tau_leap_pyx); + Py_VISIT(traverse_module_state->__pyx_n_s_pyx_PickleError); + Py_VISIT(traverse_module_state->__pyx_n_s_pyx_checksum); + Py_VISIT(traverse_module_state->__pyx_n_s_pyx_result); + Py_VISIT(traverse_module_state->__pyx_n_s_pyx_state); + Py_VISIT(traverse_module_state->__pyx_n_s_pyx_type); + Py_VISIT(traverse_module_state->__pyx_n_s_pyx_unpickle_Enum); + Py_VISIT(traverse_module_state->__pyx_n_s_pyx_vtable); + Py_VISIT(traverse_module_state->__pyx_n_s_range); + Py_VISIT(traverse_module_state->__pyx_n_s_rates); + Py_VISIT(traverse_module_state->__pyx_n_s_rates_view); + Py_VISIT(traverse_module_state->__pyx_n_s_reactant_mat); + Py_VISIT(traverse_module_state->__pyx_n_s_reactant_mat_view); + Py_VISIT(traverse_module_state->__pyx_n_s_reduce); + Py_VISIT(traverse_module_state->__pyx_n_s_reduce_cython); + Py_VISIT(traverse_module_state->__pyx_n_s_reduce_ex); + Py_VISIT(traverse_module_state->__pyx_n_s_register); + Py_VISIT(traverse_module_state->__pyx_n_s_safe); + Py_VISIT(traverse_module_state->__pyx_n_s_setstate); + Py_VISIT(traverse_module_state->__pyx_n_s_setstate_cython); + Py_VISIT(traverse_module_state->__pyx_n_s_shape); + Py_VISIT(traverse_module_state->__pyx_n_s_size); + Py_VISIT(traverse_module_state->__pyx_n_s_spec); + Py_VISIT(traverse_module_state->__pyx_n_s_start); + Py_VISIT(traverse_module_state->__pyx_n_s_step); + Py_VISIT(traverse_module_state->__pyx_n_s_stop); + Py_VISIT(traverse_module_state->__pyx_kp_s_strided_and_direct); + Py_VISIT(traverse_module_state->__pyx_kp_s_strided_and_direct_or_indirect); + Py_VISIT(traverse_module_state->__pyx_kp_s_strided_and_indirect); + Py_VISIT(traverse_module_state->__pyx_kp_s_stringsource); + Py_VISIT(traverse_module_state->__pyx_n_s_struct); + Py_VISIT(traverse_module_state->__pyx_n_s_sum); + Py_VISIT(traverse_module_state->__pyx_n_s_sys); + Py_VISIT(traverse_module_state->__pyx_n_s_tau_scale); + Py_VISIT(traverse_module_state->__pyx_n_s_test); + Py_VISIT(traverse_module_state->__pyx_n_s_total_rate); + Py_VISIT(traverse_module_state->__pyx_kp_s_unable_to_allocate_array_data); + Py_VISIT(traverse_module_state->__pyx_kp_s_unable_to_allocate_shape_and_str); + Py_VISIT(traverse_module_state->__pyx_n_s_unpack); + Py_VISIT(traverse_module_state->__pyx_n_s_update); + Py_VISIT(traverse_module_state->__pyx_n_s_version_info); + Py_VISIT(traverse_module_state->__pyx_n_s_x); + Py_VISIT(traverse_module_state->__pyx_n_s_x_view); + Py_VISIT(traverse_module_state->__pyx_int_0); + Py_VISIT(traverse_module_state->__pyx_int_1); + Py_VISIT(traverse_module_state->__pyx_int_3); + Py_VISIT(traverse_module_state->__pyx_int_112105877); + Py_VISIT(traverse_module_state->__pyx_int_136983863); + Py_VISIT(traverse_module_state->__pyx_int_184977713); + Py_VISIT(traverse_module_state->__pyx_int_neg_1); + Py_VISIT(traverse_module_state->__pyx_slice__5); + Py_VISIT(traverse_module_state->__pyx_tuple__4); + Py_VISIT(traverse_module_state->__pyx_tuple__8); + Py_VISIT(traverse_module_state->__pyx_tuple__9); + Py_VISIT(traverse_module_state->__pyx_tuple__10); + Py_VISIT(traverse_module_state->__pyx_tuple__11); + Py_VISIT(traverse_module_state->__pyx_tuple__12); + Py_VISIT(traverse_module_state->__pyx_tuple__13); + Py_VISIT(traverse_module_state->__pyx_tuple__14); + Py_VISIT(traverse_module_state->__pyx_tuple__15); + Py_VISIT(traverse_module_state->__pyx_tuple__16); + Py_VISIT(traverse_module_state->__pyx_tuple__17); + Py_VISIT(traverse_module_state->__pyx_tuple__18); + Py_VISIT(traverse_module_state->__pyx_tuple__19); + Py_VISIT(traverse_module_state->__pyx_tuple__20); + Py_VISIT(traverse_module_state->__pyx_tuple__22); + Py_VISIT(traverse_module_state->__pyx_codeobj__21); + Py_VISIT(traverse_module_state->__pyx_codeobj__23); + return 0; +} +#endif +/* #### Code section: module_state_defines ### */ +#define __pyx_d __pyx_mstate_global->__pyx_d +#define __pyx_b __pyx_mstate_global->__pyx_b +#define __pyx_cython_runtime __pyx_mstate_global->__pyx_cython_runtime +#define __pyx_empty_tuple __pyx_mstate_global->__pyx_empty_tuple +#define __pyx_empty_bytes __pyx_mstate_global->__pyx_empty_bytes +#define __pyx_empty_unicode __pyx_mstate_global->__pyx_empty_unicode +#ifdef __Pyx_CyFunction_USED +#define __pyx_CyFunctionType __pyx_mstate_global->__pyx_CyFunctionType +#endif +#ifdef __Pyx_FusedFunction_USED +#define __pyx_FusedFunctionType __pyx_mstate_global->__pyx_FusedFunctionType +#endif +#ifdef __Pyx_Generator_USED +#define __pyx_GeneratorType __pyx_mstate_global->__pyx_GeneratorType +#endif +#ifdef __Pyx_IterableCoroutine_USED +#define __pyx_IterableCoroutineType __pyx_mstate_global->__pyx_IterableCoroutineType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineAwaitType __pyx_mstate_global->__pyx_CoroutineAwaitType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineType __pyx_mstate_global->__pyx_CoroutineType +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#define __pyx_ptype_7cpython_4type_type __pyx_mstate_global->__pyx_ptype_7cpython_4type_type +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#define __pyx_ptype_5numpy_dtype __pyx_mstate_global->__pyx_ptype_5numpy_dtype +#define __pyx_ptype_5numpy_flatiter __pyx_mstate_global->__pyx_ptype_5numpy_flatiter +#define __pyx_ptype_5numpy_broadcast __pyx_mstate_global->__pyx_ptype_5numpy_broadcast +#define __pyx_ptype_5numpy_ndarray __pyx_mstate_global->__pyx_ptype_5numpy_ndarray +#define __pyx_ptype_5numpy_generic __pyx_mstate_global->__pyx_ptype_5numpy_generic +#define __pyx_ptype_5numpy_number __pyx_mstate_global->__pyx_ptype_5numpy_number +#define __pyx_ptype_5numpy_integer __pyx_mstate_global->__pyx_ptype_5numpy_integer +#define __pyx_ptype_5numpy_signedinteger __pyx_mstate_global->__pyx_ptype_5numpy_signedinteger +#define __pyx_ptype_5numpy_unsignedinteger __pyx_mstate_global->__pyx_ptype_5numpy_unsignedinteger +#define __pyx_ptype_5numpy_inexact __pyx_mstate_global->__pyx_ptype_5numpy_inexact +#define __pyx_ptype_5numpy_floating __pyx_mstate_global->__pyx_ptype_5numpy_floating +#define __pyx_ptype_5numpy_complexfloating __pyx_mstate_global->__pyx_ptype_5numpy_complexfloating +#define __pyx_ptype_5numpy_flexible __pyx_mstate_global->__pyx_ptype_5numpy_flexible +#define __pyx_ptype_5numpy_character __pyx_mstate_global->__pyx_ptype_5numpy_character +#define __pyx_ptype_5numpy_ufunc __pyx_mstate_global->__pyx_ptype_5numpy_ufunc +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#define __pyx_type___pyx_array __pyx_mstate_global->__pyx_type___pyx_array +#define __pyx_type___pyx_MemviewEnum __pyx_mstate_global->__pyx_type___pyx_MemviewEnum +#define __pyx_type___pyx_memoryview __pyx_mstate_global->__pyx_type___pyx_memoryview +#define __pyx_type___pyx_memoryviewslice __pyx_mstate_global->__pyx_type___pyx_memoryviewslice +#endif +#define __pyx_array_type __pyx_mstate_global->__pyx_array_type +#define __pyx_MemviewEnum_type __pyx_mstate_global->__pyx_MemviewEnum_type +#define __pyx_memoryview_type __pyx_mstate_global->__pyx_memoryview_type +#define __pyx_memoryviewslice_type __pyx_mstate_global->__pyx_memoryviewslice_type +#define __pyx_kp_u_ __pyx_mstate_global->__pyx_kp_u_ +#define __pyx_n_s_ASCII __pyx_mstate_global->__pyx_n_s_ASCII +#define __pyx_kp_s_All_dimensions_preceding_dimensi __pyx_mstate_global->__pyx_kp_s_All_dimensions_preceding_dimensi +#define __pyx_n_s_AssertionError __pyx_mstate_global->__pyx_n_s_AssertionError +#define __pyx_kp_s_Buffer_view_does_not_expose_stri __pyx_mstate_global->__pyx_kp_s_Buffer_view_does_not_expose_stri +#define __pyx_kp_s_Can_only_create_a_buffer_that_is __pyx_mstate_global->__pyx_kp_s_Can_only_create_a_buffer_that_is +#define __pyx_kp_s_Cannot_assign_to_read_only_memor __pyx_mstate_global->__pyx_kp_s_Cannot_assign_to_read_only_memor +#define __pyx_kp_s_Cannot_create_writable_memory_vi __pyx_mstate_global->__pyx_kp_s_Cannot_create_writable_memory_vi +#define __pyx_kp_u_Cannot_index_with_type __pyx_mstate_global->__pyx_kp_u_Cannot_index_with_type +#define __pyx_kp_s_Cannot_transpose_memoryview_with __pyx_mstate_global->__pyx_kp_s_Cannot_transpose_memoryview_with +#define __pyx_kp_s_Dimension_d_is_not_direct __pyx_mstate_global->__pyx_kp_s_Dimension_d_is_not_direct +#define __pyx_n_s_Ellipsis __pyx_mstate_global->__pyx_n_s_Ellipsis +#define __pyx_kp_s_Empty_shape_tuple_for_cython_arr __pyx_mstate_global->__pyx_kp_s_Empty_shape_tuple_for_cython_arr +#define __pyx_n_s_ImportError __pyx_mstate_global->__pyx_n_s_ImportError +#define __pyx_kp_s_Incompatible_checksums_0x_x_vs_0 __pyx_mstate_global->__pyx_kp_s_Incompatible_checksums_0x_x_vs_0 +#define __pyx_n_s_IndexError __pyx_mstate_global->__pyx_n_s_IndexError +#define __pyx_kp_s_Index_out_of_bounds_axis_d __pyx_mstate_global->__pyx_kp_s_Index_out_of_bounds_axis_d +#define __pyx_kp_s_Indirect_dimensions_not_supporte __pyx_mstate_global->__pyx_kp_s_Indirect_dimensions_not_supporte +#define __pyx_kp_u_Invalid_mode_expected_c_or_fortr __pyx_mstate_global->__pyx_kp_u_Invalid_mode_expected_c_or_fortr +#define __pyx_kp_u_Invalid_shape_in_axis __pyx_mstate_global->__pyx_kp_u_Invalid_shape_in_axis +#define __pyx_n_s_MemoryError __pyx_mstate_global->__pyx_n_s_MemoryError +#define __pyx_kp_s_MemoryView_of_r_at_0x_x __pyx_mstate_global->__pyx_kp_s_MemoryView_of_r_at_0x_x +#define __pyx_kp_s_MemoryView_of_r_object __pyx_mstate_global->__pyx_kp_s_MemoryView_of_r_object +#define __pyx_n_b_O __pyx_mstate_global->__pyx_n_b_O +#define __pyx_kp_u_Out_of_bounds_on_buffer_access_a __pyx_mstate_global->__pyx_kp_u_Out_of_bounds_on_buffer_access_a +#define __pyx_n_s_PickleError __pyx_mstate_global->__pyx_n_s_PickleError +#define __pyx_n_s_Sequence __pyx_mstate_global->__pyx_n_s_Sequence +#define __pyx_kp_s_Step_may_not_be_zero_axis_d __pyx_mstate_global->__pyx_kp_s_Step_may_not_be_zero_axis_d +#define __pyx_n_s_TypeError __pyx_mstate_global->__pyx_n_s_TypeError +#define __pyx_kp_s_Unable_to_convert_item_to_object __pyx_mstate_global->__pyx_kp_s_Unable_to_convert_item_to_object +#define __pyx_n_s_ValueError __pyx_mstate_global->__pyx_n_s_ValueError +#define __pyx_n_s_View_MemoryView __pyx_mstate_global->__pyx_n_s_View_MemoryView +#define __pyx_kp_u__2 __pyx_mstate_global->__pyx_kp_u__2 +#define __pyx_n_s__24 __pyx_mstate_global->__pyx_n_s__24 +#define __pyx_n_s__3 __pyx_mstate_global->__pyx_n_s__3 +#define __pyx_kp_u__6 __pyx_mstate_global->__pyx_kp_u__6 +#define __pyx_kp_u__7 __pyx_mstate_global->__pyx_kp_u__7 +#define __pyx_n_s_abc __pyx_mstate_global->__pyx_n_s_abc +#define __pyx_n_s_allocate_buffer __pyx_mstate_global->__pyx_n_s_allocate_buffer +#define __pyx_kp_u_and __pyx_mstate_global->__pyx_kp_u_and +#define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines +#define __pyx_n_s_base __pyx_mstate_global->__pyx_n_s_base +#define __pyx_n_s_c __pyx_mstate_global->__pyx_n_s_c +#define __pyx_n_u_c __pyx_mstate_global->__pyx_n_u_c +#define __pyx_n_s_cdf_val __pyx_mstate_global->__pyx_n_s_cdf_val +#define __pyx_n_s_class __pyx_mstate_global->__pyx_n_s_class +#define __pyx_n_s_class_getitem __pyx_mstate_global->__pyx_n_s_class_getitem +#define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback +#define __pyx_n_s_collections __pyx_mstate_global->__pyx_n_s_collections +#define __pyx_kp_s_collections_abc __pyx_mstate_global->__pyx_kp_s_collections_abc +#define __pyx_kp_s_contiguous_and_direct __pyx_mstate_global->__pyx_kp_s_contiguous_and_direct +#define __pyx_kp_s_contiguous_and_indirect __pyx_mstate_global->__pyx_kp_s_contiguous_and_indirect +#define __pyx_n_s_count __pyx_mstate_global->__pyx_n_s_count +#define __pyx_n_s_cy_test_tau_leap_safety __pyx_mstate_global->__pyx_n_s_cy_test_tau_leap_safety +#define __pyx_n_s_dict __pyx_mstate_global->__pyx_n_s_dict +#define __pyx_kp_u_disable __pyx_mstate_global->__pyx_kp_u_disable +#define __pyx_n_s_dtype_is_object __pyx_mstate_global->__pyx_n_s_dtype_is_object +#define __pyx_kp_u_enable __pyx_mstate_global->__pyx_kp_u_enable +#define __pyx_n_s_encode __pyx_mstate_global->__pyx_n_s_encode +#define __pyx_n_s_enumerate __pyx_mstate_global->__pyx_n_s_enumerate +#define __pyx_n_s_epsilon __pyx_mstate_global->__pyx_n_s_epsilon +#define __pyx_n_s_error __pyx_mstate_global->__pyx_n_s_error +#define __pyx_n_s_flags __pyx_mstate_global->__pyx_n_s_flags +#define __pyx_n_s_format __pyx_mstate_global->__pyx_n_s_format +#define __pyx_n_s_fortran __pyx_mstate_global->__pyx_n_s_fortran +#define __pyx_n_u_fortran __pyx_mstate_global->__pyx_n_u_fortran +#define __pyx_kp_u_gc __pyx_mstate_global->__pyx_kp_u_gc +#define __pyx_n_s_getstate __pyx_mstate_global->__pyx_n_s_getstate +#define __pyx_kp_u_got __pyx_mstate_global->__pyx_kp_u_got +#define __pyx_kp_u_got_differing_extents_in_dimensi __pyx_mstate_global->__pyx_kp_u_got_differing_extents_in_dimensi +#define __pyx_n_s_i __pyx_mstate_global->__pyx_n_s_i +#define __pyx_n_s_id __pyx_mstate_global->__pyx_n_s_id +#define __pyx_n_s_import __pyx_mstate_global->__pyx_n_s_import +#define __pyx_n_s_index __pyx_mstate_global->__pyx_n_s_index +#define __pyx_n_s_initializing __pyx_mstate_global->__pyx_n_s_initializing +#define __pyx_n_s_is_coroutine __pyx_mstate_global->__pyx_n_s_is_coroutine +#define __pyx_kp_u_isenabled __pyx_mstate_global->__pyx_kp_u_isenabled +#define __pyx_n_s_itemsize __pyx_mstate_global->__pyx_n_s_itemsize +#define __pyx_kp_s_itemsize_0_for_cython_array __pyx_mstate_global->__pyx_kp_s_itemsize_0_for_cython_array +#define __pyx_n_s_j __pyx_mstate_global->__pyx_n_s_j +#define __pyx_n_s_main __pyx_mstate_global->__pyx_n_s_main +#define __pyx_n_s_max_cdf __pyx_mstate_global->__pyx_n_s_max_cdf +#define __pyx_n_s_memview __pyx_mstate_global->__pyx_n_s_memview +#define __pyx_n_s_mode __pyx_mstate_global->__pyx_n_s_mode +#define __pyx_n_s_mu __pyx_mstate_global->__pyx_n_s_mu +#define __pyx_n_s_n_rates __pyx_mstate_global->__pyx_n_s_n_rates +#define __pyx_n_s_n_reactants __pyx_mstate_global->__pyx_n_s_n_reactants +#define __pyx_n_s_name __pyx_mstate_global->__pyx_n_s_name +#define __pyx_n_s_name_2 __pyx_mstate_global->__pyx_n_s_name_2 +#define __pyx_n_s_ndim __pyx_mstate_global->__pyx_n_s_ndim +#define __pyx_n_s_new __pyx_mstate_global->__pyx_n_s_new +#define __pyx_n_s_new_cdf __pyx_mstate_global->__pyx_n_s_new_cdf +#define __pyx_kp_s_no_default___reduce___due_to_non __pyx_mstate_global->__pyx_kp_s_no_default___reduce___due_to_non +#define __pyx_n_s_np __pyx_mstate_global->__pyx_n_s_np +#define __pyx_n_s_numpy __pyx_mstate_global->__pyx_n_s_numpy +#define __pyx_kp_s_numpy_core_multiarray_failed_to __pyx_mstate_global->__pyx_kp_s_numpy_core_multiarray_failed_to +#define __pyx_kp_s_numpy_core_umath_failed_to_impor __pyx_mstate_global->__pyx_kp_s_numpy_core_umath_failed_to_impor +#define __pyx_n_s_obj __pyx_mstate_global->__pyx_n_s_obj +#define __pyx_n_s_pack __pyx_mstate_global->__pyx_n_s_pack +#define __pyx_n_s_pickle __pyx_mstate_global->__pyx_n_s_pickle +#define __pyx_n_s_pygom_model__tau_leap __pyx_mstate_global->__pyx_n_s_pygom_model__tau_leap +#define __pyx_kp_s_pygom_model__tau_leap_pyx __pyx_mstate_global->__pyx_kp_s_pygom_model__tau_leap_pyx +#define __pyx_n_s_pyx_PickleError __pyx_mstate_global->__pyx_n_s_pyx_PickleError +#define __pyx_n_s_pyx_checksum __pyx_mstate_global->__pyx_n_s_pyx_checksum +#define __pyx_n_s_pyx_result __pyx_mstate_global->__pyx_n_s_pyx_result +#define __pyx_n_s_pyx_state __pyx_mstate_global->__pyx_n_s_pyx_state +#define __pyx_n_s_pyx_type __pyx_mstate_global->__pyx_n_s_pyx_type +#define __pyx_n_s_pyx_unpickle_Enum __pyx_mstate_global->__pyx_n_s_pyx_unpickle_Enum +#define __pyx_n_s_pyx_vtable __pyx_mstate_global->__pyx_n_s_pyx_vtable +#define __pyx_n_s_range __pyx_mstate_global->__pyx_n_s_range +#define __pyx_n_s_rates __pyx_mstate_global->__pyx_n_s_rates +#define __pyx_n_s_rates_view __pyx_mstate_global->__pyx_n_s_rates_view +#define __pyx_n_s_reactant_mat __pyx_mstate_global->__pyx_n_s_reactant_mat +#define __pyx_n_s_reactant_mat_view __pyx_mstate_global->__pyx_n_s_reactant_mat_view +#define __pyx_n_s_reduce __pyx_mstate_global->__pyx_n_s_reduce +#define __pyx_n_s_reduce_cython __pyx_mstate_global->__pyx_n_s_reduce_cython +#define __pyx_n_s_reduce_ex __pyx_mstate_global->__pyx_n_s_reduce_ex +#define __pyx_n_s_register __pyx_mstate_global->__pyx_n_s_register +#define __pyx_n_s_safe __pyx_mstate_global->__pyx_n_s_safe +#define __pyx_n_s_setstate __pyx_mstate_global->__pyx_n_s_setstate +#define __pyx_n_s_setstate_cython __pyx_mstate_global->__pyx_n_s_setstate_cython +#define __pyx_n_s_shape __pyx_mstate_global->__pyx_n_s_shape +#define __pyx_n_s_size __pyx_mstate_global->__pyx_n_s_size +#define __pyx_n_s_spec __pyx_mstate_global->__pyx_n_s_spec +#define __pyx_n_s_start __pyx_mstate_global->__pyx_n_s_start +#define __pyx_n_s_step __pyx_mstate_global->__pyx_n_s_step +#define __pyx_n_s_stop __pyx_mstate_global->__pyx_n_s_stop +#define __pyx_kp_s_strided_and_direct __pyx_mstate_global->__pyx_kp_s_strided_and_direct +#define __pyx_kp_s_strided_and_direct_or_indirect __pyx_mstate_global->__pyx_kp_s_strided_and_direct_or_indirect +#define __pyx_kp_s_strided_and_indirect __pyx_mstate_global->__pyx_kp_s_strided_and_indirect +#define __pyx_kp_s_stringsource __pyx_mstate_global->__pyx_kp_s_stringsource +#define __pyx_n_s_struct __pyx_mstate_global->__pyx_n_s_struct +#define __pyx_n_s_sum __pyx_mstate_global->__pyx_n_s_sum +#define __pyx_n_s_sys __pyx_mstate_global->__pyx_n_s_sys +#define __pyx_n_s_tau_scale __pyx_mstate_global->__pyx_n_s_tau_scale +#define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test +#define __pyx_n_s_total_rate __pyx_mstate_global->__pyx_n_s_total_rate +#define __pyx_kp_s_unable_to_allocate_array_data __pyx_mstate_global->__pyx_kp_s_unable_to_allocate_array_data +#define __pyx_kp_s_unable_to_allocate_shape_and_str __pyx_mstate_global->__pyx_kp_s_unable_to_allocate_shape_and_str +#define __pyx_n_s_unpack __pyx_mstate_global->__pyx_n_s_unpack +#define __pyx_n_s_update __pyx_mstate_global->__pyx_n_s_update +#define __pyx_n_s_version_info __pyx_mstate_global->__pyx_n_s_version_info +#define __pyx_n_s_x __pyx_mstate_global->__pyx_n_s_x +#define __pyx_n_s_x_view __pyx_mstate_global->__pyx_n_s_x_view +#define __pyx_int_0 __pyx_mstate_global->__pyx_int_0 +#define __pyx_int_1 __pyx_mstate_global->__pyx_int_1 +#define __pyx_int_3 __pyx_mstate_global->__pyx_int_3 +#define __pyx_int_112105877 __pyx_mstate_global->__pyx_int_112105877 +#define __pyx_int_136983863 __pyx_mstate_global->__pyx_int_136983863 +#define __pyx_int_184977713 __pyx_mstate_global->__pyx_int_184977713 +#define __pyx_int_neg_1 __pyx_mstate_global->__pyx_int_neg_1 +#define __pyx_slice__5 __pyx_mstate_global->__pyx_slice__5 +#define __pyx_tuple__4 __pyx_mstate_global->__pyx_tuple__4 +#define __pyx_tuple__8 __pyx_mstate_global->__pyx_tuple__8 +#define __pyx_tuple__9 __pyx_mstate_global->__pyx_tuple__9 +#define __pyx_tuple__10 __pyx_mstate_global->__pyx_tuple__10 +#define __pyx_tuple__11 __pyx_mstate_global->__pyx_tuple__11 +#define __pyx_tuple__12 __pyx_mstate_global->__pyx_tuple__12 +#define __pyx_tuple__13 __pyx_mstate_global->__pyx_tuple__13 +#define __pyx_tuple__14 __pyx_mstate_global->__pyx_tuple__14 +#define __pyx_tuple__15 __pyx_mstate_global->__pyx_tuple__15 +#define __pyx_tuple__16 __pyx_mstate_global->__pyx_tuple__16 +#define __pyx_tuple__17 __pyx_mstate_global->__pyx_tuple__17 +#define __pyx_tuple__18 __pyx_mstate_global->__pyx_tuple__18 +#define __pyx_tuple__19 __pyx_mstate_global->__pyx_tuple__19 +#define __pyx_tuple__20 __pyx_mstate_global->__pyx_tuple__20 +#define __pyx_tuple__22 __pyx_mstate_global->__pyx_tuple__22 +#define __pyx_codeobj__21 __pyx_mstate_global->__pyx_codeobj__21 +#define __pyx_codeobj__23 __pyx_mstate_global->__pyx_codeobj__23 +/* #### Code section: module_code ### */ + +/* "View.MemoryView":131 + * cdef bint dtype_is_object + * + * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< + * mode="c", bint allocate_buffer=True): + * */ /* Python wrapper */ -static PyObject *__pyx_pw_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety[] = "\n Additional safety test on :math:`\\tau`-leap, decrease the step size if\n the original is not small enough. Decrease a couple of times and then\n bail out because we don't want to spend too long decreasing the\n step size until we find a suitable one.\n "; -static PyMethodDef __pyx_mdef_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety = {"_cy_test_tau_leap_safety", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety}; -static PyObject *__pyx_pw_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyArrayObject *__pyx_v_x = 0; - PyArrayObject *__pyx_v_reactant_mat = 0; - PyArrayObject *__pyx_v_rates = 0; - double __pyx_v_tau_scale; - double __pyx_v_epsilon; +static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_shape = 0; + Py_ssize_t __pyx_v_itemsize; + PyObject *__pyx_v_format = 0; + PyObject *__pyx_v_mode = 0; + int __pyx_v_allocate_buffer; + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - PyObject *__pyx_r = 0; + int __pyx_r; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_cy_test_tau_leap_safety (wrapper)", 0); + __Pyx_RefNannySetupContext("__cinit__ (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); { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_reactant_mat,&__pyx_n_s_rates,&__pyx_n_s_tau_scale,&__pyx_n_s_epsilon,0}; - PyObject* values[5] = {0,0,0,0,0}; - if (unlikely(__pyx_kwds)) { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0}; + values[3] = __Pyx_Arg_NewRef_VARARGS(((PyObject *)__pyx_n_s_c)); + if (__pyx_kwds) { Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_VARARGS(__pyx_args, 4); CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + case 4: values[3] = __Pyx_Arg_VARARGS(__pyx_args, 3); CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + case 3: values[2] = __Pyx_Arg_VARARGS(__pyx_args, 2); CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 2: values[1] = __Pyx_Arg_VARARGS(__pyx_args, 1); CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 1: values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); CYTHON_FALLTHROUGH; case 0: break; default: goto __pyx_L5_argtuple_error; } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { + kw_args = __Pyx_NumKwargs_VARARGS(__pyx_kwds); + switch (__pyx_nargs) { case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--; + if (likely((values[0] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_shape)) != 0)) { + (void)__Pyx_Arg_NewRef_VARARGS(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) else goto __pyx_L5_argtuple_error; CYTHON_FALLTHROUGH; case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_reactant_mat)) != 0)) kw_args--; + if (likely((values[1] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_itemsize)) != 0)) { + (void)__Pyx_Arg_NewRef_VARARGS(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) else { - __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 1); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); __PYX_ERR(1, 131, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rates)) != 0)) kw_args--; + if (likely((values[2] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_format)) != 0)) { + (void)__Pyx_Arg_NewRef_VARARGS(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) else { - __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 2); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); __PYX_ERR(1, 131, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 3: - if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_tau_scale)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 3); __PYX_ERR(0, 11, __pyx_L3_error) + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_mode); + if (value) { values[3] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 4: - if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_epsilon)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 4); __PYX_ERR(0, 11, __pyx_L3_error) + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_allocate_buffer); + if (value) { values[4] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_cy_test_tau_leap_safety") < 0)) __PYX_ERR(0, 11, __pyx_L3_error) + 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, "__cinit__") < 0)) __PYX_ERR(1, 131, __pyx_L3_error) } - } else if (PyTuple_GET_SIZE(__pyx_args) != 5) { - goto __pyx_L5_argtuple_error; } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + 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); + values[1] = __Pyx_Arg_VARARGS(__pyx_args, 1); + values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_shape = ((PyObject*)values[0]); + __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) + __pyx_v_format = values[2]; + __pyx_v_mode = values[3]; + if (values[4]) { + __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 132, __pyx_L3_error) + } else { + + /* "View.MemoryView":132 + * + * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, + * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<< + * + * cdef int idx + */ + __pyx_v_allocate_buffer = ((int)1); } - __pyx_v_x = ((PyArrayObject *)values[0]); - __pyx_v_reactant_mat = ((PyArrayObject *)values[1]); - __pyx_v_rates = ((PyArrayObject *)values[2]); - __pyx_v_tau_scale = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_tau_scale == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error) - __pyx_v_epsilon = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_epsilon == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 15, __pyx_L3_error) } - goto __pyx_L4_argument_unpacking_done; + goto __pyx_L6_skip; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, __pyx_nargs); __PYX_ERR(1, 131, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; - __Pyx_AddTraceback("pygom.model._tau_leap._cy_test_tau_leap_safety", __pyx_clineno, __pyx_lineno, __pyx_filename); + { + 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("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); - return NULL; + return -1; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_x), __pyx_ptype_5numpy_ndarray, 1, "x", 0))) __PYX_ERR(0, 11, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_reactant_mat), __pyx_ptype_5numpy_ndarray, 1, "reactant_mat", 0))) __PYX_ERR(0, 12, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rates), __pyx_ptype_5numpy_ndarray, 1, "rates", 0))) __PYX_ERR(0, 13, __pyx_L1_error) - __pyx_r = __pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(__pyx_self, __pyx_v_x, __pyx_v_reactant_mat, __pyx_v_rates, __pyx_v_tau_scale, __pyx_v_epsilon); + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) __PYX_ERR(1, 131, __pyx_L1_error) + if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) { + PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); __PYX_ERR(1, 131, __pyx_L1_error) + } + __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer); + + /* "View.MemoryView":131 + * cdef bint dtype_is_object + * + * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< + * mode="c", bint allocate_buffer=True): + * + */ /* function exit code */ goto __pyx_L0; __pyx_L1_error:; - __pyx_r = NULL; + __pyx_r = -1; __pyx_L0:; + { + 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 PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_x, PyArrayObject *__pyx_v_reactant_mat, PyArrayObject *__pyx_v_rates, double __pyx_v_tau_scale, double __pyx_v_epsilon) { - __Pyx_memviewslice __pyx_v_rates_view = { 0, 0, { 0 }, { 0 }, { 0 } }; - __pyx_t_5numpy_int64_t __pyx_v_n_rates; - __Pyx_memviewslice __pyx_v_x_view = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_reactant_mat_view = { 0, 0, { 0 }, { 0 }, { 0 } }; - __pyx_t_5numpy_int64_t __pyx_v_n_reactants; - double __pyx_v_mu; - double __pyx_v_max_cdf; - double __pyx_v_new_cdf; - double __pyx_v_total_rate; - int __pyx_v_safe; - int __pyx_v_count; - double __pyx_v_cdf_val; - __pyx_t_5numpy_int64_t __pyx_v_i; - __pyx_t_5numpy_int64_t __pyx_v_j; - __Pyx_LocalBuf_ND __pyx_pybuffernd_rates; - __Pyx_Buffer __pyx_pybuffer_rates; - __Pyx_LocalBuf_ND __pyx_pybuffernd_reactant_mat; - __Pyx_Buffer __pyx_pybuffer_reactant_mat; - __Pyx_LocalBuf_ND __pyx_pybuffernd_x; - __Pyx_Buffer __pyx_pybuffer_x; - PyObject *__pyx_r = NULL; +static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) { + int __pyx_v_idx; + Py_ssize_t __pyx_v_dim; + char __pyx_v_order; + int __pyx_r; __Pyx_RefNannyDeclarations - __Pyx_memviewslice __pyx_t_1 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_t_2 = { 0, 0, { 0 }, { 0 }, { 0 } }; - PyObject *__pyx_t_3 = NULL; + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; - double __pyx_t_6; + PyObject *__pyx_t_6 = NULL; int __pyx_t_7; - __pyx_t_5numpy_int64_t __pyx_t_8; - __pyx_t_5numpy_int64_t __pyx_t_9; - __pyx_t_5numpy_int64_t __pyx_t_10; - __pyx_t_5numpy_int64_t __pyx_t_11; - __pyx_t_5numpy_int64_t __pyx_t_12; - __pyx_t_5numpy_int64_t __pyx_t_13; - __pyx_t_5numpy_int64_t __pyx_t_14; - __pyx_t_5numpy_int64_t __pyx_t_15; - int __pyx_t_16; + char *__pyx_t_8; + Py_ssize_t __pyx_t_9; + Py_UCS4 __pyx_t_10; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_cy_test_tau_leap_safety", 0); - __pyx_pybuffer_x.pybuffer.buf = NULL; - __pyx_pybuffer_x.refcount = 0; - __pyx_pybuffernd_x.data = NULL; - __pyx_pybuffernd_x.rcbuffer = &__pyx_pybuffer_x; - __pyx_pybuffer_reactant_mat.pybuffer.buf = NULL; - __pyx_pybuffer_reactant_mat.refcount = 0; - __pyx_pybuffernd_reactant_mat.data = NULL; - __pyx_pybuffernd_reactant_mat.rcbuffer = &__pyx_pybuffer_reactant_mat; - __pyx_pybuffer_rates.pybuffer.buf = NULL; - __pyx_pybuffer_rates.refcount = 0; - __pyx_pybuffernd_rates.data = NULL; - __pyx_pybuffernd_rates.rcbuffer = &__pyx_pybuffer_rates; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x.rcbuffer->pybuffer, (PyObject*)__pyx_v_x, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 11, __pyx_L1_error) - } - __pyx_pybuffernd_x.diminfo[0].strides = __pyx_pybuffernd_x.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x.diminfo[0].shape = __pyx_pybuffernd_x.rcbuffer->pybuffer.shape[0]; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer, (PyObject*)__pyx_v_reactant_mat, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 11, __pyx_L1_error) - } - __pyx_pybuffernd_reactant_mat.diminfo[0].strides = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_reactant_mat.diminfo[0].shape = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_reactant_mat.diminfo[1].strides = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_reactant_mat.diminfo[1].shape = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.shape[1]; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_rates.rcbuffer->pybuffer, (PyObject*)__pyx_v_rates, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 11, __pyx_L1_error) - } - __pyx_pybuffernd_rates.diminfo[0].strides = __pyx_pybuffernd_rates.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_rates.diminfo[0].shape = __pyx_pybuffernd_rates.rcbuffer->pybuffer.shape[0]; - - /* "pygom/model/_tau_leap.pyx":23 - * """ - * #view on arrays - * cdef double[:] rates_view = rates # <<<<<<<<<<<<<< - * cdef np.int64_t n_rates = rates.shape[0] - * cdef double[:] x_view = x - */ - __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_rates), PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 23, __pyx_L1_error) - __pyx_v_rates_view = __pyx_t_1; - __pyx_t_1.memview = NULL; - __pyx_t_1.data = NULL; + __Pyx_RefNannySetupContext("__cinit__", 0); + __Pyx_INCREF(__pyx_v_format); - /* "pygom/model/_tau_leap.pyx":24 - * #view on arrays - * cdef double[:] rates_view = rates - * cdef np.int64_t n_rates = rates.shape[0] # <<<<<<<<<<<<<< - * cdef double[:] x_view = x - * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat + /* "View.MemoryView":137 + * cdef Py_ssize_t dim + * + * self.ndim = len(shape) # <<<<<<<<<<<<<< + * self.itemsize = itemsize + * */ - __pyx_v_n_rates = (__pyx_v_rates->dimensions[0]); + if (unlikely(__pyx_v_shape == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(1, 137, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(1, 137, __pyx_L1_error) + __pyx_v_self->ndim = ((int)__pyx_t_1); - /* "pygom/model/_tau_leap.pyx":25 - * cdef double[:] rates_view = rates - * cdef np.int64_t n_rates = rates.shape[0] - * cdef double[:] x_view = x # <<<<<<<<<<<<<< - * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat - * cdef np.int64_t n_reactants = reactant_mat.shape[0] + /* "View.MemoryView":138 + * + * self.ndim = len(shape) + * self.itemsize = itemsize # <<<<<<<<<<<<<< + * + * if not self.ndim: */ - __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_x), PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 25, __pyx_L1_error) - __pyx_v_x_view = __pyx_t_1; - __pyx_t_1.memview = NULL; - __pyx_t_1.data = NULL; + __pyx_v_self->itemsize = __pyx_v_itemsize; - /* "pygom/model/_tau_leap.pyx":26 - * cdef np.int64_t n_rates = rates.shape[0] - * cdef double[:] x_view = x - * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat # <<<<<<<<<<<<<< - * cdef np.int64_t n_reactants = reactant_mat.shape[0] + /* "View.MemoryView":140 + * self.itemsize = itemsize + * + * if not self.ndim: # <<<<<<<<<<<<<< + * raise ValueError, "Empty shape tuple for cython.array" * */ - __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int64_t(((PyObject *)__pyx_v_reactant_mat), PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 26, __pyx_L1_error) - __pyx_v_reactant_mat_view = __pyx_t_2; - __pyx_t_2.memview = NULL; - __pyx_t_2.data = NULL; + __pyx_t_2 = (!(__pyx_v_self->ndim != 0)); + if (unlikely(__pyx_t_2)) { - /* "pygom/model/_tau_leap.pyx":27 - * cdef double[:] x_view = x - * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat - * cdef np.int64_t n_reactants = reactant_mat.shape[0] # <<<<<<<<<<<<<< + /* "View.MemoryView":141 * - * cdef double mu, max_cdf, new_cdf + * if not self.ndim: + * raise ValueError, "Empty shape tuple for cython.array" # <<<<<<<<<<<<<< + * + * if itemsize <= 0: */ - __pyx_v_n_reactants = (__pyx_v_reactant_mat->dimensions[0]); + __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Empty_shape_tuple_for_cython_arr, 0, 0); + __PYX_ERR(1, 141, __pyx_L1_error) - /* "pygom/model/_tau_leap.pyx":30 + /* "View.MemoryView":140 + * self.itemsize = itemsize + * + * if not self.ndim: # <<<<<<<<<<<<<< + * raise ValueError, "Empty shape tuple for cython.array" * - * cdef double mu, max_cdf, new_cdf - * cdef double total_rate = np.sum(rates) # <<<<<<<<<<<<<< - * safe = False - * cdef int count = 0 */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_sum); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - } } - __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_4, ((PyObject *)__pyx_v_rates)) : __Pyx_PyObject_CallOneArg(__pyx_t_5, ((PyObject *)__pyx_v_rates)); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_total_rate = __pyx_t_6; - /* "pygom/model/_tau_leap.pyx":31 - * cdef double mu, max_cdf, new_cdf - * cdef double total_rate = np.sum(rates) - * safe = False # <<<<<<<<<<<<<< - * cdef int count = 0 - * while safe is False: + /* "View.MemoryView":143 + * raise ValueError, "Empty shape tuple for cython.array" + * + * if itemsize <= 0: # <<<<<<<<<<<<<< + * raise ValueError, "itemsize <= 0 for cython.array" + * */ - __pyx_v_safe = 0; + __pyx_t_2 = (__pyx_v_itemsize <= 0); + if (unlikely(__pyx_t_2)) { - /* "pygom/model/_tau_leap.pyx":32 - * cdef double total_rate = np.sum(rates) - * safe = False - * cdef int count = 0 # <<<<<<<<<<<<<< - * while safe is False: - * cdf_val = 1.0 + /* "View.MemoryView":144 + * + * if itemsize <= 0: + * raise ValueError, "itemsize <= 0 for cython.array" # <<<<<<<<<<<<<< + * + * if not isinstance(format, bytes): */ - __pyx_v_count = 0; + __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_itemsize_0_for_cython_array, 0, 0); + __PYX_ERR(1, 144, __pyx_L1_error) - /* "pygom/model/_tau_leap.pyx":33 - * safe = False - * cdef int count = 0 - * while safe is False: # <<<<<<<<<<<<<< - * cdf_val = 1.0 - * for i in range(n_rates): + /* "View.MemoryView":143 + * raise ValueError, "Empty shape tuple for cython.array" + * + * if itemsize <= 0: # <<<<<<<<<<<<<< + * raise ValueError, "itemsize <= 0 for cython.array" + * */ - while (1) { - __pyx_t_7 = ((__pyx_v_safe == 0) != 0); - if (!__pyx_t_7) break; + } - /* "pygom/model/_tau_leap.pyx":34 - * cdef int count = 0 - * while safe is False: - * cdf_val = 1.0 # <<<<<<<<<<<<<< - * for i in range(n_rates): - * #xi = x[reactant_mat[:, i]] + /* "View.MemoryView":146 + * raise ValueError, "itemsize <= 0 for cython.array" + * + * if not isinstance(format, bytes): # <<<<<<<<<<<<<< + * format = format.encode('ASCII') + * self._format = format # keep a reference to the byte string */ - __pyx_v_cdf_val = 1.0; + __pyx_t_2 = PyBytes_Check(__pyx_v_format); + __pyx_t_3 = (!__pyx_t_2); + if (__pyx_t_3) { - /* "pygom/model/_tau_leap.pyx":35 - * while safe is False: - * cdf_val = 1.0 - * for i in range(n_rates): # <<<<<<<<<<<<<< - * #xi = x[reactant_mat[:, i]] - * #new_cdf = _ppois(xi, mu=tau_scale*r).min() + /* "View.MemoryView":147 + * + * if not isinstance(format, bytes): + * format = format.encode('ASCII') # <<<<<<<<<<<<<< + * self._format = format # keep a reference to the byte string + * self.format = self._format */ - __pyx_t_8 = __pyx_v_n_rates; - __pyx_t_9 = __pyx_t_8; - for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { - __pyx_v_i = __pyx_t_10; + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_format, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = NULL; + __pyx_t_7 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_7 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_n_s_ASCII}; + __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_4); + __pyx_t_4 = 0; - /* "pygom/model/_tau_leap.pyx":38 - * #xi = x[reactant_mat[:, i]] - * #new_cdf = _ppois(xi, mu=tau_scale*r).min() - * for j in range(n_reactants): # <<<<<<<<<<<<<< - * if reactant_mat_view[j, i] == 1: - * mu = rates_view[i] * tau_scale + /* "View.MemoryView":146 + * raise ValueError, "itemsize <= 0 for cython.array" + * + * if not isinstance(format, bytes): # <<<<<<<<<<<<<< + * format = format.encode('ASCII') + * self._format = format # keep a reference to the byte string */ - __pyx_t_11 = __pyx_v_n_reactants; - __pyx_t_12 = __pyx_t_11; - for (__pyx_t_13 = 0; __pyx_t_13 < __pyx_t_12; __pyx_t_13+=1) { - __pyx_v_j = __pyx_t_13; + } - /* "pygom/model/_tau_leap.pyx":39 - * #new_cdf = _ppois(xi, mu=tau_scale*r).min() - * for j in range(n_reactants): - * if reactant_mat_view[j, i] == 1: # <<<<<<<<<<<<<< - * mu = rates_view[i] * tau_scale - * new_cdf = csc.pdtr(floor(x_view[i]), mu) + /* "View.MemoryView":148 + * if not isinstance(format, bytes): + * format = format.encode('ASCII') + * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<< + * self.format = self._format + * */ - __pyx_t_14 = __pyx_v_j; - __pyx_t_15 = __pyx_v_i; - __pyx_t_7 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_reactant_mat_view.data + __pyx_t_14 * __pyx_v_reactant_mat_view.strides[0]) ) + __pyx_t_15 * __pyx_v_reactant_mat_view.strides[1]) ))) == 1) != 0); - if (__pyx_t_7) { + if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None) || __Pyx_RaiseUnexpectedTypeError("bytes", __pyx_v_format))) __PYX_ERR(1, 148, __pyx_L1_error) + __pyx_t_4 = __pyx_v_format; + __Pyx_INCREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __Pyx_GOTREF(__pyx_v_self->_format); + __Pyx_DECREF(__pyx_v_self->_format); + __pyx_v_self->_format = ((PyObject*)__pyx_t_4); + __pyx_t_4 = 0; - /* "pygom/model/_tau_leap.pyx":40 - * for j in range(n_reactants): - * if reactant_mat_view[j, i] == 1: - * mu = rates_view[i] * tau_scale # <<<<<<<<<<<<<< - * new_cdf = csc.pdtr(floor(x_view[i]), mu) - * if new_cdf < cdf_val: + /* "View.MemoryView":149 + * format = format.encode('ASCII') + * self._format = format # keep a reference to the byte string + * self.format = self._format # <<<<<<<<<<<<<< + * + * */ - __pyx_t_15 = __pyx_v_i; - __pyx_v_mu = ((*((double *) ( /* dim=0 */ (__pyx_v_rates_view.data + __pyx_t_15 * __pyx_v_rates_view.strides[0]) ))) * __pyx_v_tau_scale); + if (unlikely(__pyx_v_self->_format == Py_None)) { + PyErr_SetString(PyExc_TypeError, "expected bytes, NoneType found"); + __PYX_ERR(1, 149, __pyx_L1_error) + } + __pyx_t_8 = __Pyx_PyBytes_AsWritableString(__pyx_v_self->_format); if (unlikely((!__pyx_t_8) && PyErr_Occurred())) __PYX_ERR(1, 149, __pyx_L1_error) + __pyx_v_self->format = __pyx_t_8; - /* "pygom/model/_tau_leap.pyx":41 - * if reactant_mat_view[j, i] == 1: - * mu = rates_view[i] * tau_scale - * new_cdf = csc.pdtr(floor(x_view[i]), mu) # <<<<<<<<<<<<<< - * if new_cdf < cdf_val: - * cdf_val = new_cdf + /* "View.MemoryView":152 + * + * + * self._shape = PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<< + * self._strides = self._shape + self.ndim + * */ - __pyx_t_15 = __pyx_v_i; - __pyx_v_new_cdf = __pyx_f_5scipy_7special_14cython_special_pdtr(floor((*((double *) ( /* dim=0 */ (__pyx_v_x_view.data + __pyx_t_15 * __pyx_v_x_view.strides[0]) )))), __pyx_v_mu, 0); + __pyx_v_self->_shape = ((Py_ssize_t *)PyObject_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2))); - /* "pygom/model/_tau_leap.pyx":39 - * #new_cdf = _ppois(xi, mu=tau_scale*r).min() - * for j in range(n_reactants): - * if reactant_mat_view[j, i] == 1: # <<<<<<<<<<<<<< - * mu = rates_view[i] * tau_scale - * new_cdf = csc.pdtr(floor(x_view[i]), mu) + /* "View.MemoryView":153 + * + * self._shape = PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2) + * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<< + * + * if not self._shape: */ - } + __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim); - /* "pygom/model/_tau_leap.pyx":42 - * mu = rates_view[i] * tau_scale - * new_cdf = csc.pdtr(floor(x_view[i]), mu) - * if new_cdf < cdf_val: # <<<<<<<<<<<<<< - * cdf_val = new_cdf - * if new_cdf < cdf_val: + /* "View.MemoryView":155 + * self._strides = self._shape + self.ndim + * + * if not self._shape: # <<<<<<<<<<<<<< + * raise MemoryError, "unable to allocate shape and strides." + * */ - __pyx_t_7 = ((__pyx_v_new_cdf < __pyx_v_cdf_val) != 0); - if (__pyx_t_7) { + __pyx_t_3 = (!(__pyx_v_self->_shape != 0)); + if (unlikely(__pyx_t_3)) { - /* "pygom/model/_tau_leap.pyx":43 - * new_cdf = csc.pdtr(floor(x_view[i]), mu) - * if new_cdf < cdf_val: - * cdf_val = new_cdf # <<<<<<<<<<<<<< - * if new_cdf < cdf_val: - * cdf_val = new_cdf + /* "View.MemoryView":156 + * + * if not self._shape: + * raise MemoryError, "unable to allocate shape and strides." # <<<<<<<<<<<<<< + * + * */ - __pyx_v_cdf_val = __pyx_v_new_cdf; + __Pyx_Raise(__pyx_builtin_MemoryError, __pyx_kp_s_unable_to_allocate_shape_and_str, 0, 0); + __PYX_ERR(1, 156, __pyx_L1_error) - /* "pygom/model/_tau_leap.pyx":42 - * mu = rates_view[i] * tau_scale - * new_cdf = csc.pdtr(floor(x_view[i]), mu) - * if new_cdf < cdf_val: # <<<<<<<<<<<<<< - * cdf_val = new_cdf - * if new_cdf < cdf_val: + /* "View.MemoryView":155 + * self._strides = self._shape + self.ndim + * + * if not self._shape: # <<<<<<<<<<<<<< + * raise MemoryError, "unable to allocate shape and strides." + * */ - } - } + } - /* "pygom/model/_tau_leap.pyx":44 - * if new_cdf < cdf_val: - * cdf_val = new_cdf - * if new_cdf < cdf_val: # <<<<<<<<<<<<<< - * cdf_val = new_cdf - * #cdf_val[i * reactant_mat.shape[0] : (i * reactant_mat.shape[0]) + len(rates)] = _ppois(xi, mu=tau_scale*r) + /* "View.MemoryView":159 + * + * + * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<< + * if dim <= 0: + * raise ValueError, f"Invalid shape in axis {idx}: {dim}." */ - __pyx_t_7 = ((__pyx_v_new_cdf < __pyx_v_cdf_val) != 0); - if (__pyx_t_7) { + __pyx_t_7 = 0; + __pyx_t_4 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_4); + __pyx_t_1 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_4); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 159, __pyx_L1_error) + #endif + if (__pyx_t_1 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_1); __Pyx_INCREF(__pyx_t_5); __pyx_t_1++; if (unlikely((0 < 0))) __PYX_ERR(1, 159, __pyx_L1_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_4, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_t_5); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 159, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_v_dim = __pyx_t_9; + __pyx_v_idx = __pyx_t_7; + __pyx_t_7 = (__pyx_t_7 + 1); - /* "pygom/model/_tau_leap.pyx":45 - * cdf_val = new_cdf - * if new_cdf < cdf_val: - * cdf_val = new_cdf # <<<<<<<<<<<<<< - * #cdf_val[i * reactant_mat.shape[0] : (i * reactant_mat.shape[0]) + len(rates)] = _ppois(xi, mu=tau_scale*r) + /* "View.MemoryView":160 * + * for idx, dim in enumerate(shape): + * if dim <= 0: # <<<<<<<<<<<<<< + * raise ValueError, f"Invalid shape in axis {idx}: {dim}." + * self._shape[idx] = dim */ - __pyx_v_cdf_val = __pyx_v_new_cdf; + __pyx_t_3 = (__pyx_v_dim <= 0); + if (unlikely(__pyx_t_3)) { - /* "pygom/model/_tau_leap.pyx":44 - * if new_cdf < cdf_val: - * cdf_val = new_cdf - * if new_cdf < cdf_val: # <<<<<<<<<<<<<< - * cdf_val = new_cdf - * #cdf_val[i * reactant_mat.shape[0] : (i * reactant_mat.shape[0]) + len(rates)] = _ppois(xi, mu=tau_scale*r) + /* "View.MemoryView":161 + * for idx, dim in enumerate(shape): + * if dim <= 0: + * raise ValueError, f"Invalid shape in axis {idx}: {dim}." # <<<<<<<<<<<<<< + * self._shape[idx] = dim + * + */ + __pyx_t_5 = PyTuple_New(5); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 161, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_9 = 0; + __pyx_t_10 = 127; + __Pyx_INCREF(__pyx_kp_u_Invalid_shape_in_axis); + __pyx_t_9 += 22; + __Pyx_GIVEREF(__pyx_kp_u_Invalid_shape_in_axis); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_Invalid_shape_in_axis); + __pyx_t_6 = __Pyx_PyUnicode_From_int(__pyx_v_idx, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 161, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_kp_u_); + __pyx_t_9 += 2; + __Pyx_GIVEREF(__pyx_kp_u_); + PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u_); + __pyx_t_6 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_dim, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 161, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_kp_u__2); + __pyx_t_9 += 1; + __Pyx_GIVEREF(__pyx_kp_u__2); + PyTuple_SET_ITEM(__pyx_t_5, 4, __pyx_kp_u__2); + __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_5, 5, __pyx_t_9, __pyx_t_10); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 161, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_Raise(__pyx_builtin_ValueError, __pyx_t_6, 0, 0); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __PYX_ERR(1, 161, __pyx_L1_error) + + /* "View.MemoryView":160 + * + * for idx, dim in enumerate(shape): + * if dim <= 0: # <<<<<<<<<<<<<< + * raise ValueError, f"Invalid shape in axis {idx}: {dim}." + * self._shape[idx] = dim */ - } } - /* "pygom/model/_tau_leap.pyx":49 + /* "View.MemoryView":162 + * if dim <= 0: + * raise ValueError, f"Invalid shape in axis {idx}: {dim}." + * self._shape[idx] = dim # <<<<<<<<<<<<<< * - * # the expected probability that our jump will exceed the value - * max_cdf = 1.0 - cdf_val # <<<<<<<<<<<<<< - * # cannot allow it to exceed out epsilon - * if max_cdf > epsilon: + * cdef char order */ - __pyx_v_max_cdf = (1.0 - __pyx_v_cdf_val); + (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim; - /* "pygom/model/_tau_leap.pyx":51 - * max_cdf = 1.0 - cdf_val - * # cannot allow it to exceed out epsilon - * if max_cdf > epsilon: # <<<<<<<<<<<<<< - * tau_scale /= (max_cdf / epsilon) - * else: + /* "View.MemoryView":159 + * + * + * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<< + * if dim <= 0: + * raise ValueError, f"Invalid shape in axis {idx}: {dim}." */ - __pyx_t_7 = ((__pyx_v_max_cdf > __pyx_v_epsilon) != 0); - if (__pyx_t_7) { + } + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - /* "pygom/model/_tau_leap.pyx":52 - * # cannot allow it to exceed out epsilon - * if max_cdf > epsilon: - * tau_scale /= (max_cdf / epsilon) # <<<<<<<<<<<<<< + /* "View.MemoryView":165 + * + * cdef char order + * if mode == 'c': # <<<<<<<<<<<<<< + * order = b'C' + * self.mode = u'c' + */ + __pyx_t_3 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(1, 165, __pyx_L1_error) + if (__pyx_t_3) { + + /* "View.MemoryView":166 + * cdef char order + * if mode == 'c': + * order = b'C' # <<<<<<<<<<<<<< + * self.mode = u'c' + * elif mode == 'fortran': + */ + __pyx_v_order = 'C'; + + /* "View.MemoryView":167 + * if mode == 'c': + * order = b'C' + * self.mode = u'c' # <<<<<<<<<<<<<< + * elif mode == 'fortran': + * order = b'F' + */ + __Pyx_INCREF(__pyx_n_u_c); + __Pyx_GIVEREF(__pyx_n_u_c); + __Pyx_GOTREF(__pyx_v_self->mode); + __Pyx_DECREF(__pyx_v_self->mode); + __pyx_v_self->mode = __pyx_n_u_c; + + /* "View.MemoryView":165 + * + * cdef char order + * if mode == 'c': # <<<<<<<<<<<<<< + * order = b'C' + * self.mode = u'c' + */ + goto __pyx_L11; + } + + /* "View.MemoryView":168 + * order = b'C' + * self.mode = u'c' + * elif mode == 'fortran': # <<<<<<<<<<<<<< + * order = b'F' + * self.mode = u'fortran' + */ + __pyx_t_3 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(1, 168, __pyx_L1_error) + if (likely(__pyx_t_3)) { + + /* "View.MemoryView":169 + * self.mode = u'c' + * elif mode == 'fortran': + * order = b'F' # <<<<<<<<<<<<<< + * self.mode = u'fortran' * else: - * safe = True */ - __pyx_v_tau_scale = (__pyx_v_tau_scale / (__pyx_v_max_cdf / __pyx_v_epsilon)); + __pyx_v_order = 'F'; - /* "pygom/model/_tau_leap.pyx":51 - * max_cdf = 1.0 - cdf_val - * # cannot allow it to exceed out epsilon - * if max_cdf > epsilon: # <<<<<<<<<<<<<< - * tau_scale /= (max_cdf / epsilon) + /* "View.MemoryView":170 + * elif mode == 'fortran': + * order = b'F' + * self.mode = u'fortran' # <<<<<<<<<<<<<< * else: + * raise ValueError, f"Invalid mode, expected 'c' or 'fortran', got {mode}" */ - goto __pyx_L12; - } + __Pyx_INCREF(__pyx_n_u_fortran); + __Pyx_GIVEREF(__pyx_n_u_fortran); + __Pyx_GOTREF(__pyx_v_self->mode); + __Pyx_DECREF(__pyx_v_self->mode); + __pyx_v_self->mode = __pyx_n_u_fortran; - /* "pygom/model/_tau_leap.pyx":54 - * tau_scale /= (max_cdf / epsilon) + /* "View.MemoryView":168 + * order = b'C' + * self.mode = u'c' + * elif mode == 'fortran': # <<<<<<<<<<<<<< + * order = b'F' + * self.mode = u'fortran' + */ + goto __pyx_L11; + } + + /* "View.MemoryView":172 + * self.mode = u'fortran' * else: - * safe = True # <<<<<<<<<<<<<< + * raise ValueError, f"Invalid mode, expected 'c' or 'fortran', got {mode}" # <<<<<<<<<<<<<< * - * if tau_scale*total_rate <= 1.0 or count > 256: + * self.len = fill_contig_strides_array(self._shape, self._strides, itemsize, self.ndim, order) */ - /*else*/ { - __pyx_v_safe = 1; - } - __pyx_L12:; + /*else*/ { + __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_v_mode, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 172, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Invalid_mode_expected_c_or_fortr, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 172, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_Raise(__pyx_builtin_ValueError, __pyx_t_6, 0, 0); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __PYX_ERR(1, 172, __pyx_L1_error) + } + __pyx_L11:; - /* "pygom/model/_tau_leap.pyx":56 - * safe = True + /* "View.MemoryView":174 + * raise ValueError, f"Invalid mode, expected 'c' or 'fortran', got {mode}" * - * if tau_scale*total_rate <= 1.0 or count > 256: # <<<<<<<<<<<<<< - * return False - * count += 1 + * self.len = fill_contig_strides_array(self._shape, self._strides, itemsize, self.ndim, order) # <<<<<<<<<<<<<< + * + * self.free_data = allocate_buffer */ - __pyx_t_16 = (((__pyx_v_tau_scale * __pyx_v_total_rate) <= 1.0) != 0); - if (!__pyx_t_16) { - } else { - __pyx_t_7 = __pyx_t_16; - goto __pyx_L14_bool_binop_done; - } - __pyx_t_16 = ((__pyx_v_count > 0x100) != 0); - __pyx_t_7 = __pyx_t_16; - __pyx_L14_bool_binop_done:; - if (__pyx_t_7) { + __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order); - /* "pygom/model/_tau_leap.pyx":57 + /* "View.MemoryView":176 + * self.len = fill_contig_strides_array(self._shape, self._strides, itemsize, self.ndim, order) * - * if tau_scale*total_rate <= 1.0 or count > 256: - * return False # <<<<<<<<<<<<<< - * count += 1 + * self.free_data = allocate_buffer # <<<<<<<<<<<<<< + * self.dtype_is_object = format == b'O' * */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(Py_False); - __pyx_r = Py_False; - goto __pyx_L0; + __pyx_v_self->free_data = __pyx_v_allocate_buffer; - /* "pygom/model/_tau_leap.pyx":56 - * safe = True + /* "View.MemoryView":177 * - * if tau_scale*total_rate <= 1.0 or count > 256: # <<<<<<<<<<<<<< - * return False - * count += 1 + * self.free_data = allocate_buffer + * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<< + * + * if allocate_buffer: */ - } + __pyx_t_6 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 177, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 177, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_v_self->dtype_is_object = __pyx_t_3; - /* "pygom/model/_tau_leap.pyx":58 - * if tau_scale*total_rate <= 1.0 or count > 256: - * return False - * count += 1 # <<<<<<<<<<<<<< + /* "View.MemoryView":179 + * self.dtype_is_object = format == b'O' + * + * if allocate_buffer: # <<<<<<<<<<<<<< + * _allocate_buffer(self) * - * return tau_scale, True */ - __pyx_v_count = (__pyx_v_count + 1); - } + if (__pyx_v_allocate_buffer) { - /* "pygom/model/_tau_leap.pyx":60 - * count += 1 + /* "View.MemoryView":180 * - * return tau_scale, True # <<<<<<<<<<<<<< + * if allocate_buffer: + * _allocate_buffer(self) # <<<<<<<<<<<<<< + * + * @cname('getbuffer') */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = PyFloat_FromDouble(__pyx_v_tau_scale); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); - __Pyx_INCREF(Py_True); - __Pyx_GIVEREF(Py_True); - PyTuple_SET_ITEM(__pyx_t_5, 1, Py_True); - __pyx_t_3 = 0; - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; - goto __pyx_L0; + __pyx_t_7 = __pyx_array_allocate_buffer(__pyx_v_self); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(1, 180, __pyx_L1_error) - /* "pygom/model/_tau_leap.pyx":11 - * @cython.wraparound(False) # Deactivate negative indexing. - * @cython.cdivision(True) # Deactivate the div 0 error checking - * def _cy_test_tau_leap_safety(np.ndarray[np.float64_t] x, # <<<<<<<<<<<<<< - * np.ndarray[np.int64_t, ndim=2] reactant_mat, - * np.ndarray[np.float64_t] rates, + /* "View.MemoryView":179 + * self.dtype_is_object = format == b'O' + * + * if allocate_buffer: # <<<<<<<<<<<<<< + * _allocate_buffer(self) + * + */ + } + + /* "View.MemoryView":131 + * cdef bint dtype_is_object + * + * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< + * mode="c", bint allocate_buffer=True): + * */ /* function exit code */ - __pyx_L1_error:; - __PYX_XDEC_MEMVIEW(&__pyx_t_1, 1); - __PYX_XDEC_MEMVIEW(&__pyx_t_2, 1); - __Pyx_XDECREF(__pyx_t_3); + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); - { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_rates.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); - __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("pygom.model._tau_leap._cy_test_tau_leap_safety", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - goto __pyx_L2; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; __pyx_L0:; - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_rates.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); - __pyx_L2:; - __PYX_XDEC_MEMVIEW(&__pyx_v_rates_view, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_x_view, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_reactant_mat_view, 1); - __Pyx_XGIVEREF(__pyx_r); + __Pyx_XDECREF(__pyx_v_format); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":734 - * ctypedef npy_cdouble complex_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) +/* "View.MemoryView":182 + * _allocate_buffer(self) * + * @cname('getbuffer') # <<<<<<<<<<<<<< + * def __getbuffer__(self, Py_buffer *info, int flags): + * cdef int bufmode = -1 */ -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { - PyObject *__pyx_r = NULL; +/* Python wrapper */ +CYTHON_UNUSED static int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ +CYTHON_UNUSED static int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + int __pyx_r; __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":735 - * - * cdef inline object PyArray_MultiIterNew1(a): - * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew2(a, b): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 735, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":734 - * ctypedef npy_cdouble complex_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) - * - */ + __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":737 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { - PyObject *__pyx_r = NULL; +static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + int __pyx_v_bufmode; + int __pyx_r; __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; + int __pyx_t_1; + char *__pyx_t_2; + Py_ssize_t __pyx_t_3; + int __pyx_t_4; + Py_ssize_t *__pyx_t_5; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); + if (unlikely(__pyx_v_info == NULL)) { + PyErr_SetString(PyExc_BufferError, "PyObject_GetBuffer: view==NULL argument is obsolete"); + return -1; + } + __Pyx_RefNannySetupContext("__getbuffer__", 0); + __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(__pyx_v_info->obj); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":738 - * - * cdef inline object PyArray_MultiIterNew2(a, b): - * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): + /* "View.MemoryView":184 + * @cname('getbuffer') + * def __getbuffer__(self, Py_buffer *info, int flags): + * cdef int bufmode = -1 # <<<<<<<<<<<<<< + * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): + * if self.mode == u"c": */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 738, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; + __pyx_v_bufmode = -1; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":737 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) - * + /* "View.MemoryView":185 + * def __getbuffer__(self, Py_buffer *info, int flags): + * cdef int bufmode = -1 + * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): # <<<<<<<<<<<<<< + * if self.mode == u"c": + * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS */ + __pyx_t_1 = ((__pyx_v_flags & ((PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS) | PyBUF_ANY_CONTIGUOUS)) != 0); + if (__pyx_t_1) { - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":740 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) - * + /* "View.MemoryView":186 + * cdef int bufmode = -1 + * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): + * if self.mode == u"c": # <<<<<<<<<<<<<< + * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + * elif self.mode == u"fortran": */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 186, __pyx_L1_error) + if (__pyx_t_1) { -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); + /* "View.MemoryView":187 + * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): + * if self.mode == u"c": + * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<< + * elif self.mode == u"fortran": + * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + */ + __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":741 - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): - * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + /* "View.MemoryView":186 + * cdef int bufmode = -1 + * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): + * if self.mode == u"c": # <<<<<<<<<<<<<< + * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + * elif self.mode == u"fortran": */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 741, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; + goto __pyx_L4; + } - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":740 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) - * + /* "View.MemoryView":188 + * if self.mode == u"c": + * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + * elif self.mode == u"fortran": # <<<<<<<<<<<<<< + * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + * if not (flags & bufmode): */ + __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 188, __pyx_L1_error) + if (__pyx_t_1) { - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":189 + * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + * elif self.mode == u"fortran": + * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<< + * if not (flags & bufmode): + * raise ValueError, "Can only create a buffer that is contiguous in memory." + */ + __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS); -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":743 - * return PyArray_MultiIterNew(3, a, b, c) - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(4, a, b, c, d) - * + /* "View.MemoryView":188 + * if self.mode == u"c": + * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + * elif self.mode == u"fortran": # <<<<<<<<<<<<<< + * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + * if not (flags & bufmode): */ + } + __pyx_L4:; -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); + /* "View.MemoryView":190 + * elif self.mode == u"fortran": + * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + * if not (flags & bufmode): # <<<<<<<<<<<<<< + * raise ValueError, "Can only create a buffer that is contiguous in memory." + * info.buf = self.data + */ + __pyx_t_1 = (!((__pyx_v_flags & __pyx_v_bufmode) != 0)); + if (unlikely(__pyx_t_1)) { - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":744 - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): - * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + /* "View.MemoryView":191 + * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + * if not (flags & bufmode): + * raise ValueError, "Can only create a buffer that is contiguous in memory." # <<<<<<<<<<<<<< + * info.buf = self.data + * info.len = self.len */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 744, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; + __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Can_only_create_a_buffer_that_is, 0, 0); + __PYX_ERR(1, 191, __pyx_L1_error) - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":743 - * return PyArray_MultiIterNew(3, a, b, c) - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(4, a, b, c, d) - * + /* "View.MemoryView":190 + * elif self.mode == u"fortran": + * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + * if not (flags & bufmode): # <<<<<<<<<<<<<< + * raise ValueError, "Can only create a buffer that is contiguous in memory." + * info.buf = self.data */ + } - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":185 + * def __getbuffer__(self, Py_buffer *info, int flags): + * cdef int bufmode = -1 + * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): # <<<<<<<<<<<<<< + * if self.mode == u"c": + * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + */ + } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":746 - * return PyArray_MultiIterNew(4, a, b, c, d) - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(5, a, b, c, d, e) + /* "View.MemoryView":192 + * if not (flags & bufmode): + * raise ValueError, "Can only create a buffer that is contiguous in memory." + * info.buf = self.data # <<<<<<<<<<<<<< + * info.len = self.len * */ + __pyx_t_2 = __pyx_v_self->data; + __pyx_v_info->buf = __pyx_t_2; -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":747 - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): - * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< + /* "View.MemoryView":193 + * raise ValueError, "Can only create a buffer that is contiguous in memory." + * info.buf = self.data + * info.len = self.len # <<<<<<<<<<<<<< * - * cdef inline tuple PyDataType_SHAPE(dtype d): + * if flags & PyBUF_STRIDES: */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 747, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; + __pyx_t_3 = __pyx_v_self->len; + __pyx_v_info->len = __pyx_t_3; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":746 - * return PyArray_MultiIterNew(4, a, b, c, d) + /* "View.MemoryView":195 + * info.len = self.len * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(5, a, b, c, d, e) + * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< + * info.ndim = self.ndim + * info.shape = self._shape + */ + __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0); + if (__pyx_t_1) { + + /* "View.MemoryView":196 * + * if flags & PyBUF_STRIDES: + * info.ndim = self.ndim # <<<<<<<<<<<<<< + * info.shape = self._shape + * info.strides = self._strides */ + __pyx_t_4 = __pyx_v_self->ndim; + __pyx_v_info->ndim = __pyx_t_4; - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":749 - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape + /* "View.MemoryView":197 + * if flags & PyBUF_STRIDES: + * info.ndim = self.ndim + * info.shape = self._shape # <<<<<<<<<<<<<< + * info.strides = self._strides + * else: */ + __pyx_t_5 = __pyx_v_self->_shape; + __pyx_v_info->shape = __pyx_t_5; -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__pyx_v_d) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("PyDataType_SHAPE", 0); + /* "View.MemoryView":198 + * info.ndim = self.ndim + * info.shape = self._shape + * info.strides = self._strides # <<<<<<<<<<<<<< + * else: + * info.ndim = 1 + */ + __pyx_t_5 = __pyx_v_self->_strides; + __pyx_v_info->strides = __pyx_t_5; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":750 + /* "View.MemoryView":195 + * info.len = self.len * - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< - * return d.subarray.shape - * else: + * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< + * info.ndim = self.ndim + * info.shape = self._shape */ - __pyx_t_1 = (PyDataType_HASSUBARRAY(__pyx_v_d) != 0); - if (__pyx_t_1) { + goto __pyx_L6; + } - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":751 - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape # <<<<<<<<<<<<<< - * else: - * return () + /* "View.MemoryView":200 + * info.strides = self._strides + * else: + * info.ndim = 1 # <<<<<<<<<<<<<< + * info.shape = &self.len if flags & PyBUF_ND else NULL + * info.strides = NULL */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject*)__pyx_v_d->subarray->shape)); - __pyx_r = ((PyObject*)__pyx_v_d->subarray->shape); - goto __pyx_L0; + /*else*/ { + __pyx_v_info->ndim = 1; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":750 + /* "View.MemoryView":201 + * else: + * info.ndim = 1 + * info.shape = &self.len if flags & PyBUF_ND else NULL # <<<<<<<<<<<<<< + * info.strides = NULL * - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< - * return d.subarray.shape - * else: */ - } + __pyx_t_1 = ((__pyx_v_flags & PyBUF_ND) != 0); + if (__pyx_t_1) { + __pyx_t_5 = (&__pyx_v_self->len); + } else { + __pyx_t_5 = NULL; + } + __pyx_v_info->shape = __pyx_t_5; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":753 - * return d.subarray.shape - * else: - * return () # <<<<<<<<<<<<<< - * + /* "View.MemoryView":202 + * info.ndim = 1 + * info.shape = &self.len if flags & PyBUF_ND else NULL + * info.strides = NULL # <<<<<<<<<<<<<< * + * info.suboffsets = NULL */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_empty_tuple); - __pyx_r = __pyx_empty_tuple; - goto __pyx_L0; + __pyx_v_info->strides = NULL; } + __pyx_L6:; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":749 - * return PyArray_MultiIterNew(5, a, b, c, d, e) + /* "View.MemoryView":204 + * info.strides = NULL * - * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape + * info.suboffsets = NULL # <<<<<<<<<<<<<< + * info.itemsize = self.itemsize + * info.readonly = 0 */ + __pyx_v_info->suboffsets = NULL; - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":928 - * int _import_umath() except -1 + /* "View.MemoryView":205 * - * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) + * info.suboffsets = NULL + * info.itemsize = self.itemsize # <<<<<<<<<<<<<< + * info.readonly = 0 + * info.format = self.format if flags & PyBUF_FORMAT else NULL */ + __pyx_t_3 = __pyx_v_self->itemsize; + __pyx_v_info->itemsize = __pyx_t_3; -static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("set_array_base", 0); + /* "View.MemoryView":206 + * info.suboffsets = NULL + * info.itemsize = self.itemsize + * info.readonly = 0 # <<<<<<<<<<<<<< + * info.format = self.format if flags & PyBUF_FORMAT else NULL + * info.obj = self + */ + __pyx_v_info->readonly = 0; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":929 - * - * cdef inline void set_array_base(ndarray arr, object base): - * Py_INCREF(base) # important to do this before stealing the reference below! # <<<<<<<<<<<<<< - * PyArray_SetBaseObject(arr, base) + /* "View.MemoryView":207 + * info.itemsize = self.itemsize + * info.readonly = 0 + * info.format = self.format if flags & PyBUF_FORMAT else NULL # <<<<<<<<<<<<<< + * info.obj = self * */ - Py_INCREF(__pyx_v_base); + __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); + if (__pyx_t_1) { + __pyx_t_2 = __pyx_v_self->format; + } else { + __pyx_t_2 = NULL; + } + __pyx_v_info->format = __pyx_t_2; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":930 - * cdef inline void set_array_base(ndarray arr, object base): - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) # <<<<<<<<<<<<<< + /* "View.MemoryView":208 + * info.readonly = 0 + * info.format = self.format if flags & PyBUF_FORMAT else NULL + * info.obj = self # <<<<<<<<<<<<<< * - * cdef inline object get_array_base(ndarray arr): + * def __dealloc__(array self): */ - (void)(PyArray_SetBaseObject(__pyx_v_arr, __pyx_v_base)); + __Pyx_INCREF((PyObject *)__pyx_v_self); + __Pyx_GIVEREF((PyObject *)__pyx_v_self); + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); + __pyx_v_info->obj = ((PyObject *)__pyx_v_self); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":928 - * int _import_umath() except -1 + /* "View.MemoryView":182 + * _allocate_buffer(self) * - * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) + * @cname('getbuffer') # <<<<<<<<<<<<<< + * def __getbuffer__(self, Py_buffer *info, int flags): + * cdef int bufmode = -1 */ /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + if (__pyx_v_info->obj != NULL) { + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; + } + goto __pyx_L2; + __pyx_L0:; + if (__pyx_v_info->obj == Py_None) { + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; + } + __pyx_L2:; __Pyx_RefNannyFinishContext(); + return __pyx_r; } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":932 - * PyArray_SetBaseObject(arr, base) +/* "View.MemoryView":210 + * info.obj = self * - * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< - * base = PyArray_BASE(arr) - * if base is NULL: + * def __dealloc__(array self): # <<<<<<<<<<<<<< + * if self.callback_free_data != NULL: + * self.callback_free_data(self.data) */ -static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { - PyObject *__pyx_v_base; - PyObject *__pyx_r = NULL; +/* Python wrapper */ +static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/ +static void __pyx_array___dealloc__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +static void __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) { int __pyx_t_1; - __Pyx_RefNannySetupContext("get_array_base", 0); + int __pyx_t_2; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":933 + /* "View.MemoryView":211 * - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) # <<<<<<<<<<<<<< - * if base is NULL: - * return None + * def __dealloc__(array self): + * if self.callback_free_data != NULL: # <<<<<<<<<<<<<< + * self.callback_free_data(self.data) + * elif self.free_data and self.data is not NULL: */ - __pyx_v_base = PyArray_BASE(__pyx_v_arr); + __pyx_t_1 = (__pyx_v_self->callback_free_data != NULL); + if (__pyx_t_1) { - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":934 - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) - * if base is NULL: # <<<<<<<<<<<<<< - * return None - * return base + /* "View.MemoryView":212 + * def __dealloc__(array self): + * if self.callback_free_data != NULL: + * self.callback_free_data(self.data) # <<<<<<<<<<<<<< + * elif self.free_data and self.data is not NULL: + * if self.dtype_is_object: */ - __pyx_t_1 = ((__pyx_v_base == NULL) != 0); - if (__pyx_t_1) { + __pyx_v_self->callback_free_data(__pyx_v_self->data); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":935 - * base = PyArray_BASE(arr) - * if base is NULL: - * return None # <<<<<<<<<<<<<< - * return base + /* "View.MemoryView":211 * + * def __dealloc__(array self): + * if self.callback_free_data != NULL: # <<<<<<<<<<<<<< + * self.callback_free_data(self.data) + * elif self.free_data and self.data is not NULL: */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; + goto __pyx_L3; + } - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":934 - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) - * if base is NULL: # <<<<<<<<<<<<<< - * return None - * return base + /* "View.MemoryView":213 + * if self.callback_free_data != NULL: + * self.callback_free_data(self.data) + * elif self.free_data and self.data is not NULL: # <<<<<<<<<<<<<< + * if self.dtype_is_object: + * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) */ + if (__pyx_v_self->free_data) { + } else { + __pyx_t_1 = __pyx_v_self->free_data; + goto __pyx_L4_bool_binop_done; } + __pyx_t_2 = (__pyx_v_self->data != NULL); + __pyx_t_1 = __pyx_t_2; + __pyx_L4_bool_binop_done:; + if (__pyx_t_1) { - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":936 - * if base is NULL: - * return None - * return base # <<<<<<<<<<<<<< - * - * # Versions of the import_* functions which are more suitable for + /* "View.MemoryView":214 + * self.callback_free_data(self.data) + * elif self.free_data and self.data is not NULL: + * if self.dtype_is_object: # <<<<<<<<<<<<<< + * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) + * free(self.data) */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_base)); - __pyx_r = ((PyObject *)__pyx_v_base); - goto __pyx_L0; + if (__pyx_v_self->dtype_is_object) { - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":932 - * PyArray_SetBaseObject(arr, base) - * - * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< - * base = PyArray_BASE(arr) - * if base is NULL: + /* "View.MemoryView":215 + * elif self.free_data and self.data is not NULL: + * if self.dtype_is_object: + * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) # <<<<<<<<<<<<<< + * free(self.data) + * PyObject_Free(self._shape) */ + __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0); - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":940 - * # Versions of the import_* functions which are more suitable for - * # Cython code. - * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< - * try: - * __pyx_import_array() + /* "View.MemoryView":214 + * self.callback_free_data(self.data) + * elif self.free_data and self.data is not NULL: + * if self.dtype_is_object: # <<<<<<<<<<<<<< + * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) + * free(self.data) */ + } -static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("import_array", 0); - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":941 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * __pyx_import_array() - * except Exception: + /* "View.MemoryView":216 + * if self.dtype_is_object: + * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) + * free(self.data) # <<<<<<<<<<<<<< + * PyObject_Free(self._shape) + * */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { + free(__pyx_v_self->data); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":942 - * cdef inline int import_array() except -1: - * try: - * __pyx_import_array() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") + /* "View.MemoryView":213 + * if self.callback_free_data != NULL: + * self.callback_free_data(self.data) + * elif self.free_data and self.data is not NULL: # <<<<<<<<<<<<<< + * if self.dtype_is_object: + * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) */ - __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 942, __pyx_L3_error) + } + __pyx_L3:; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":941 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * __pyx_import_array() - * except Exception: + /* "View.MemoryView":217 + * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) + * free(self.data) + * PyObject_Free(self._shape) # <<<<<<<<<<<<<< + * + * @property */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; + PyObject_Free(__pyx_v_self->_shape); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":943 - * try: - * __pyx_import_array() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.multiarray failed to import") + /* "View.MemoryView":210 + * info.obj = self * + * def __dealloc__(array self): # <<<<<<<<<<<<<< + * if self.callback_free_data != NULL: + * self.callback_free_data(self.data) */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 943, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":944 - * __pyx_import_array() - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + /* function exit code */ +} + +/* "View.MemoryView":219 + * PyObject_Free(self._shape) * - * cdef inline int import_umath() except -1: + * @property # <<<<<<<<<<<<<< + * def memview(self): + * return self.get_memview() */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 944, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 944, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":941 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * __pyx_import_array() - * except Exception: +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_15View_dot_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_15View_dot_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 1); + + /* "View.MemoryView":221 + * @property + * def memview(self): + * return self.get_memview() # <<<<<<<<<<<<<< + * + * @cname('get_memview') */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = ((struct __pyx_vtabstruct_array *)__pyx_v_self->__pyx_vtab)->get_memview(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":940 - * # Versions of the import_* functions which are more suitable for - * # Cython code. - * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< - * try: - * __pyx_import_array() + /* "View.MemoryView":219 + * PyObject_Free(self._shape) + * + * @property # <<<<<<<<<<<<<< + * def memview(self): + * return self.get_memview() */ /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":946 - * raise ImportError("numpy.core.multiarray failed to import") +/* "View.MemoryView":224 * - * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() + * @cname('get_memview') + * cdef get_memview(self): # <<<<<<<<<<<<<< + * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE + * return memoryview(self, flags, self.dtype_is_object) */ -static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { - int __pyx_r; +static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *__pyx_v_self) { + int __pyx_v_flags; + PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("import_umath", 0); + __Pyx_RefNannySetupContext("get_memview", 1); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":947 + /* "View.MemoryView":225 + * @cname('get_memview') + * cdef get_memview(self): + * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<< + * return memoryview(self, flags, self.dtype_is_object) * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { + __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":948 - * cdef inline int import_umath() except -1: - * try: - * _import_umath() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.umath failed to import") + /* "View.MemoryView":226 + * cdef get_memview(self): + * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE + * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<< + * + * def __len__(self): */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 948, __pyx_L3_error) + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF((PyObject *)__pyx_v_self); + __Pyx_GIVEREF((PyObject *)__pyx_v_self); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self))) __PYX_ERR(1, 226, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1)) __PYX_ERR(1, 226, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2)) __PYX_ERR(1, 226, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":947 + /* "View.MemoryView":224 * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: + * @cname('get_memview') + * cdef get_memview(self): # <<<<<<<<<<<<<< + * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE + * return memoryview(self, flags, self.dtype_is_object) */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":949 - * try: - * _import_umath() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.umath failed to import") + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("View.MemoryView.array.get_memview", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "View.MemoryView":228 + * return memoryview(self, flags, self.dtype_is_object) + * + * def __len__(self): # <<<<<<<<<<<<<< + * return self._shape[0] * */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 949, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":950 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_ufunc() except -1: - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 950, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 950, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; +/* Python wrapper */ +static Py_ssize_t __pyx_array___len__(PyObject *__pyx_v_self); /*proto*/ +static Py_ssize_t __pyx_array___len__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + Py_ssize_t __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__len__(((struct __pyx_array_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static Py_ssize_t __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__len__(struct __pyx_array_obj *__pyx_v_self) { + Py_ssize_t __pyx_r; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":947 + /* "View.MemoryView":229 * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: + * def __len__(self): + * return self._shape[0] # <<<<<<<<<<<<<< + * + * def __getattr__(self, attr): */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } + __pyx_r = (__pyx_v_self->_shape[0]); + goto __pyx_L0; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":946 - * raise ImportError("numpy.core.multiarray failed to import") + /* "View.MemoryView":228 + * return memoryview(self, flags, self.dtype_is_object) + * + * def __len__(self): # <<<<<<<<<<<<<< + * return self._shape[0] * - * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() */ /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; __pyx_L0:; - __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":952 - * raise ImportError("numpy.core.umath failed to import") +/* "View.MemoryView":231 + * return self._shape[0] + * + * def __getattr__(self, attr): # <<<<<<<<<<<<<< + * return getattr(self.memview, attr) * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() */ -static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { - int __pyx_r; +/* Python wrapper */ +static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/ +static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) { + PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("import_ufunc", 0); - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":953 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":954 - * cdef inline int import_ufunc() except -1: - * try: - * _import_umath() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.umath failed to import") - */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 954, __pyx_L3_error) - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":953 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; + __Pyx_RefNannySetupContext("__getattr__", 1); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":955 - * try: - * _import_umath() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.umath failed to import") + /* "View.MemoryView":232 * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 955, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":956 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * def __getattr__(self, attr): + * return getattr(self.memview, attr) # <<<<<<<<<<<<<< * - * cdef extern from *: + * def __getitem__(self, item): */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 956, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 956, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":953 + /* "View.MemoryView":231 + * return self._shape[0] * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":952 - * raise ImportError("numpy.core.umath failed to import") + * def __getattr__(self, attr): # <<<<<<<<<<<<<< + * return getattr(self.memview, attr) * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() */ /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":966 +/* "View.MemoryView":234 + * return getattr(self.memview, attr) * + * def __getitem__(self, item): # <<<<<<<<<<<<<< + * return self.memview[item] * - * cdef inline bint is_timedelta64_object(object obj): # <<<<<<<<<<<<<< - * """ - * Cython equivalent of `isinstance(obj, np.timedelta64)` */ -static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_obj) { - int __pyx_r; +/* Python wrapper */ +static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ +static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("is_timedelta64_object", 0); + __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item)); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":978 - * bool - * """ - * return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type) # <<<<<<<<<<<<<< + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__getitem__", 1); + + /* "View.MemoryView":235 * + * def __getitem__(self, item): + * return self.memview[item] # <<<<<<<<<<<<<< * + * def __setitem__(self, item, value): */ - __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyTimedeltaArrType_Type)); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; goto __pyx_L0; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":966 + /* "View.MemoryView":234 + * return getattr(self.memview, attr) * + * def __getitem__(self, item): # <<<<<<<<<<<<<< + * return self.memview[item] * - * cdef inline bint is_timedelta64_object(object obj): # <<<<<<<<<<<<<< - * """ - * Cython equivalent of `isinstance(obj, np.timedelta64)` */ /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":981 +/* "View.MemoryView":237 + * return self.memview[item] * + * def __setitem__(self, item, value): # <<<<<<<<<<<<<< + * self.memview[item] = value * - * cdef inline bint is_datetime64_object(object obj): # <<<<<<<<<<<<<< - * """ - * Cython equivalent of `isinstance(obj, np.datetime64)` */ -static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_obj) { +/* Python wrapper */ +static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/ +static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; int __pyx_r; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("is_datetime64_object", 0); - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":993 - * bool - * """ - * return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type) # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyDatetimeArrType_Type)); - goto __pyx_L0; - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":981 - * - * - * cdef inline bint is_datetime64_object(object obj): # <<<<<<<<<<<<<< - * """ - * Cython equivalent of `isinstance(obj, np.datetime64)` - */ + __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_12__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value)); /* function exit code */ - __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":996 - * - * - * cdef inline npy_datetime get_datetime64_value(object obj) nogil: # <<<<<<<<<<<<<< - * """ - * returns the int64 value underlying scalar numpy datetime64 object - */ - -static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject *__pyx_v_obj) { - npy_datetime __pyx_r; +static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_12__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setitem__", 1); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":1003 - * also needed. That can be found using `get_datetime64_unit`. - * """ - * return (obj).obval # <<<<<<<<<<<<<< + /* "View.MemoryView":238 + * + * def __setitem__(self, item, value): + * self.memview[item] = value # <<<<<<<<<<<<<< * * */ - __pyx_r = ((PyDatetimeScalarObject *)__pyx_v_obj)->obval; - goto __pyx_L0; + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (unlikely((PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0))) __PYX_ERR(1, 238, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":996 + /* "View.MemoryView":237 + * return self.memview[item] * + * def __setitem__(self, item, value): # <<<<<<<<<<<<<< + * self.memview[item] = value * - * cdef inline npy_datetime get_datetime64_value(object obj) nogil: # <<<<<<<<<<<<<< - * """ - * returns the int64 value underlying scalar numpy datetime64 object */ /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; __pyx_L0:; + __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":1006 - * - * - * cdef inline npy_timedelta get_timedelta64_value(object obj) nogil: # <<<<<<<<<<<<<< - * """ - * returns the int64 value underlying scalar numpy timedelta64 object - */ - -static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject *__pyx_v_obj) { - npy_timedelta __pyx_r; - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":1010 - * returns the int64 value underlying scalar numpy timedelta64 object - * """ - * return (obj).obval # <<<<<<<<<<<<<< - * - * +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): */ - __pyx_r = ((PyTimedeltaScalarObject *)__pyx_v_obj)->obval; - goto __pyx_L0; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":1006 - * - * - * cdef inline npy_timedelta get_timedelta64_value(object obj) nogil: # <<<<<<<<<<<<<< - * """ - * returns the int64 value underlying scalar numpy timedelta64 object - */ +/* Python wrapper */ +static PyObject *__pyx_pw___pyx_array_1__reduce_cython__(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*/ +static PyObject *__pyx_pw___pyx_array_1__reduce_cython__(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 +) { + #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("__reduce_cython__ (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); + if (unlikely(__pyx_nargs > 0)) { + __Pyx_RaiseArgtupleInvalid("__reduce_cython__", 1, 0, 0, __pyx_nargs); return NULL;} + if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__reduce_cython__", 0))) return NULL; + __pyx_r = __pyx_pf___pyx_array___reduce_cython__(((struct __pyx_array_obj *)__pyx_v_self)); /* function exit code */ - __pyx_L0:; + __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":1013 - * - * - * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil: # <<<<<<<<<<<<<< - * """ - * returns the unit part of the dtype for a numpy datetime64 object. - */ - -static CYTHON_INLINE NPY_DATETIMEUNIT __pyx_f_5numpy_get_datetime64_unit(PyObject *__pyx_v_obj) { - NPY_DATETIMEUNIT __pyx_r; +static PyObject *__pyx_pf___pyx_array___reduce_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 1); - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":1017 - * returns the unit part of the dtype for a numpy datetime64 object. - * """ - * return (obj).obmeta.base # <<<<<<<<<<<<<< + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" */ - __pyx_r = ((NPY_DATETIMEUNIT)((PyDatetimeScalarObject *)__pyx_v_obj)->obmeta.base); - goto __pyx_L0; + __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); + __PYX_ERR(1, 2, __pyx_L1_error) - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":1013 - * - * - * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil: # <<<<<<<<<<<<<< - * """ - * returns the unit part of the dtype for a numpy datetime64 object. + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): */ /* function exit code */ - __pyx_L0:; + __pyx_L1_error:; + __Pyx_AddTraceback("View.MemoryView.array.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":123 - * cdef bint dtype_is_object - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< - * mode="c", bint allocate_buffer=True): - * +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" */ /* Python wrapper */ -static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_shape = 0; - Py_ssize_t __pyx_v_itemsize; - PyObject *__pyx_v_format = 0; - PyObject *__pyx_v_mode = 0; - int __pyx_v_allocate_buffer; +static PyObject *__pyx_pw___pyx_array_3__setstate_cython__(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*/ +static PyObject *__pyx_pw___pyx_array_3__setstate_cython__(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 +) { + CYTHON_UNUSED PyObject *__pyx_v___pyx_state = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - int __pyx_r; + PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); + __Pyx_RefNannySetupContext("__setstate_cython__ (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); { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0}; - PyObject* values[5] = {0,0,0,0,0}; - values[3] = ((PyObject *)__pyx_n_s_c); - if (unlikely(__pyx_kwds)) { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_state,0}; + if (__pyx_kwds) { Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); CYTHON_FALLTHROUGH; case 0: break; default: goto __pyx_L5_argtuple_error; } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); __PYX_ERR(2, 123, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); __PYX_ERR(2, 123, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mode); - if (value) { values[3] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 4: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_allocate_buffer); - if (value) { values[4] = value; kw_args--; } + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pyx_state)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 3, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(2, 123, __pyx_L3_error) + 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, "__setstate_cython__") < 0)) __PYX_ERR(1, 3, __pyx_L3_error) } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_shape = ((PyObject*)values[0]); - __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 123, __pyx_L3_error) - __pyx_v_format = values[2]; - __pyx_v_mode = values[3]; - if (values[4]) { - __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 124, __pyx_L3_error) - } else { - - /* "View.MemoryView":124 - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, - * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<< - * - * cdef int idx - */ - __pyx_v_allocate_buffer = ((int)1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); } + __pyx_v___pyx_state = values[0]; } - goto __pyx_L4_argument_unpacking_done; + goto __pyx_L6_skip; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 123, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("__setstate_cython__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 3, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; - __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + { + 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("View.MemoryView.array.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); - return -1; + return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) __PYX_ERR(2, 123, __pyx_L1_error) - if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) { - PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); __PYX_ERR(2, 123, __pyx_L1_error) + __pyx_r = __pyx_pf___pyx_array_2__setstate_cython__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v___pyx_state); + + /* 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_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":123 - * cdef bint dtype_is_object - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< - * mode="c", bint allocate_buffer=True): - * +static PyObject *__pyx_pf___pyx_array_2__setstate_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 1); + + /* "(tree fragment)":4 + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< + */ + __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); + __PYX_ERR(1, 4, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" */ /* function exit code */ - goto __pyx_L0; __pyx_L1_error:; - __pyx_r = -1; - __pyx_L0:; + __Pyx_AddTraceback("View.MemoryView.array.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) { - int __pyx_v_idx; +/* "View.MemoryView":248 + * + * @cname("__pyx_array_allocate_buffer") + * cdef int _allocate_buffer(array self) except -1: # <<<<<<<<<<<<<< + * + * + */ + +static int __pyx_array_allocate_buffer(struct __pyx_array_obj *__pyx_v_self) { Py_ssize_t __pyx_v_i; - Py_ssize_t __pyx_v_dim; PyObject **__pyx_v_p; - char __pyx_v_order; int __pyx_r; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - char *__pyx_t_7; - int __pyx_t_8; - Py_ssize_t __pyx_t_9; - PyObject *__pyx_t_10 = NULL; - Py_ssize_t __pyx_t_11; + int __pyx_t_1; + Py_ssize_t __pyx_t_2; + Py_ssize_t __pyx_t_3; + Py_ssize_t __pyx_t_4; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 0); - __Pyx_INCREF(__pyx_v_format); - /* "View.MemoryView":130 - * cdef PyObject **p - * - * self.ndim = len(shape) # <<<<<<<<<<<<<< - * self.itemsize = itemsize + /* "View.MemoryView":254 + * cdef PyObject **p * + * self.free_data = True # <<<<<<<<<<<<<< + * self.data = malloc(self.len) + * if not self.data: */ - if (unlikely(__pyx_v_shape == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(2, 130, __pyx_L1_error) - } - __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(2, 130, __pyx_L1_error) - __pyx_v_self->ndim = ((int)__pyx_t_1); + __pyx_v_self->free_data = 1; - /* "View.MemoryView":131 - * - * self.ndim = len(shape) - * self.itemsize = itemsize # <<<<<<<<<<<<<< + /* "View.MemoryView":255 * - * if not self.ndim: + * self.free_data = True + * self.data = malloc(self.len) # <<<<<<<<<<<<<< + * if not self.data: + * raise MemoryError, "unable to allocate array data." */ - __pyx_v_self->itemsize = __pyx_v_itemsize; + __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len)); - /* "View.MemoryView":133 - * self.itemsize = itemsize - * - * if not self.ndim: # <<<<<<<<<<<<<< - * raise ValueError("Empty shape tuple for cython.array") + /* "View.MemoryView":256 + * self.free_data = True + * self.data = malloc(self.len) + * if not self.data: # <<<<<<<<<<<<<< + * raise MemoryError, "unable to allocate array data." * */ - __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0); - if (unlikely(__pyx_t_2)) { + __pyx_t_1 = (!(__pyx_v_self->data != 0)); + if (unlikely(__pyx_t_1)) { - /* "View.MemoryView":134 - * - * if not self.ndim: - * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<< + /* "View.MemoryView":257 + * self.data = malloc(self.len) + * if not self.data: + * raise MemoryError, "unable to allocate array data." # <<<<<<<<<<<<<< * - * if itemsize <= 0: + * if self.dtype_is_object: */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 134, __pyx_L1_error) + __Pyx_Raise(__pyx_builtin_MemoryError, __pyx_kp_s_unable_to_allocate_array_data, 0, 0); + __PYX_ERR(1, 257, __pyx_L1_error) - /* "View.MemoryView":133 - * self.itemsize = itemsize - * - * if not self.ndim: # <<<<<<<<<<<<<< - * raise ValueError("Empty shape tuple for cython.array") + /* "View.MemoryView":256 + * self.free_data = True + * self.data = malloc(self.len) + * if not self.data: # <<<<<<<<<<<<<< + * raise MemoryError, "unable to allocate array data." * */ } - /* "View.MemoryView":136 - * raise ValueError("Empty shape tuple for cython.array") - * - * if itemsize <= 0: # <<<<<<<<<<<<<< - * raise ValueError("itemsize <= 0 for cython.array") + /* "View.MemoryView":259 + * raise MemoryError, "unable to allocate array data." * + * if self.dtype_is_object: # <<<<<<<<<<<<<< + * p = self.data + * for i in range(self.len // self.itemsize): */ - __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0); - if (unlikely(__pyx_t_2)) { + if (__pyx_v_self->dtype_is_object) { - /* "View.MemoryView":137 + /* "View.MemoryView":260 * - * if itemsize <= 0: - * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<< - * - * if not isinstance(format, bytes): + * if self.dtype_is_object: + * p = self.data # <<<<<<<<<<<<<< + * for i in range(self.len // self.itemsize): + * p[i] = Py_None */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 137, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 137, __pyx_L1_error) + __pyx_v_p = ((PyObject **)__pyx_v_self->data); - /* "View.MemoryView":136 - * raise ValueError("Empty shape tuple for cython.array") - * - * if itemsize <= 0: # <<<<<<<<<<<<<< - * raise ValueError("itemsize <= 0 for cython.array") - * + /* "View.MemoryView":261 + * if self.dtype_is_object: + * p = self.data + * for i in range(self.len // self.itemsize): # <<<<<<<<<<<<<< + * p[i] = Py_None + * Py_INCREF(Py_None) */ - } + if (unlikely(__pyx_v_self->itemsize == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); + __PYX_ERR(1, 261, __pyx_L1_error) + } + else if (sizeof(Py_ssize_t) == sizeof(long) && (!(((Py_ssize_t)-1) > 0)) && unlikely(__pyx_v_self->itemsize == (Py_ssize_t)-1) && unlikely(__Pyx_UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) { + PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); + __PYX_ERR(1, 261, __pyx_L1_error) + } + __pyx_t_2 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_self->itemsize); + __pyx_t_3 = __pyx_t_2; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_i = __pyx_t_4; - /* "View.MemoryView":139 - * raise ValueError("itemsize <= 0 for cython.array") - * - * if not isinstance(format, bytes): # <<<<<<<<<<<<<< - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string + /* "View.MemoryView":262 + * p = self.data + * for i in range(self.len // self.itemsize): + * p[i] = Py_None # <<<<<<<<<<<<<< + * Py_INCREF(Py_None) + * return 0 */ - __pyx_t_2 = PyBytes_Check(__pyx_v_format); - __pyx_t_4 = ((!(__pyx_t_2 != 0)) != 0); - if (__pyx_t_4) { + (__pyx_v_p[__pyx_v_i]) = Py_None; - /* "View.MemoryView":140 + /* "View.MemoryView":263 + * for i in range(self.len // self.itemsize): + * p[i] = Py_None + * Py_INCREF(Py_None) # <<<<<<<<<<<<<< + * return 0 * - * if not isinstance(format, bytes): - * format = format.encode('ASCII') # <<<<<<<<<<<<<< - * self._format = format # keep a reference to the byte string - * self.format = self._format */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_format, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 140, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_6)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_6); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - } + Py_INCREF(Py_None); } - __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_n_s_ASCII) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_n_s_ASCII); - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 140, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3); - __pyx_t_3 = 0; - /* "View.MemoryView":139 - * raise ValueError("itemsize <= 0 for cython.array") + /* "View.MemoryView":259 + * raise MemoryError, "unable to allocate array data." * - * if not isinstance(format, bytes): # <<<<<<<<<<<<<< - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string + * if self.dtype_is_object: # <<<<<<<<<<<<<< + * p = self.data + * for i in range(self.len // self.itemsize): */ } - /* "View.MemoryView":141 - * if not isinstance(format, bytes): - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<< - * self.format = self._format - * - */ - if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||((void)PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) __PYX_ERR(2, 141, __pyx_L1_error) - __pyx_t_3 = __pyx_v_format; - __Pyx_INCREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __Pyx_GOTREF(__pyx_v_self->_format); - __Pyx_DECREF(__pyx_v_self->_format); - __pyx_v_self->_format = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":142 - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string - * self.format = self._format # <<<<<<<<<<<<<< + /* "View.MemoryView":264 + * p[i] = Py_None + * Py_INCREF(Py_None) + * return 0 # <<<<<<<<<<<<<< * * */ - if (unlikely(__pyx_v_self->_format == Py_None)) { - PyErr_SetString(PyExc_TypeError, "expected bytes, NoneType found"); - __PYX_ERR(2, 142, __pyx_L1_error) - } - __pyx_t_7 = __Pyx_PyBytes_AsWritableString(__pyx_v_self->_format); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) __PYX_ERR(2, 142, __pyx_L1_error) - __pyx_v_self->format = __pyx_t_7; + __pyx_r = 0; + goto __pyx_L0; - /* "View.MemoryView":145 + /* "View.MemoryView":248 * + * @cname("__pyx_array_allocate_buffer") + * cdef int _allocate_buffer(array self) except -1: # <<<<<<<<<<<<<< * - * self._shape = PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<< - * self._strides = self._shape + self.ndim * */ - __pyx_v_self->_shape = ((Py_ssize_t *)PyObject_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2))); - /* "View.MemoryView":146 - * - * self._shape = PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2) - * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<< - * - * if not self._shape: - */ - __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim); + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("View.MemoryView._allocate_buffer", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + return __pyx_r; +} - /* "View.MemoryView":148 - * self._strides = self._shape + self.ndim - * - * if not self._shape: # <<<<<<<<<<<<<< - * raise MemoryError("unable to allocate shape and strides.") +/* "View.MemoryView":268 * + * @cname("__pyx_array_new") + * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *c_mode, char *buf): # <<<<<<<<<<<<<< + * cdef array result + * cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string. */ - __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0); - if (unlikely(__pyx_t_4)) { - /* "View.MemoryView":149 - * - * if not self._shape: - * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 149, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 149, __pyx_L1_error) +static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_c_mode, char *__pyx_v_buf) { + struct __pyx_array_obj *__pyx_v_result = 0; + PyObject *__pyx_v_mode = 0; + struct __pyx_array_obj *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("array_cwrapper", 1); - /* "View.MemoryView":148 - * self._strides = self._shape + self.ndim - * - * if not self._shape: # <<<<<<<<<<<<<< - * raise MemoryError("unable to allocate shape and strides.") + /* "View.MemoryView":270 + * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *c_mode, char *buf): + * cdef array result + * cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string. # <<<<<<<<<<<<<< * + * if buf is NULL: */ + __pyx_t_2 = ((__pyx_v_c_mode[0]) == 'f'); + if (__pyx_t_2) { + __Pyx_INCREF(__pyx_n_s_fortran); + __pyx_t_1 = __pyx_n_s_fortran; + } else { + __Pyx_INCREF(__pyx_n_s_c); + __pyx_t_1 = __pyx_n_s_c; } + __pyx_v_mode = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; - /* "View.MemoryView":152 + /* "View.MemoryView":272 + * cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string. * - * - * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<< - * if dim <= 0: - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) + * if buf is NULL: # <<<<<<<<<<<<<< + * result = array.__new__(array, shape, itemsize, format, mode) + * else: */ - __pyx_t_8 = 0; - __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0; - for (;;) { - if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_5); __pyx_t_1++; if (unlikely(0 < 0)) __PYX_ERR(2, 152, __pyx_L1_error) - #else - __pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 152, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_t_5); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 152, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_dim = __pyx_t_9; - __pyx_v_idx = __pyx_t_8; - __pyx_t_8 = (__pyx_t_8 + 1); + __pyx_t_2 = (__pyx_v_buf == NULL); + if (__pyx_t_2) { - /* "View.MemoryView":153 + /* "View.MemoryView":273 * - * for idx, dim in enumerate(shape): - * if dim <= 0: # <<<<<<<<<<<<<< - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) - * self._shape[idx] = dim + * if buf is NULL: + * result = array.__new__(array, shape, itemsize, format, mode) # <<<<<<<<<<<<<< + * else: + * result = array.__new__(array, shape, itemsize, format, mode, allocate_buffer=False) */ - __pyx_t_4 = ((__pyx_v_dim <= 0) != 0); - if (unlikely(__pyx_t_4)) { + __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 273, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 273, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 273, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(__pyx_v_shape); + __Pyx_GIVEREF(__pyx_v_shape); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_shape)) __PYX_ERR(1, 273, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1)) __PYX_ERR(1, 273, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3)) __PYX_ERR(1, 273, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_mode); + __Pyx_GIVEREF(__pyx_v_mode); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 3, __pyx_v_mode)) __PYX_ERR(1, 273, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_t_3 = ((PyObject *)__pyx_tp_new_array(((PyTypeObject *)__pyx_array_type), __pyx_t_4, NULL)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 273, __pyx_L1_error) + __Pyx_GOTREF((PyObject *)__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_3); + __pyx_t_3 = 0; - /* "View.MemoryView":154 - * for idx, dim in enumerate(shape): - * if dim <= 0: - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<< - * self._shape[idx] = dim + /* "View.MemoryView":272 + * cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string. * + * if buf is NULL: # <<<<<<<<<<<<<< + * result = array.__new__(array, shape, itemsize, format, mode) + * else: */ - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 154, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 154, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 154, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_6); - __pyx_t_5 = 0; - __pyx_t_6 = 0; - __pyx_t_6 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 154, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_6); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 154, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_Raise(__pyx_t_10, 0, 0, 0); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __PYX_ERR(2, 154, __pyx_L1_error) + goto __pyx_L3; + } - /* "View.MemoryView":153 + /* "View.MemoryView":275 + * result = array.__new__(array, shape, itemsize, format, mode) + * else: + * result = array.__new__(array, shape, itemsize, format, mode, allocate_buffer=False) # <<<<<<<<<<<<<< + * result.data = buf * - * for idx, dim in enumerate(shape): - * if dim <= 0: # <<<<<<<<<<<<<< - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) - * self._shape[idx] = dim */ - } + /*else*/ { + __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 275, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 275, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 275, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_shape); + __Pyx_GIVEREF(__pyx_v_shape); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_shape)) __PYX_ERR(1, 275, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3)) __PYX_ERR(1, 275, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_4)) __PYX_ERR(1, 275, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_mode); + __Pyx_GIVEREF(__pyx_v_mode); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_mode)) __PYX_ERR(1, 275, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 275, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_allocate_buffer, Py_False) < 0) __PYX_ERR(1, 275, __pyx_L1_error) + __pyx_t_3 = ((PyObject *)__pyx_tp_new_array(((PyTypeObject *)__pyx_array_type), __pyx_t_1, __pyx_t_4)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 275, __pyx_L1_error) + __Pyx_GOTREF((PyObject *)__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_3); + __pyx_t_3 = 0; - /* "View.MemoryView":155 - * if dim <= 0: - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) - * self._shape[idx] = dim # <<<<<<<<<<<<<< + /* "View.MemoryView":276 + * else: + * result = array.__new__(array, shape, itemsize, format, mode, allocate_buffer=False) + * result.data = buf # <<<<<<<<<<<<<< * - * cdef char order + * return result */ - (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim; + __pyx_v_result->data = __pyx_v_buf; + } + __pyx_L3:; - /* "View.MemoryView":152 + /* "View.MemoryView":278 + * result.data = buf + * + * return result # <<<<<<<<<<<<<< * * - * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<< - * if dim <= 0: - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) */ - } - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF((PyObject *)__pyx_r); + __Pyx_INCREF((PyObject *)__pyx_v_result); + __pyx_r = __pyx_v_result; + goto __pyx_L0; - /* "View.MemoryView":158 - * - * cdef char order - * if mode == 'fortran': # <<<<<<<<<<<<<< - * order = b'F' - * self.mode = u'fortran' - */ - __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 158, __pyx_L1_error) - if (__pyx_t_4) { - - /* "View.MemoryView":159 - * cdef char order - * if mode == 'fortran': - * order = b'F' # <<<<<<<<<<<<<< - * self.mode = u'fortran' - * elif mode == 'c': - */ - __pyx_v_order = 'F'; - - /* "View.MemoryView":160 - * if mode == 'fortran': - * order = b'F' - * self.mode = u'fortran' # <<<<<<<<<<<<<< - * elif mode == 'c': - * order = b'C' - */ - __Pyx_INCREF(__pyx_n_u_fortran); - __Pyx_GIVEREF(__pyx_n_u_fortran); - __Pyx_GOTREF(__pyx_v_self->mode); - __Pyx_DECREF(__pyx_v_self->mode); - __pyx_v_self->mode = __pyx_n_u_fortran; - - /* "View.MemoryView":158 - * - * cdef char order - * if mode == 'fortran': # <<<<<<<<<<<<<< - * order = b'F' - * self.mode = u'fortran' - */ - goto __pyx_L10; - } - - /* "View.MemoryView":161 - * order = b'F' - * self.mode = u'fortran' - * elif mode == 'c': # <<<<<<<<<<<<<< - * order = b'C' - * self.mode = u'c' - */ - __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 161, __pyx_L1_error) - if (likely(__pyx_t_4)) { - - /* "View.MemoryView":162 - * self.mode = u'fortran' - * elif mode == 'c': - * order = b'C' # <<<<<<<<<<<<<< - * self.mode = u'c' - * else: - */ - __pyx_v_order = 'C'; - - /* "View.MemoryView":163 - * elif mode == 'c': - * order = b'C' - * self.mode = u'c' # <<<<<<<<<<<<<< - * else: - * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) - */ - __Pyx_INCREF(__pyx_n_u_c); - __Pyx_GIVEREF(__pyx_n_u_c); - __Pyx_GOTREF(__pyx_v_self->mode); - __Pyx_DECREF(__pyx_v_self->mode); - __pyx_v_self->mode = __pyx_n_u_c; - - /* "View.MemoryView":161 - * order = b'F' - * self.mode = u'fortran' - * elif mode == 'c': # <<<<<<<<<<<<<< - * order = b'C' - * self.mode = u'c' - */ - goto __pyx_L10; - } - - /* "View.MemoryView":165 - * self.mode = u'c' - * else: - * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<< - * - * self.len = fill_contig_strides_array(self._shape, self._strides, - */ - /*else*/ { - __pyx_t_3 = __Pyx_PyString_FormatSafe(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 165, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 165, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_10, 0, 0, 0); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __PYX_ERR(2, 165, __pyx_L1_error) - } - __pyx_L10:; - - /* "View.MemoryView":167 - * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) - * - * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<< - * itemsize, self.ndim, order) - * - */ - __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order); - - /* "View.MemoryView":170 - * itemsize, self.ndim, order) - * - * self.free_data = allocate_buffer # <<<<<<<<<<<<<< - * self.dtype_is_object = format == b'O' - * if allocate_buffer: - */ - __pyx_v_self->free_data = __pyx_v_allocate_buffer; - - /* "View.MemoryView":171 - * - * self.free_data = allocate_buffer - * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<< - * if allocate_buffer: - * - */ - __pyx_t_10 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 171, __pyx_L1_error) - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 171, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __pyx_v_self->dtype_is_object = __pyx_t_4; - - /* "View.MemoryView":172 - * self.free_data = allocate_buffer - * self.dtype_is_object = format == b'O' - * if allocate_buffer: # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_4 = (__pyx_v_allocate_buffer != 0); - if (__pyx_t_4) { - - /* "View.MemoryView":175 - * - * - * self.data = malloc(self.len) # <<<<<<<<<<<<<< - * if not self.data: - * raise MemoryError("unable to allocate array data.") - */ - __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len)); - - /* "View.MemoryView":176 - * - * self.data = malloc(self.len) - * if not self.data: # <<<<<<<<<<<<<< - * raise MemoryError("unable to allocate array data.") - * - */ - __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0); - if (unlikely(__pyx_t_4)) { - - /* "View.MemoryView":177 - * self.data = malloc(self.len) - * if not self.data: - * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<< - * - * if self.dtype_is_object: - */ - __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 177, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_Raise(__pyx_t_10, 0, 0, 0); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __PYX_ERR(2, 177, __pyx_L1_error) - - /* "View.MemoryView":176 - * - * self.data = malloc(self.len) - * if not self.data: # <<<<<<<<<<<<<< - * raise MemoryError("unable to allocate array data.") + /* "View.MemoryView":268 * + * @cname("__pyx_array_new") + * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *c_mode, char *buf): # <<<<<<<<<<<<<< + * cdef array result + * cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string. */ - } - /* "View.MemoryView":179 - * raise MemoryError("unable to allocate array data.") - * - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * p = self.data - * for i in range(self.len / itemsize): - */ - __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0); - if (__pyx_t_4) { + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_result); + __Pyx_XDECREF(__pyx_v_mode); + __Pyx_XGIVEREF((PyObject *)__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":180 - * - * if self.dtype_is_object: - * p = self.data # <<<<<<<<<<<<<< - * for i in range(self.len / itemsize): - * p[i] = Py_None +/* "View.MemoryView":304 + * cdef class Enum(object): + * cdef object name + * def __init__(self, name): # <<<<<<<<<<<<<< + * self.name = name + * def __repr__(self): */ - __pyx_v_p = ((PyObject **)__pyx_v_self->data); - /* "View.MemoryView":181 - * if self.dtype_is_object: - * p = self.data - * for i in range(self.len / itemsize): # <<<<<<<<<<<<<< - * p[i] = Py_None - * Py_INCREF(Py_None) - */ - if (unlikely(__pyx_v_itemsize == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); - __PYX_ERR(2, 181, __pyx_L1_error) +/* Python wrapper */ +static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_name = 0; + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + 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_name,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; } - else if (sizeof(Py_ssize_t) == sizeof(long) && (!(((Py_ssize_t)-1) > 0)) && unlikely(__pyx_v_itemsize == (Py_ssize_t)-1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) { - PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); - __PYX_ERR(2, 181, __pyx_L1_error) + kw_args = __Pyx_NumKwargs_VARARGS(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_name)) != 0)) { + (void)__Pyx_Arg_NewRef_VARARGS(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 304, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; } - __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize); - __pyx_t_9 = __pyx_t_1; - for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_9; __pyx_t_11+=1) { - __pyx_v_i = __pyx_t_11; - - /* "View.MemoryView":182 - * p = self.data - * for i in range(self.len / itemsize): - * p[i] = Py_None # <<<<<<<<<<<<<< - * Py_INCREF(Py_None) - * - */ - (__pyx_v_p[__pyx_v_i]) = Py_None; - - /* "View.MemoryView":183 - * for i in range(self.len / itemsize): - * p[i] = Py_None - * Py_INCREF(Py_None) # <<<<<<<<<<<<<< - * - * @cname('getbuffer') - */ - Py_INCREF(Py_None); + 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(1, 304, __pyx_L3_error) } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); + } + __pyx_v_name = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 304, __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("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name); - /* "View.MemoryView":179 - * raise MemoryError("unable to allocate array data.") - * - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * p = self.data - * for i in range(self.len / itemsize): - */ + /* 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; +} - /* "View.MemoryView":172 - * self.free_data = allocate_buffer - * self.dtype_is_object = format == b'O' - * if allocate_buffer: # <<<<<<<<<<<<<< - * - * +static int __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__", 1); + + /* "View.MemoryView":305 + * cdef object name + * def __init__(self, name): + * self.name = name # <<<<<<<<<<<<<< + * def __repr__(self): + * return self.name */ - } + __Pyx_INCREF(__pyx_v_name); + __Pyx_GIVEREF(__pyx_v_name); + __Pyx_GOTREF(__pyx_v_self->name); + __Pyx_DECREF(__pyx_v_self->name); + __pyx_v_self->name = __pyx_v_name; - /* "View.MemoryView":123 - * cdef bint dtype_is_object - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< - * mode="c", bint allocate_buffer=True): - * + /* "View.MemoryView":304 + * cdef class Enum(object): + * cdef object name + * def __init__(self, name): # <<<<<<<<<<<<<< + * self.name = name + * def __repr__(self): */ /* function exit code */ __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_format); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":186 +/* "View.MemoryView":306 + * def __init__(self, name): + * self.name = name + * def __repr__(self): # <<<<<<<<<<<<<< + * return self.name * - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< - * cdef int bufmode = -1 - * if self.mode == u"c": */ /* Python wrapper */ -static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_r; +static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); + __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_v_bufmode; - int __pyx_r; +static PyObject *__pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) { + PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - char *__pyx_t_4; - Py_ssize_t __pyx_t_5; - int __pyx_t_6; - Py_ssize_t *__pyx_t_7; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - if (__pyx_v_info == NULL) { - PyErr_SetString(PyExc_BufferError, "PyObject_GetBuffer: view==NULL argument is obsolete"); - return -1; - } - __Pyx_RefNannySetupContext("__getbuffer__", 0); - __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(__pyx_v_info->obj); + __Pyx_RefNannySetupContext("__repr__", 1); - /* "View.MemoryView":187 - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 # <<<<<<<<<<<<<< - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS + /* "View.MemoryView":307 + * self.name = name + * def __repr__(self): + * return self.name # <<<<<<<<<<<<<< + * + * cdef generic = Enum("") */ - __pyx_v_bufmode = -1; + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->name); + __pyx_r = __pyx_v_self->name; + goto __pyx_L0; - /* "View.MemoryView":188 - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 - * if self.mode == u"c": # <<<<<<<<<<<<<< - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": + /* "View.MemoryView":306 + * def __init__(self, name): + * self.name = name + * def __repr__(self): # <<<<<<<<<<<<<< + * return self.name + * */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 188, __pyx_L1_error) - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - /* "View.MemoryView":189 - * cdef int bufmode = -1 - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<< - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - */ - __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS); + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":188 - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 - * if self.mode == u"c": # <<<<<<<<<<<<<< - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * cdef tuple state + * cdef object _dict */ - goto __pyx_L3; - } - /* "View.MemoryView":190 - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": # <<<<<<<<<<<<<< - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - */ - __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(2, 190, __pyx_L1_error) - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { +/* Python wrapper */ +static PyObject *__pyx_pw___pyx_MemviewEnum_1__reduce_cython__(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*/ +static PyObject *__pyx_pw___pyx_MemviewEnum_1__reduce_cython__(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 +) { + #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("__reduce_cython__ (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); + if (unlikely(__pyx_nargs > 0)) { + __Pyx_RaiseArgtupleInvalid("__reduce_cython__", 1, 0, 0, __pyx_nargs); return NULL;} + if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__reduce_cython__", 0))) return NULL; + __pyx_r = __pyx_pf___pyx_MemviewEnum___reduce_cython__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self)); - /* "View.MemoryView":191 - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<< - * if not (flags & bufmode): - * raise ValueError("Can only create a buffer that is contiguous in memory.") - */ - __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS); + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":190 - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": # <<<<<<<<<<<<<< - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - */ - } - __pyx_L3:; +static PyObject *__pyx_pf___pyx_MemviewEnum___reduce_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self) { + PyObject *__pyx_v_state = 0; + PyObject *__pyx_v__dict = 0; + int __pyx_v_use_setstate; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 1); - /* "View.MemoryView":192 - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): # <<<<<<<<<<<<<< - * raise ValueError("Can only create a buffer that is contiguous in memory.") - * info.buf = self.data + /* "(tree fragment)":5 + * cdef object _dict + * cdef bint use_setstate + * state = (self.name,) # <<<<<<<<<<<<<< + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: */ - __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0); - if (unlikely(__pyx_t_1)) { + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_self->name); + __Pyx_GIVEREF(__pyx_v_self->name); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->name)) __PYX_ERR(1, 5, __pyx_L1_error); + __pyx_v_state = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; - /* "View.MemoryView":193 - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<< - * info.buf = self.data - * info.len = self.len + /* "(tree fragment)":6 + * cdef bint use_setstate + * state = (self.name,) + * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< + * if _dict is not None: + * state += (_dict,) */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 193, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 193, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v__dict = __pyx_t_1; + __pyx_t_1 = 0; - /* "View.MemoryView":192 - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): # <<<<<<<<<<<<<< - * raise ValueError("Can only create a buffer that is contiguous in memory.") - * info.buf = self.data + /* "(tree fragment)":7 + * state = (self.name,) + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: # <<<<<<<<<<<<<< + * state += (_dict,) + * use_setstate = True */ - } + __pyx_t_2 = (__pyx_v__dict != Py_None); + if (__pyx_t_2) { - /* "View.MemoryView":194 - * if not (flags & bufmode): - * raise ValueError("Can only create a buffer that is contiguous in memory.") - * info.buf = self.data # <<<<<<<<<<<<<< - * info.len = self.len - * info.ndim = self.ndim + /* "(tree fragment)":8 + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: + * state += (_dict,) # <<<<<<<<<<<<<< + * use_setstate = True + * else: */ - __pyx_t_4 = __pyx_v_self->data; - __pyx_v_info->buf = __pyx_t_4; + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v__dict); + __Pyx_GIVEREF(__pyx_v__dict); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__dict)) __PYX_ERR(1, 8, __pyx_L1_error); + __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; - /* "View.MemoryView":195 - * raise ValueError("Can only create a buffer that is contiguous in memory.") - * info.buf = self.data - * info.len = self.len # <<<<<<<<<<<<<< - * info.ndim = self.ndim - * info.shape = self._shape + /* "(tree fragment)":9 + * if _dict is not None: + * state += (_dict,) + * use_setstate = True # <<<<<<<<<<<<<< + * else: + * use_setstate = self.name is not None */ - __pyx_t_5 = __pyx_v_self->len; - __pyx_v_info->len = __pyx_t_5; + __pyx_v_use_setstate = 1; - /* "View.MemoryView":196 - * info.buf = self.data - * info.len = self.len - * info.ndim = self.ndim # <<<<<<<<<<<<<< - * info.shape = self._shape - * info.strides = self._strides + /* "(tree fragment)":7 + * state = (self.name,) + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: # <<<<<<<<<<<<<< + * state += (_dict,) + * use_setstate = True */ - __pyx_t_6 = __pyx_v_self->ndim; - __pyx_v_info->ndim = __pyx_t_6; + goto __pyx_L3; + } - /* "View.MemoryView":197 - * info.len = self.len - * info.ndim = self.ndim - * info.shape = self._shape # <<<<<<<<<<<<<< - * info.strides = self._strides - * info.suboffsets = NULL + /* "(tree fragment)":11 + * use_setstate = True + * else: + * use_setstate = self.name is not None # <<<<<<<<<<<<<< + * if use_setstate: + * return __pyx_unpickle_Enum, (type(self), 0x82a3537, None), state */ - __pyx_t_7 = __pyx_v_self->_shape; - __pyx_v_info->shape = __pyx_t_7; + /*else*/ { + __pyx_t_2 = (__pyx_v_self->name != Py_None); + __pyx_v_use_setstate = __pyx_t_2; + } + __pyx_L3:; - /* "View.MemoryView":198 - * info.ndim = self.ndim - * info.shape = self._shape - * info.strides = self._strides # <<<<<<<<<<<<<< - * info.suboffsets = NULL - * info.itemsize = self.itemsize + /* "(tree fragment)":12 + * else: + * use_setstate = self.name is not None + * if use_setstate: # <<<<<<<<<<<<<< + * return __pyx_unpickle_Enum, (type(self), 0x82a3537, None), state + * else: */ - __pyx_t_7 = __pyx_v_self->_strides; - __pyx_v_info->strides = __pyx_t_7; + if (__pyx_v_use_setstate) { - /* "View.MemoryView":199 - * info.shape = self._shape - * info.strides = self._strides - * info.suboffsets = NULL # <<<<<<<<<<<<<< - * info.itemsize = self.itemsize - * info.readonly = 0 + /* "(tree fragment)":13 + * use_setstate = self.name is not None + * if use_setstate: + * return __pyx_unpickle_Enum, (type(self), 0x82a3537, None), state # <<<<<<<<<<<<<< + * else: + * return __pyx_unpickle_Enum, (type(self), 0x82a3537, state) */ - __pyx_v_info->suboffsets = NULL; + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_pyx_unpickle_Enum); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))))) __PYX_ERR(1, 13, __pyx_L1_error); + __Pyx_INCREF(__pyx_int_136983863); + __Pyx_GIVEREF(__pyx_int_136983863); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_136983863)) __PYX_ERR(1, 13, __pyx_L1_error); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, Py_None)) __PYX_ERR(1, 13, __pyx_L1_error); + __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3)) __PYX_ERR(1, 13, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_state); + __Pyx_GIVEREF(__pyx_v_state); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_state)) __PYX_ERR(1, 13, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_1 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; - /* "View.MemoryView":200 - * info.strides = self._strides - * info.suboffsets = NULL - * info.itemsize = self.itemsize # <<<<<<<<<<<<<< - * info.readonly = 0 - * + /* "(tree fragment)":12 + * else: + * use_setstate = self.name is not None + * if use_setstate: # <<<<<<<<<<<<<< + * return __pyx_unpickle_Enum, (type(self), 0x82a3537, None), state + * else: */ - __pyx_t_5 = __pyx_v_self->itemsize; - __pyx_v_info->itemsize = __pyx_t_5; + } - /* "View.MemoryView":201 - * info.suboffsets = NULL - * info.itemsize = self.itemsize - * info.readonly = 0 # <<<<<<<<<<<<<< - * - * if flags & PyBUF_FORMAT: + /* "(tree fragment)":15 + * return __pyx_unpickle_Enum, (type(self), 0x82a3537, None), state + * else: + * return __pyx_unpickle_Enum, (type(self), 0x82a3537, state) # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * __pyx_unpickle_Enum__set_state(self, __pyx_state) */ - __pyx_v_info->readonly = 0; + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyx_unpickle_Enum); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))))) __PYX_ERR(1, 15, __pyx_L1_error); + __Pyx_INCREF(__pyx_int_136983863); + __Pyx_GIVEREF(__pyx_int_136983863); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_136983863)) __PYX_ERR(1, 15, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_state); + __Pyx_GIVEREF(__pyx_v_state); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_state)) __PYX_ERR(1, 15, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 15, __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(1, 15, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error); + __pyx_t_4 = 0; + __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + } - /* "View.MemoryView":203 - * info.readonly = 0 - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * info.format = self.format - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":204 - * - * if flags & PyBUF_FORMAT: - * info.format = self.format # <<<<<<<<<<<<<< - * else: - * info.format = NULL - */ - __pyx_t_4 = __pyx_v_self->format; - __pyx_v_info->format = __pyx_t_4; - - /* "View.MemoryView":203 - * info.readonly = 0 - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * info.format = self.format - * else: - */ - goto __pyx_L5; - } - - /* "View.MemoryView":206 - * info.format = self.format - * else: - * info.format = NULL # <<<<<<<<<<<<<< - * - * info.obj = self - */ - /*else*/ { - __pyx_v_info->format = NULL; - } - __pyx_L5:; - - /* "View.MemoryView":208 - * info.format = NULL - * - * info.obj = self # <<<<<<<<<<<<<< - * - * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") - */ - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); - __pyx_v_info->obj = ((PyObject *)__pyx_v_self); - - /* "View.MemoryView":186 - * - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< - * cdef int bufmode = -1 - * if self.mode == u"c": + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * cdef tuple state + * cdef object _dict */ /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - if (__pyx_v_info->obj != NULL) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - goto __pyx_L2; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("View.MemoryView.Enum.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; - if (__pyx_v_info->obj == Py_None) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - __pyx_L2:; + __Pyx_XDECREF(__pyx_v_state); + __Pyx_XDECREF(__pyx_v__dict); + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":212 - * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") - * - * def __dealloc__(array self): # <<<<<<<<<<<<<< - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) +/* "(tree fragment)":16 + * else: + * return __pyx_unpickle_Enum, (type(self), 0x82a3537, state) + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * __pyx_unpickle_Enum__set_state(self, __pyx_state) */ /* Python wrapper */ -static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_array___dealloc__(PyObject *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) { +static PyObject *__pyx_pw___pyx_MemviewEnum_3__setstate_cython__(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*/ +static PyObject *__pyx_pw___pyx_MemviewEnum_3__setstate_cython__(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___pyx_state = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("__dealloc__", 0); - - /* "View.MemoryView":213 - * - * def __dealloc__(array self): - * if self.callback_free_data != NULL: # <<<<<<<<<<<<<< - * self.callback_free_data(self.data) - * elif self.free_data: - */ - __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":214 - * def __dealloc__(array self): - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) # <<<<<<<<<<<<<< - * elif self.free_data: - * if self.dtype_is_object: - */ - __pyx_v_self->callback_free_data(__pyx_v_self->data); - - /* "View.MemoryView":213 - * - * def __dealloc__(array self): - * if self.callback_free_data != NULL: # <<<<<<<<<<<<<< - * self.callback_free_data(self.data) - * elif self.free_data: - */ - goto __pyx_L3; + __Pyx_RefNannySetupContext("__setstate_cython__ (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_pyx_state,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + 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_pyx_state)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 16, __pyx_L3_error) + else goto __pyx_L5_argtuple_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, "__setstate_cython__") < 0)) __PYX_ERR(1, 16, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v___pyx_state = values[0]; } - - /* "View.MemoryView":215 - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - * elif self.free_data: # <<<<<<<<<<<<<< - * if self.dtype_is_object: - * refcount_objects_in_slice(self.data, self._shape, - */ - __pyx_t_1 = (__pyx_v_self->free_data != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":216 - * self.callback_free_data(self.data) - * elif self.free_data: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice(self.data, self._shape, - * self._strides, self.ndim, False) - */ - __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":217 - * elif self.free_data: - * if self.dtype_is_object: - * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<< - * self._strides, self.ndim, False) - * free(self.data) - */ - __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0); - - /* "View.MemoryView":216 - * self.callback_free_data(self.data) - * elif self.free_data: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice(self.data, self._shape, - * self._strides, self.ndim, False) - */ + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__setstate_cython__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 16, __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]); } - - /* "View.MemoryView":219 - * refcount_objects_in_slice(self.data, self._shape, - * self._strides, self.ndim, False) - * free(self.data) # <<<<<<<<<<<<<< - * PyObject_Free(self._shape) - * - */ - free(__pyx_v_self->data); - - /* "View.MemoryView":215 - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - * elif self.free_data: # <<<<<<<<<<<<<< - * if self.dtype_is_object: - * refcount_objects_in_slice(self.data, self._shape, - */ } - __pyx_L3:; - - /* "View.MemoryView":220 - * self._strides, self.ndim, False) - * free(self.data) - * PyObject_Free(self._shape) # <<<<<<<<<<<<<< - * - * @property - */ - PyObject_Free(__pyx_v_self->_shape); - - /* "View.MemoryView":212 - * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") - * - * def __dealloc__(array self): # <<<<<<<<<<<<<< - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - */ - - /* function exit code */ + __Pyx_AddTraceback("View.MemoryView.Enum.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); -} - -/* "View.MemoryView":223 - * - * @property - * def memview(self): # <<<<<<<<<<<<<< - * return self.get_memview() - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self)); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf___pyx_MemviewEnum_2__setstate_cython__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v___pyx_state); /* 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_15View_dot_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) { +static PyObject *__pyx_pf___pyx_MemviewEnum_2__setstate_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v___pyx_state) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_RefNannySetupContext("__setstate_cython__", 1); - /* "View.MemoryView":224 - * @property - * def memview(self): - * return self.get_memview() # <<<<<<<<<<<<<< - * - * @cname('get_memview') + /* "(tree fragment)":17 + * return __pyx_unpickle_Enum, (type(self), 0x82a3537, state) + * def __setstate_cython__(self, __pyx_state): + * __pyx_unpickle_Enum__set_state(self, __pyx_state) # <<<<<<<<<<<<<< */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = ((struct __pyx_vtabstruct_array *)__pyx_v_self->__pyx_vtab)->get_memview(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 224, __pyx_L1_error) + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None) || __Pyx_RaiseUnexpectedTypeError("tuple", __pyx_v___pyx_state))) __PYX_ERR(1, 17, __pyx_L1_error) + __pyx_t_1 = __pyx_unpickle_Enum__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "View.MemoryView":223 - * - * @property - * def memview(self): # <<<<<<<<<<<<<< - * return self.get_memview() - * + /* "(tree fragment)":16 + * else: + * return __pyx_unpickle_Enum, (type(self), 0x82a3537, state) + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * __pyx_unpickle_Enum__set_state(self, __pyx_state) */ /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("View.MemoryView.Enum.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); @@ -5594,4052 +7144,4006 @@ static PyObject *__pyx_pf_15View_dot_MemoryView_5array_7memview___get__(struct _ return __pyx_r; } -/* "View.MemoryView":227 +/* "View.MemoryView":349 + * cdef __Pyx_TypeInfo *typeinfo * - * @cname('get_memview') - * cdef get_memview(self): # <<<<<<<<<<<<<< - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE - * return memoryview(self, flags, self.dtype_is_object) + * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<< + * self.obj = obj + * self.flags = flags */ -static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *__pyx_v_self) { +/* Python wrapper */ +static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_obj = 0; int __pyx_v_flags; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; + int __pyx_v_dtype_is_object; + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_memview", 0); - - /* "View.MemoryView":228 - * @cname('get_memview') - * cdef get_memview(self): - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<< - * return memoryview(self, flags, self.dtype_is_object) - * - */ - __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE); - - /* "View.MemoryView":229 - * cdef get_memview(self): - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE - * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<< - * - * def __len__(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 229, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 229, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 229, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); - PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self)); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 229, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":227 - * - * @cname('get_memview') - * cdef get_memview(self): # <<<<<<<<<<<<<< - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE - * return memoryview(self, flags, self.dtype_is_object) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.array.get_memview", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":231 - * return memoryview(self, flags, self.dtype_is_object) - * - * def __len__(self): # <<<<<<<<<<<<<< - * return self._shape[0] - * - */ - -/* Python wrapper */ -static Py_ssize_t __pyx_array___len__(PyObject *__pyx_v_self); /*proto*/ -static Py_ssize_t __pyx_array___len__(PyObject *__pyx_v_self) { - Py_ssize_t __pyx_r; + int __pyx_r; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__len__(((struct __pyx_array_obj *)__pyx_v_self)); + __Pyx_RefNannySetupContext("__cinit__ (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_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + 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 (likely((values[0] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_obj)) != 0)) { + (void)__Pyx_Arg_NewRef_VARARGS(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 349, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_flags)) != 0)) { + (void)__Pyx_Arg_NewRef_VARARGS(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 349, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); __PYX_ERR(1, 349, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_dtype_is_object); + if (value) { values[2] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 349, __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, "__cinit__") < 0)) __PYX_ERR(1, 349, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_VARARGS(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_VARARGS(__pyx_args, 1); + values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_obj = values[0]; + __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 349, __pyx_L3_error) + if (values[2]) { + __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 349, __pyx_L3_error) + } else { + __pyx_v_dtype_is_object = ((int)0); + } + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, __pyx_nargs); __PYX_ERR(1, 349, __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("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object); /* 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 Py_ssize_t __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__len__(struct __pyx_array_obj *__pyx_v_self) { - Py_ssize_t __pyx_r; +static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) { + int __pyx_r; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__", 0); + int __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + Py_intptr_t __pyx_t_4; + size_t __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__cinit__", 1); - /* "View.MemoryView":232 + /* "View.MemoryView":350 * - * def __len__(self): - * return self._shape[0] # <<<<<<<<<<<<<< - * - * def __getattr__(self, attr): + * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): + * self.obj = obj # <<<<<<<<<<<<<< + * self.flags = flags + * if type(self) is memoryview or obj is not None: */ - __pyx_r = (__pyx_v_self->_shape[0]); - goto __pyx_L0; + __Pyx_INCREF(__pyx_v_obj); + __Pyx_GIVEREF(__pyx_v_obj); + __Pyx_GOTREF(__pyx_v_self->obj); + __Pyx_DECREF(__pyx_v_self->obj); + __pyx_v_self->obj = __pyx_v_obj; - /* "View.MemoryView":231 - * return memoryview(self, flags, self.dtype_is_object) - * - * def __len__(self): # <<<<<<<<<<<<<< - * return self._shape[0] - * + /* "View.MemoryView":351 + * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): + * self.obj = obj + * self.flags = flags # <<<<<<<<<<<<<< + * if type(self) is memoryview or obj is not None: + * __Pyx_GetBuffer(obj, &self.view, flags) */ + __pyx_v_self->flags = __pyx_v_flags; - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":234 - * return self._shape[0] - * - * def __getattr__(self, attr): # <<<<<<<<<<<<<< - * return getattr(self.memview, attr) - * + /* "View.MemoryView":352 + * self.obj = obj + * self.flags = flags + * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<< + * __Pyx_GetBuffer(obj, &self.view, flags) + * if self.view.obj == NULL: */ + __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)__pyx_memoryview_type)); + if (!__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = (__pyx_v_obj != Py_None); + __pyx_t_1 = __pyx_t_2; + __pyx_L4_bool_binop_done:; + if (__pyx_t_1) { -/* Python wrapper */ -static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/ -static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":353 + * self.flags = flags + * if type(self) is memoryview or obj is not None: + * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<< + * if self.view.obj == NULL: + * (<__pyx_buffer *> &self.view).obj = Py_None + */ + __pyx_t_3 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(1, 353, __pyx_L1_error) -static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__getattr__", 0); + /* "View.MemoryView":354 + * if type(self) is memoryview or obj is not None: + * __Pyx_GetBuffer(obj, &self.view, flags) + * if self.view.obj == NULL: # <<<<<<<<<<<<<< + * (<__pyx_buffer *> &self.view).obj = Py_None + * Py_INCREF(Py_None) + */ + __pyx_t_1 = (((PyObject *)__pyx_v_self->view.obj) == NULL); + if (__pyx_t_1) { - /* "View.MemoryView":235 - * - * def __getattr__(self, attr): - * return getattr(self.memview, attr) # <<<<<<<<<<<<<< + /* "View.MemoryView":355 + * __Pyx_GetBuffer(obj, &self.view, flags) + * if self.view.obj == NULL: + * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<< + * Py_INCREF(Py_None) * - * def __getitem__(self, item): */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 235, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 235, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; + ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None; - /* "View.MemoryView":234 - * return self._shape[0] - * - * def __getattr__(self, attr): # <<<<<<<<<<<<<< - * return getattr(self.memview, attr) + /* "View.MemoryView":356 + * if self.view.obj == NULL: + * (<__pyx_buffer *> &self.view).obj = Py_None + * Py_INCREF(Py_None) # <<<<<<<<<<<<<< * + * if not __PYX_CYTHON_ATOMICS_ENABLED(): */ + Py_INCREF(Py_None); - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":237 - * return getattr(self.memview, attr) - * - * def __getitem__(self, item): # <<<<<<<<<<<<<< - * return self.memview[item] - * + /* "View.MemoryView":354 + * if type(self) is memoryview or obj is not None: + * __Pyx_GetBuffer(obj, &self.view, flags) + * if self.view.obj == NULL: # <<<<<<<<<<<<<< + * (<__pyx_buffer *> &self.view).obj = Py_None + * Py_INCREF(Py_None) */ + } -/* Python wrapper */ -static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ -static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item)); + /* "View.MemoryView":352 + * self.obj = obj + * self.flags = flags + * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<< + * __Pyx_GetBuffer(obj, &self.view, flags) + * if self.view.obj == NULL: + */ + } - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":358 + * Py_INCREF(Py_None) + * + * if not __PYX_CYTHON_ATOMICS_ENABLED(): # <<<<<<<<<<<<<< + * global __pyx_memoryview_thread_locks_used + * if __pyx_memoryview_thread_locks_used < 8: + */ + __pyx_t_1 = (!__PYX_CYTHON_ATOMICS_ENABLED()); + if (__pyx_t_1) { -static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__getitem__", 0); + /* "View.MemoryView":360 + * if not __PYX_CYTHON_ATOMICS_ENABLED(): + * global __pyx_memoryview_thread_locks_used + * if __pyx_memoryview_thread_locks_used < 8: # <<<<<<<<<<<<<< + * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] + * __pyx_memoryview_thread_locks_used += 1 + */ + __pyx_t_1 = (__pyx_memoryview_thread_locks_used < 8); + if (__pyx_t_1) { - /* "View.MemoryView":238 - * - * def __getitem__(self, item): - * return self.memview[item] # <<<<<<<<<<<<<< + /* "View.MemoryView":361 + * global __pyx_memoryview_thread_locks_used + * if __pyx_memoryview_thread_locks_used < 8: + * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] # <<<<<<<<<<<<<< + * __pyx_memoryview_thread_locks_used += 1 + * if self.lock is NULL: + */ + __pyx_v_self->lock = (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]); + + /* "View.MemoryView":362 + * if __pyx_memoryview_thread_locks_used < 8: + * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] + * __pyx_memoryview_thread_locks_used += 1 # <<<<<<<<<<<<<< + * if self.lock is NULL: + * self.lock = PyThread_allocate_lock() + */ + __pyx_memoryview_thread_locks_used = (__pyx_memoryview_thread_locks_used + 1); + + /* "View.MemoryView":360 + * if not __PYX_CYTHON_ATOMICS_ENABLED(): + * global __pyx_memoryview_thread_locks_used + * if __pyx_memoryview_thread_locks_used < 8: # <<<<<<<<<<<<<< + * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] + * __pyx_memoryview_thread_locks_used += 1 + */ + } + + /* "View.MemoryView":363 + * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] + * __pyx_memoryview_thread_locks_used += 1 + * if self.lock is NULL: # <<<<<<<<<<<<<< + * self.lock = PyThread_allocate_lock() + * if self.lock is NULL: + */ + __pyx_t_1 = (__pyx_v_self->lock == NULL); + if (__pyx_t_1) { + + /* "View.MemoryView":364 + * __pyx_memoryview_thread_locks_used += 1 + * if self.lock is NULL: + * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<< + * if self.lock is NULL: + * raise MemoryError + */ + __pyx_v_self->lock = PyThread_allocate_lock(); + + /* "View.MemoryView":365 + * if self.lock is NULL: + * self.lock = PyThread_allocate_lock() + * if self.lock is NULL: # <<<<<<<<<<<<<< + * raise MemoryError * - * def __setitem__(self, item, value): */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 238, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 238, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; + __pyx_t_1 = (__pyx_v_self->lock == NULL); + if (unlikely(__pyx_t_1)) { - /* "View.MemoryView":237 - * return getattr(self.memview, attr) + /* "View.MemoryView":366 + * self.lock = PyThread_allocate_lock() + * if self.lock is NULL: + * raise MemoryError # <<<<<<<<<<<<<< * - * def __getitem__(self, item): # <<<<<<<<<<<<<< - * return self.memview[item] + * if flags & PyBUF_FORMAT: + */ + PyErr_NoMemory(); __PYX_ERR(1, 366, __pyx_L1_error) + + /* "View.MemoryView":365 + * if self.lock is NULL: + * self.lock = PyThread_allocate_lock() + * if self.lock is NULL: # <<<<<<<<<<<<<< + * raise MemoryError * */ + } - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":363 + * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] + * __pyx_memoryview_thread_locks_used += 1 + * if self.lock is NULL: # <<<<<<<<<<<<<< + * self.lock = PyThread_allocate_lock() + * if self.lock is NULL: + */ + } -/* "View.MemoryView":240 - * return self.memview[item] - * - * def __setitem__(self, item, value): # <<<<<<<<<<<<<< - * self.memview[item] = value + /* "View.MemoryView":358 + * Py_INCREF(Py_None) * + * if not __PYX_CYTHON_ATOMICS_ENABLED(): # <<<<<<<<<<<<<< + * global __pyx_memoryview_thread_locks_used + * if __pyx_memoryview_thread_locks_used < 8: */ + } -/* Python wrapper */ -static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/ -static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_12__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value)); + /* "View.MemoryView":368 + * raise MemoryError + * + * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< + * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') + * else: + */ + __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); + if (__pyx_t_1) { - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":369 + * + * if flags & PyBUF_FORMAT: + * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') # <<<<<<<<<<<<<< + * else: + * self.dtype_is_object = dtype_is_object + */ + __pyx_t_2 = ((__pyx_v_self->view.format[0]) == 'O'); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L12_bool_binop_done; + } + __pyx_t_2 = ((__pyx_v_self->view.format[1]) == '\x00'); + __pyx_t_1 = __pyx_t_2; + __pyx_L12_bool_binop_done:; + __pyx_v_self->dtype_is_object = __pyx_t_1; -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_12__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setitem__", 0); + /* "View.MemoryView":368 + * raise MemoryError + * + * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< + * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') + * else: + */ + goto __pyx_L11; + } - /* "View.MemoryView":241 + /* "View.MemoryView":371 + * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') + * else: + * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<< * - * def __setitem__(self, item, value): - * self.memview[item] = value # <<<<<<<<<<<<<< + * assert (&self.acquisition_count) % sizeof(__pyx_atomic_int_type) == 0 + */ + /*else*/ { + __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object; + } + __pyx_L11:; + + /* "View.MemoryView":373 + * self.dtype_is_object = dtype_is_object * + * assert (&self.acquisition_count) % sizeof(__pyx_atomic_int_type) == 0 # <<<<<<<<<<<<<< + * self.typeinfo = NULL * */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 241, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) __PYX_ERR(2, 241, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + #ifndef CYTHON_WITHOUT_ASSERTIONS + if (unlikely(__pyx_assertions_enabled())) { + __pyx_t_4 = ((Py_intptr_t)((void *)(&__pyx_v_self->acquisition_count))); + __pyx_t_5 = (sizeof(__pyx_atomic_int_type)); + if (unlikely(__pyx_t_5 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); + __PYX_ERR(1, 373, __pyx_L1_error) + } + __pyx_t_1 = ((__pyx_t_4 % __pyx_t_5) == 0); + if (unlikely(!__pyx_t_1)) { + __Pyx_Raise(__pyx_builtin_AssertionError, 0, 0, 0); + __PYX_ERR(1, 373, __pyx_L1_error) + } + } + #else + if ((1)); else __PYX_ERR(1, 373, __pyx_L1_error) + #endif - /* "View.MemoryView":240 - * return self.memview[item] + /* "View.MemoryView":374 * - * def __setitem__(self, item, value): # <<<<<<<<<<<<<< - * self.memview[item] = value + * assert (&self.acquisition_count) % sizeof(__pyx_atomic_int_type) == 0 + * self.typeinfo = NULL # <<<<<<<<<<<<<< + * + * def __dealloc__(memoryview self): + */ + __pyx_v_self->typeinfo = NULL; + + /* "View.MemoryView":349 + * cdef __Pyx_TypeInfo *typeinfo * + * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<< + * self.obj = obj + * self.flags = flags */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): +/* "View.MemoryView":376 + * self.typeinfo = NULL + * + * def __dealloc__(memoryview self): # <<<<<<<<<<<<<< + * if self.obj is not None: + * __Pyx_ReleaseBuffer(&self.view) */ /* Python wrapper */ -static PyObject *__pyx_pw___pyx_array_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw___pyx_array_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; +static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/ +static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_array___reduce_cython__(((struct __pyx_array_obj *)__pyx_v_self)); + __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); - return __pyx_r; } -static PyObject *__pyx_pf___pyx_array___reduce_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.array.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} +static void __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) { + int __pyx_v_i; + int __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + int __pyx_t_4; + PyThread_type_lock __pyx_t_5; + PyThread_type_lock __pyx_t_6; -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + /* "View.MemoryView":377 + * + * def __dealloc__(memoryview self): + * if self.obj is not None: # <<<<<<<<<<<<<< + * __Pyx_ReleaseBuffer(&self.view) + * elif (<__pyx_buffer *> &self.view).obj == Py_None: */ + __pyx_t_1 = (__pyx_v_self->obj != Py_None); + if (__pyx_t_1) { -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_array_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw___pyx_array_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_array_2__setstate_cython__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_array_2__setstate_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + /* "View.MemoryView":378 + * def __dealloc__(memoryview self): + * if self.obj is not None: + * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<< + * elif (<__pyx_buffer *> &self.view).obj == Py_None: + * */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 4, __pyx_L1_error) + __Pyx_ReleaseBuffer((&__pyx_v_self->view)); - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + /* "View.MemoryView":377 + * + * def __dealloc__(memoryview self): + * if self.obj is not None: # <<<<<<<<<<<<<< + * __Pyx_ReleaseBuffer(&self.view) + * elif (<__pyx_buffer *> &self.view).obj == Py_None: */ + goto __pyx_L3; + } - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.array.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":245 + /* "View.MemoryView":379 + * if self.obj is not None: + * __Pyx_ReleaseBuffer(&self.view) + * elif (<__pyx_buffer *> &self.view).obj == Py_None: # <<<<<<<<<<<<<< * - * @cname("__pyx_array_new") - * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<< - * char *mode, char *buf): - * cdef array result + * (<__pyx_buffer *> &self.view).obj = NULL */ + __pyx_t_1 = (((Py_buffer *)(&__pyx_v_self->view))->obj == Py_None); + if (__pyx_t_1) { -static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) { - struct __pyx_array_obj *__pyx_v_result = 0; - struct __pyx_array_obj *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("array_cwrapper", 0); - - /* "View.MemoryView":249 - * cdef array result + /* "View.MemoryView":381 + * elif (<__pyx_buffer *> &self.view).obj == Py_None: + * + * (<__pyx_buffer *> &self.view).obj = NULL # <<<<<<<<<<<<<< + * Py_DECREF(Py_None) * - * if buf == NULL: # <<<<<<<<<<<<<< - * result = array(shape, itemsize, format, mode.decode('ASCII')) - * else: */ - __pyx_t_1 = ((__pyx_v_buf == NULL) != 0); - if (__pyx_t_1) { + ((Py_buffer *)(&__pyx_v_self->view))->obj = NULL; - /* "View.MemoryView":250 + /* "View.MemoryView":382 * - * if buf == NULL: - * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<< - * else: - * result = array(shape, itemsize, format, mode.decode('ASCII'), + * (<__pyx_buffer *> &self.view).obj = NULL + * Py_DECREF(Py_None) # <<<<<<<<<<<<<< + * + * cdef int i */ - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 250, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 250, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 250, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 250, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_INCREF(__pyx_v_shape); - __Pyx_GIVEREF(__pyx_v_shape); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4); - __pyx_t_2 = 0; - __pyx_t_3 = 0; - __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_array_type), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 250, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4); - __pyx_t_4 = 0; + Py_DECREF(Py_None); - /* "View.MemoryView":249 - * cdef array result + /* "View.MemoryView":379 + * if self.obj is not None: + * __Pyx_ReleaseBuffer(&self.view) + * elif (<__pyx_buffer *> &self.view).obj == Py_None: # <<<<<<<<<<<<<< * - * if buf == NULL: # <<<<<<<<<<<<<< - * result = array(shape, itemsize, format, mode.decode('ASCII')) - * else: + * (<__pyx_buffer *> &self.view).obj = NULL */ - goto __pyx_L3; } + __pyx_L3:; - /* "View.MemoryView":252 - * result = array(shape, itemsize, format, mode.decode('ASCII')) - * else: - * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<< - * allocate_buffer=False) - * result.data = buf + /* "View.MemoryView":386 + * cdef int i + * global __pyx_memoryview_thread_locks_used + * if self.lock != NULL: # <<<<<<<<<<<<<< + * for i in range(__pyx_memoryview_thread_locks_used): + * if __pyx_memoryview_thread_locks[i] is self.lock: */ - /*else*/ { - __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_v_shape); - __Pyx_GIVEREF(__pyx_v_shape); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3); - __pyx_t_4 = 0; - __pyx_t_5 = 0; - __pyx_t_3 = 0; + __pyx_t_1 = (__pyx_v_self->lock != NULL); + if (__pyx_t_1) { - /* "View.MemoryView":253 - * else: - * result = array(shape, itemsize, format, mode.decode('ASCII'), - * allocate_buffer=False) # <<<<<<<<<<<<<< - * result.data = buf - * + /* "View.MemoryView":387 + * global __pyx_memoryview_thread_locks_used + * if self.lock != NULL: + * for i in range(__pyx_memoryview_thread_locks_used): # <<<<<<<<<<<<<< + * if __pyx_memoryview_thread_locks[i] is self.lock: + * __pyx_memoryview_thread_locks_used -= 1 */ - __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 253, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) __PYX_ERR(2, 253, __pyx_L1_error) + __pyx_t_2 = __pyx_memoryview_thread_locks_used; + __pyx_t_3 = __pyx_t_2; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_i = __pyx_t_4; - /* "View.MemoryView":252 - * result = array(shape, itemsize, format, mode.decode('ASCII')) - * else: - * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<< - * allocate_buffer=False) - * result.data = buf + /* "View.MemoryView":388 + * if self.lock != NULL: + * for i in range(__pyx_memoryview_thread_locks_used): + * if __pyx_memoryview_thread_locks[i] is self.lock: # <<<<<<<<<<<<<< + * __pyx_memoryview_thread_locks_used -= 1 + * if i != __pyx_memoryview_thread_locks_used: */ - __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)__pyx_array_type), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5); - __pyx_t_5 = 0; + __pyx_t_1 = ((__pyx_memoryview_thread_locks[__pyx_v_i]) == __pyx_v_self->lock); + if (__pyx_t_1) { - /* "View.MemoryView":254 - * result = array(shape, itemsize, format, mode.decode('ASCII'), - * allocate_buffer=False) - * result.data = buf # <<<<<<<<<<<<<< - * - * return result + /* "View.MemoryView":389 + * for i in range(__pyx_memoryview_thread_locks_used): + * if __pyx_memoryview_thread_locks[i] is self.lock: + * __pyx_memoryview_thread_locks_used -= 1 # <<<<<<<<<<<<<< + * if i != __pyx_memoryview_thread_locks_used: + * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( */ - __pyx_v_result->data = __pyx_v_buf; - } - __pyx_L3:; + __pyx_memoryview_thread_locks_used = (__pyx_memoryview_thread_locks_used - 1); - /* "View.MemoryView":256 - * result.data = buf - * - * return result # <<<<<<<<<<<<<< - * - * + /* "View.MemoryView":390 + * if __pyx_memoryview_thread_locks[i] is self.lock: + * __pyx_memoryview_thread_locks_used -= 1 + * if i != __pyx_memoryview_thread_locks_used: # <<<<<<<<<<<<<< + * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( + * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) */ - __Pyx_XDECREF(((PyObject *)__pyx_r)); - __Pyx_INCREF(((PyObject *)__pyx_v_result)); - __pyx_r = __pyx_v_result; - goto __pyx_L0; + __pyx_t_1 = (__pyx_v_i != __pyx_memoryview_thread_locks_used); + if (__pyx_t_1) { - /* "View.MemoryView":245 - * - * @cname("__pyx_array_new") - * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<< - * char *mode, char *buf): - * cdef array result + /* "View.MemoryView":392 + * if i != __pyx_memoryview_thread_locks_used: + * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( + * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) # <<<<<<<<<<<<<< + * break + * else: */ + __pyx_t_5 = (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]); + __pyx_t_6 = (__pyx_memoryview_thread_locks[__pyx_v_i]); - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XGIVEREF((PyObject *)__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":391 + * __pyx_memoryview_thread_locks_used -= 1 + * if i != __pyx_memoryview_thread_locks_used: + * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( # <<<<<<<<<<<<<< + * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) + * break + */ + (__pyx_memoryview_thread_locks[__pyx_v_i]) = __pyx_t_5; + (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]) = __pyx_t_6; -/* "View.MemoryView":282 - * cdef class Enum(object): - * cdef object name - * def __init__(self, name): # <<<<<<<<<<<<<< - * self.name = name - * def __repr__(self): + /* "View.MemoryView":390 + * if __pyx_memoryview_thread_locks[i] is self.lock: + * __pyx_memoryview_thread_locks_used -= 1 + * if i != __pyx_memoryview_thread_locks_used: # <<<<<<<<<<<<<< + * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( + * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) */ + } -/* Python wrapper */ -static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_name = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0}; - PyObject* values[1] = {0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(2, 282, __pyx_L3_error) + /* "View.MemoryView":393 + * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( + * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) + * break # <<<<<<<<<<<<<< + * else: + * PyThread_free_lock(self.lock) + */ + goto __pyx_L6_break; + + /* "View.MemoryView":388 + * if self.lock != NULL: + * for i in range(__pyx_memoryview_thread_locks_used): + * if __pyx_memoryview_thread_locks[i] is self.lock: # <<<<<<<<<<<<<< + * __pyx_memoryview_thread_locks_used -= 1 + * if i != __pyx_memoryview_thread_locks_used: + */ } - } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); } - __pyx_v_name = values[0]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 282, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /*else*/ { -static int __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__", 0); + /* "View.MemoryView":395 + * break + * else: + * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<< + * + * cdef char *get_item_pointer(memoryview self, object index) except NULL: + */ + PyThread_free_lock(__pyx_v_self->lock); + } + __pyx_L6_break:; - /* "View.MemoryView":283 - * cdef object name - * def __init__(self, name): - * self.name = name # <<<<<<<<<<<<<< - * def __repr__(self): - * return self.name + /* "View.MemoryView":386 + * cdef int i + * global __pyx_memoryview_thread_locks_used + * if self.lock != NULL: # <<<<<<<<<<<<<< + * for i in range(__pyx_memoryview_thread_locks_used): + * if __pyx_memoryview_thread_locks[i] is self.lock: */ - __Pyx_INCREF(__pyx_v_name); - __Pyx_GIVEREF(__pyx_v_name); - __Pyx_GOTREF(__pyx_v_self->name); - __Pyx_DECREF(__pyx_v_self->name); - __pyx_v_self->name = __pyx_v_name; + } - /* "View.MemoryView":282 - * cdef class Enum(object): - * cdef object name - * def __init__(self, name): # <<<<<<<<<<<<<< - * self.name = name - * def __repr__(self): + /* "View.MemoryView":376 + * self.typeinfo = NULL + * + * def __dealloc__(memoryview self): # <<<<<<<<<<<<<< + * if self.obj is not None: + * __Pyx_ReleaseBuffer(&self.view) */ /* function exit code */ - __pyx_r = 0; - __Pyx_RefNannyFinishContext(); - return __pyx_r; } -/* "View.MemoryView":284 - * def __init__(self, name): - * self.name = name - * def __repr__(self): # <<<<<<<<<<<<<< - * return self.name +/* "View.MemoryView":397 + * PyThread_free_lock(self.lock) * + * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<< + * cdef Py_ssize_t dim + * cdef char *itemp = self.view.buf */ -/* Python wrapper */ -static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; +static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) { + Py_ssize_t __pyx_v_dim; + char *__pyx_v_itemp; + PyObject *__pyx_v_idx = NULL; + char *__pyx_r; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); - __pyx_r = __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self)); + Py_ssize_t __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + Py_ssize_t __pyx_t_6; + char *__pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("get_item_pointer", 1); - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":399 + * cdef char *get_item_pointer(memoryview self, object index) except NULL: + * cdef Py_ssize_t dim + * cdef char *itemp = self.view.buf # <<<<<<<<<<<<<< + * + * for dim, idx in enumerate(index): + */ + __pyx_v_itemp = ((char *)__pyx_v_self->view.buf); -static PyObject *__pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__", 0); + /* "View.MemoryView":401 + * cdef char *itemp = self.view.buf + * + * for dim, idx in enumerate(index): # <<<<<<<<<<<<<< + * itemp = pybuffer_index(&self.view, itemp, idx, dim) + * + */ + __pyx_t_1 = 0; + if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) { + __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + __pyx_t_4 = NULL; + } else { + __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 401, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 401, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_4)) { + if (likely(PyList_CheckExact(__pyx_t_2))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 401, __pyx_L1_error) + #endif + if (__pyx_t_3 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(1, 401, __pyx_L1_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 401, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 401, __pyx_L1_error) + #endif + if (__pyx_t_3 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(1, 401, __pyx_L1_error) + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 401, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + } + } else { + __pyx_t_5 = __pyx_t_4(__pyx_t_2); + if (unlikely(!__pyx_t_5)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(1, 401, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_5); + } + __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5); + __pyx_t_5 = 0; + __pyx_v_dim = __pyx_t_1; + __pyx_t_1 = (__pyx_t_1 + 1); - /* "View.MemoryView":285 - * self.name = name - * def __repr__(self): - * return self.name # <<<<<<<<<<<<<< + /* "View.MemoryView":402 * - * cdef generic = Enum("") + * for dim, idx in enumerate(index): + * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<< + * + * return itemp */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->name); - __pyx_r = __pyx_v_self->name; + __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 402, __pyx_L1_error) + __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == ((char *)NULL))) __PYX_ERR(1, 402, __pyx_L1_error) + __pyx_v_itemp = __pyx_t_7; + + /* "View.MemoryView":401 + * cdef char *itemp = self.view.buf + * + * for dim, idx in enumerate(index): # <<<<<<<<<<<<<< + * itemp = pybuffer_index(&self.view, itemp, idx, dim) + * + */ + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "View.MemoryView":404 + * itemp = pybuffer_index(&self.view, itemp, idx, dim) + * + * return itemp # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_itemp; goto __pyx_L0; - /* "View.MemoryView":284 - * def __init__(self, name): - * self.name = name - * def __repr__(self): # <<<<<<<<<<<<<< - * return self.name + /* "View.MemoryView":397 + * PyThread_free_lock(self.lock) * + * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<< + * cdef Py_ssize_t dim + * cdef char *itemp = self.view.buf */ /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); + __Pyx_XDECREF(__pyx_v_idx); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict +/* "View.MemoryView":407 + * + * + * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<< + * if index is Ellipsis: + * return self */ /* Python wrapper */ -static PyObject *__pyx_pw___pyx_MemviewEnum_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw___pyx_MemviewEnum_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { +static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/ +static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_MemviewEnum___reduce_cython__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self)); + __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static PyObject *__pyx_pf___pyx_MemviewEnum___reduce_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self) { - PyObject *__pyx_v_state = 0; - PyObject *__pyx_v__dict = 0; - int __pyx_v_use_setstate; +static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) { + PyObject *__pyx_v_have_slices = NULL; + PyObject *__pyx_v_indices = NULL; + char *__pyx_v_itemp; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_t_3; + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; + char *__pyx_t_5; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); + __Pyx_RefNannySetupContext("__getitem__", 1); - /* "(tree fragment)":5 - * cdef object _dict - * cdef bint use_setstate - * state = (self.name,) # <<<<<<<<<<<<<< - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - */ - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_self->name); - __Pyx_GIVEREF(__pyx_v_self->name); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->name); - __pyx_v_state = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "(tree fragment)":6 - * cdef bint use_setstate - * state = (self.name,) - * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< - * if _dict is not None: - * state += (_dict,) - */ - __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v__dict = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":7 - * state = (self.name,) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - __pyx_t_2 = (__pyx_v__dict != Py_None); - __pyx_t_3 = (__pyx_t_2 != 0); - if (__pyx_t_3) { - - /* "(tree fragment)":8 - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - * state += (_dict,) # <<<<<<<<<<<<<< - * use_setstate = True - * else: + /* "View.MemoryView":408 + * + * def __getitem__(memoryview self, object index): + * if index is Ellipsis: # <<<<<<<<<<<<<< + * return self + * */ - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v__dict); - __Pyx_GIVEREF(__pyx_v__dict); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__dict); - __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_4)); - __pyx_t_4 = 0; + __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis); + if (__pyx_t_1) { - /* "(tree fragment)":9 - * if _dict is not None: - * state += (_dict,) - * use_setstate = True # <<<<<<<<<<<<<< - * else: - * use_setstate = self.name is not None + /* "View.MemoryView":409 + * def __getitem__(memoryview self, object index): + * if index is Ellipsis: + * return self # <<<<<<<<<<<<<< + * + * have_slices, indices = _unellipsify(index, self.view.ndim) */ - __pyx_v_use_setstate = 1; + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF((PyObject *)__pyx_v_self); + __pyx_r = ((PyObject *)__pyx_v_self); + goto __pyx_L0; - /* "(tree fragment)":7 - * state = (self.name,) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True + /* "View.MemoryView":408 + * + * def __getitem__(memoryview self, object index): + * if index is Ellipsis: # <<<<<<<<<<<<<< + * return self + * */ - goto __pyx_L3; } - /* "(tree fragment)":11 - * use_setstate = True - * else: - * use_setstate = self.name is not None # <<<<<<<<<<<<<< - * if use_setstate: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, None), state + /* "View.MemoryView":411 + * return self + * + * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<< + * + * cdef char *itemp */ - /*else*/ { - __pyx_t_3 = (__pyx_v_self->name != Py_None); - __pyx_v_use_setstate = __pyx_t_3; + __pyx_t_2 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 411, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (likely(__pyx_t_2 != Py_None)) { + PyObject* sequence = __pyx_t_2; + 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(1, 411, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 411, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 411, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 411, __pyx_L1_error) } - __pyx_L3:; + __pyx_v_have_slices = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_indices = __pyx_t_4; + __pyx_t_4 = 0; - /* "(tree fragment)":12 - * else: - * use_setstate = self.name is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_Enum, (type(self), 0xb068931, None), state - * else: + /* "View.MemoryView":414 + * + * cdef char *itemp + * if have_slices: # <<<<<<<<<<<<<< + * return memview_slice(self, indices) + * else: */ - __pyx_t_3 = (__pyx_v_use_setstate != 0); - if (__pyx_t_3) { + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 414, __pyx_L1_error) + if (__pyx_t_1) { - /* "(tree fragment)":13 - * use_setstate = self.name is not None - * if use_setstate: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, None), state # <<<<<<<<<<<<<< - * else: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, state) + /* "View.MemoryView":415 + * cdef char *itemp + * if have_slices: + * return memview_slice(self, indices) # <<<<<<<<<<<<<< + * else: + * itemp = self.get_item_pointer(indices) */ __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyx_unpickle_Enum); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_184977713); - __Pyx_GIVEREF(__pyx_int_184977713); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_184977713); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_1, 2, Py_None); - __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_state); - __pyx_t_4 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; + __pyx_t_2 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 415, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; goto __pyx_L0; - /* "(tree fragment)":12 - * else: - * use_setstate = self.name is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_Enum, (type(self), 0xb068931, None), state - * else: + /* "View.MemoryView":414 + * + * cdef char *itemp + * if have_slices: # <<<<<<<<<<<<<< + * return memview_slice(self, indices) + * else: */ } - /* "(tree fragment)":15 - * return __pyx_unpickle_Enum, (type(self), 0xb068931, None), state - * else: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, state) # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_Enum__set_state(self, __pyx_state) + /* "View.MemoryView":417 + * return memview_slice(self, indices) + * else: + * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<< + * return self.convert_item_to_object(itemp) + * */ /*else*/ { + __pyx_t_5 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_5 == ((char *)NULL))) __PYX_ERR(1, 417, __pyx_L1_error) + __pyx_v_itemp = __pyx_t_5; + + /* "View.MemoryView":418 + * else: + * itemp = self.get_item_pointer(indices) + * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<< + * + * def __setitem__(memoryview self, object index, object value): + */ __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_pyx_unpickle_Enum); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_184977713); - __Pyx_GIVEREF(__pyx_int_184977713); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_184977713); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_state); - __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1); - __pyx_t_5 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_4; - __pyx_t_4 = 0; + __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 418, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; goto __pyx_L0; } - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict + /* "View.MemoryView":407 + * + * + * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<< + * if index is Ellipsis: + * return self */ /* 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_AddTraceback("View.MemoryView.Enum.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; - __Pyx_XDECREF(__pyx_v_state); - __Pyx_XDECREF(__pyx_v__dict); + __Pyx_XDECREF(__pyx_v_have_slices); + __Pyx_XDECREF(__pyx_v_indices); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "(tree fragment)":16 - * else: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state(self, __pyx_state) +/* "View.MemoryView":420 + * return self.convert_item_to_object(itemp) + * + * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<< + * if self.view.readonly: + * raise TypeError, "Cannot assign to read-only memoryview" */ /* Python wrapper */ -static PyObject *__pyx_pw___pyx_MemviewEnum_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw___pyx_MemviewEnum_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; +static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/ +static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + int __pyx_r; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_MemviewEnum_2__setstate_cython__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static PyObject *__pyx_pf___pyx_MemviewEnum_2__setstate_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; +static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { + PyObject *__pyx_v_have_slices = NULL; + PyObject *__pyx_v_obj = NULL; + int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); + __Pyx_RefNannySetupContext("__setitem__", 0); + __Pyx_INCREF(__pyx_v_index); - /* "(tree fragment)":17 - * return __pyx_unpickle_Enum, (type(self), 0xb068931, state) - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_Enum__set_state(self, __pyx_state) # <<<<<<<<<<<<<< + /* "View.MemoryView":421 + * + * def __setitem__(memoryview self, object index, object value): + * if self.view.readonly: # <<<<<<<<<<<<<< + * raise TypeError, "Cannot assign to read-only memoryview" + * */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||((void)PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(2, 17, __pyx_L1_error) - __pyx_t_1 = __pyx_unpickle_Enum__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(__pyx_v_self->view.readonly)) { - /* "(tree fragment)":16 - * else: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state(self, __pyx_state) + /* "View.MemoryView":422 + * def __setitem__(memoryview self, object index, object value): + * if self.view.readonly: + * raise TypeError, "Cannot assign to read-only memoryview" # <<<<<<<<<<<<<< + * + * have_slices, index = _unellipsify(index, self.view.ndim) */ + __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_Cannot_assign_to_read_only_memor, 0, 0); + __PYX_ERR(1, 422, __pyx_L1_error) - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.Enum.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":299 + /* "View.MemoryView":421 * - * @cname('__pyx_align_pointer') - * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<< - * "Align pointer memory on a given boundary" - * cdef Py_intptr_t aligned_p = memory - */ - -static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) { - Py_intptr_t __pyx_v_aligned_p; - size_t __pyx_v_offset; - void *__pyx_r; - int __pyx_t_1; - - /* "View.MemoryView":301 - * cdef void *align_pointer(void *memory, size_t alignment) nogil: - * "Align pointer memory on a given boundary" - * cdef Py_intptr_t aligned_p = memory # <<<<<<<<<<<<<< - * cdef size_t offset + * def __setitem__(memoryview self, object index, object value): + * if self.view.readonly: # <<<<<<<<<<<<<< + * raise TypeError, "Cannot assign to read-only memoryview" * */ - __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory); + } - /* "View.MemoryView":305 + /* "View.MemoryView":424 + * raise TypeError, "Cannot assign to read-only memoryview" * - * with cython.cdivision(True): - * offset = aligned_p % alignment # <<<<<<<<<<<<<< + * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<< * - * if offset > 0: + * if have_slices: */ - __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment); + __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 424, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (likely(__pyx_t_1 != Py_None)) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(1, 424, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 424, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 424, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 424, __pyx_L1_error) + } + __pyx_v_have_slices = __pyx_t_2; + __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3); + __pyx_t_3 = 0; - /* "View.MemoryView":307 - * offset = aligned_p % alignment - * - * if offset > 0: # <<<<<<<<<<<<<< - * aligned_p += alignment - offset + /* "View.MemoryView":426 + * have_slices, index = _unellipsify(index, self.view.ndim) * + * if have_slices: # <<<<<<<<<<<<<< + * obj = self.is_slice(value) + * if obj: */ - __pyx_t_1 = ((__pyx_v_offset > 0) != 0); - if (__pyx_t_1) { + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(1, 426, __pyx_L1_error) + if (__pyx_t_4) { - /* "View.MemoryView":308 - * - * if offset > 0: - * aligned_p += alignment - offset # <<<<<<<<<<<<<< + /* "View.MemoryView":427 * - * return aligned_p + * if have_slices: + * obj = self.is_slice(value) # <<<<<<<<<<<<<< + * if obj: + * self.setitem_slice_assignment(self[index], obj) */ - __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset)); + __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 427, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_obj = __pyx_t_1; + __pyx_t_1 = 0; - /* "View.MemoryView":307 - * offset = aligned_p % alignment - * - * if offset > 0: # <<<<<<<<<<<<<< - * aligned_p += alignment - offset + /* "View.MemoryView":428 + * if have_slices: + * obj = self.is_slice(value) + * if obj: # <<<<<<<<<<<<<< + * self.setitem_slice_assignment(self[index], obj) + * else: + */ + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(1, 428, __pyx_L1_error) + if (__pyx_t_4) { + + /* "View.MemoryView":429 + * obj = self.is_slice(value) + * if obj: + * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<< + * else: + * self.setitem_slice_assign_scalar(self[index], value) + */ + __pyx_t_1 = __Pyx_PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 429, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 429, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "View.MemoryView":428 + * if have_slices: + * obj = self.is_slice(value) + * if obj: # <<<<<<<<<<<<<< + * self.setitem_slice_assignment(self[index], obj) + * else: + */ + goto __pyx_L5; + } + + /* "View.MemoryView":431 + * self.setitem_slice_assignment(self[index], obj) + * else: + * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<< + * else: + * self.setitem_indexed(index, value) + */ + /*else*/ { + __pyx_t_3 = __Pyx_PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 431, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) __PYX_ERR(1, 431, __pyx_L1_error) + __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 431, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __pyx_L5:; + + /* "View.MemoryView":426 + * have_slices, index = _unellipsify(index, self.view.ndim) * + * if have_slices: # <<<<<<<<<<<<<< + * obj = self.is_slice(value) + * if obj: */ + goto __pyx_L4; } - /* "View.MemoryView":310 - * aligned_p += alignment - offset - * - * return aligned_p # <<<<<<<<<<<<<< - * + /* "View.MemoryView":433 + * self.setitem_slice_assign_scalar(self[index], value) + * else: + * self.setitem_indexed(index, value) # <<<<<<<<<<<<<< * + * cdef is_slice(self, obj): */ - __pyx_r = ((void *)__pyx_v_aligned_p); - goto __pyx_L0; + /*else*/ { + __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 433, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __pyx_L4:; - /* "View.MemoryView":299 + /* "View.MemoryView":420 + * return self.convert_item_to_object(itemp) * - * @cname('__pyx_align_pointer') - * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<< - * "Align pointer memory on a given boundary" - * cdef Py_intptr_t aligned_p = memory + * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<< + * if self.view.readonly: + * raise TypeError, "Cannot assign to read-only memoryview" */ /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; __pyx_L0:; + __Pyx_XDECREF(__pyx_v_have_slices); + __Pyx_XDECREF(__pyx_v_obj); + __Pyx_XDECREF(__pyx_v_index); + __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":346 - * cdef __Pyx_TypeInfo *typeinfo +/* "View.MemoryView":435 + * self.setitem_indexed(index, value) * - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<< - * self.obj = obj - * self.flags = flags + * cdef is_slice(self, obj): # <<<<<<<<<<<<<< + * if not isinstance(obj, memoryview): + * try: */ -/* Python wrapper */ -static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_obj = 0; - int __pyx_v_flags; - int __pyx_v_dtype_is_object; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0}; - PyObject* values[3] = {0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); __PYX_ERR(2, 346, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_dtype_is_object); - if (value) { values[2] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(2, 346, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_obj = values[0]; - __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 346, __pyx_L3_error) - if (values[2]) { - __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 346, __pyx_L3_error) - } else { - __pyx_v_dtype_is_object = ((int)0); - } - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 346, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) { - int __pyx_r; +static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) { + PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_t_9; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 0); + __Pyx_RefNannySetupContext("is_slice", 0); + __Pyx_INCREF(__pyx_v_obj); - /* "View.MemoryView":347 + /* "View.MemoryView":436 * - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): - * self.obj = obj # <<<<<<<<<<<<<< - * self.flags = flags - * if type(self) is memoryview or obj is not None: + * cdef is_slice(self, obj): + * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<< + * try: + * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, */ - __Pyx_INCREF(__pyx_v_obj); - __Pyx_GIVEREF(__pyx_v_obj); - __Pyx_GOTREF(__pyx_v_self->obj); - __Pyx_DECREF(__pyx_v_self->obj); - __pyx_v_self->obj = __pyx_v_obj; + __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, __pyx_memoryview_type); + __pyx_t_2 = (!__pyx_t_1); + if (__pyx_t_2) { - /* "View.MemoryView":348 - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): - * self.obj = obj - * self.flags = flags # <<<<<<<<<<<<<< - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) + /* "View.MemoryView":437 + * cdef is_slice(self, obj): + * if not isinstance(obj, memoryview): + * try: # <<<<<<<<<<<<<< + * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, + * self.dtype_is_object) */ - __pyx_v_self->flags = __pyx_v_flags; + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + /*try:*/ { - /* "View.MemoryView":349 - * self.obj = obj - * self.flags = flags - * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<< - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: + /* "View.MemoryView":438 + * if not isinstance(obj, memoryview): + * try: + * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<< + * self.dtype_is_object) + * except TypeError: */ - __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)__pyx_memoryview_type)); - __pyx_t_3 = (__pyx_t_2 != 0); - if (!__pyx_t_3) { - } else { - __pyx_t_1 = __pyx_t_3; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_3 = (__pyx_v_obj != Py_None); - __pyx_t_2 = (__pyx_t_3 != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - if (__pyx_t_1) { + __pyx_t_6 = __Pyx_PyInt_From_int(((__pyx_v_self->flags & (~PyBUF_WRITABLE)) | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 438, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); - /* "View.MemoryView":350 - * self.flags = flags - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<< - * if self.view.obj == NULL: - * (<__pyx_buffer *> &self.view).obj = Py_None + /* "View.MemoryView":439 + * try: + * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, + * self.dtype_is_object) # <<<<<<<<<<<<<< + * except TypeError: + * return None */ - __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 350, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 439, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_7); - /* "View.MemoryView":351 - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: # <<<<<<<<<<<<<< - * (<__pyx_buffer *> &self.view).obj = Py_None - * Py_INCREF(Py_None) + /* "View.MemoryView":438 + * if not isinstance(obj, memoryview): + * try: + * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<< + * self.dtype_is_object) + * except TypeError: */ - __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0); - if (__pyx_t_1) { + __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 438, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_v_obj); + __Pyx_GIVEREF(__pyx_v_obj); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj)) __PYX_ERR(1, 438, __pyx_L4_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6)) __PYX_ERR(1, 438, __pyx_L4_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7)) __PYX_ERR(1, 438, __pyx_L4_error); + __pyx_t_6 = 0; + __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 438, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7); + __pyx_t_7 = 0; - /* "View.MemoryView":352 - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: - * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<< - * Py_INCREF(Py_None) + /* "View.MemoryView":437 + * cdef is_slice(self, obj): + * if not isinstance(obj, memoryview): + * try: # <<<<<<<<<<<<<< + * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, + * self.dtype_is_object) + */ + } + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L9_try_end; + __pyx_L4_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "View.MemoryView":440 + * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, + * self.dtype_is_object) + * except TypeError: # <<<<<<<<<<<<<< + * return None * */ - ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None; + __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError); + if (__pyx_t_9) { + __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) __PYX_ERR(1, 440, __pyx_L6_except_error) + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_6); - /* "View.MemoryView":353 - * if self.view.obj == NULL: - * (<__pyx_buffer *> &self.view).obj = Py_None - * Py_INCREF(Py_None) # <<<<<<<<<<<<<< + /* "View.MemoryView":441 + * self.dtype_is_object) + * except TypeError: + * return None # <<<<<<<<<<<<<< * - * if not __PYX_CYTHON_ATOMICS_ENABLED(): + * return obj */ - Py_INCREF(Py_None); + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + goto __pyx_L7_except_return; + } + goto __pyx_L6_except_error; - /* "View.MemoryView":351 - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: # <<<<<<<<<<<<<< - * (<__pyx_buffer *> &self.view).obj = Py_None - * Py_INCREF(Py_None) + /* "View.MemoryView":437 + * cdef is_slice(self, obj): + * if not isinstance(obj, memoryview): + * try: # <<<<<<<<<<<<<< + * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, + * self.dtype_is_object) */ + __pyx_L6_except_error:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); + goto __pyx_L1_error; + __pyx_L7_except_return:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); + goto __pyx_L0; + __pyx_L9_try_end:; } - /* "View.MemoryView":349 - * self.obj = obj - * self.flags = flags - * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<< - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: + /* "View.MemoryView":436 + * + * cdef is_slice(self, obj): + * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<< + * try: + * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, */ } - /* "View.MemoryView":355 - * Py_INCREF(Py_None) + /* "View.MemoryView":443 + * return None * - * if not __PYX_CYTHON_ATOMICS_ENABLED(): # <<<<<<<<<<<<<< - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: - */ - __pyx_t_1 = ((!(__PYX_CYTHON_ATOMICS_ENABLED() != 0)) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":357 - * if not __PYX_CYTHON_ATOMICS_ENABLED(): - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: # <<<<<<<<<<<<<< - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - */ - __pyx_t_1 = ((__pyx_memoryview_thread_locks_used < 8) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":358 - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: + * return obj # <<<<<<<<<<<<<< + * + * cdef setitem_slice_assignment(self, dst, src): */ - __pyx_v_self->lock = (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_obj); + __pyx_r = __pyx_v_obj; + goto __pyx_L0; - /* "View.MemoryView":359 - * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 # <<<<<<<<<<<<<< - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() + /* "View.MemoryView":435 + * self.setitem_indexed(index, value) + * + * cdef is_slice(self, obj): # <<<<<<<<<<<<<< + * if not isinstance(obj, memoryview): + * try: */ - __pyx_memoryview_thread_locks_used = (__pyx_memoryview_thread_locks_used + 1); - /* "View.MemoryView":357 - * if not __PYX_CYTHON_ATOMICS_ENABLED(): - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: # <<<<<<<<<<<<<< - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - */ - } + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_obj); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":360 - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: # <<<<<<<<<<<<<< - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: +/* "View.MemoryView":445 + * return obj + * + * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice dst_slice + * cdef __Pyx_memviewslice src_slice */ - __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0); - if (__pyx_t_1) { - /* "View.MemoryView":361 - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<< - * if self.lock is NULL: - * raise MemoryError - */ - __pyx_v_self->lock = PyThread_allocate_lock(); +static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) { + __Pyx_memviewslice __pyx_v_dst_slice; + __Pyx_memviewslice __pyx_v_src_slice; + __Pyx_memviewslice __pyx_v_msrc; + __Pyx_memviewslice __pyx_v_mdst; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_memviewslice *__pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("setitem_slice_assignment", 1); - /* "View.MemoryView":362 - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: # <<<<<<<<<<<<<< - * raise MemoryError + /* "View.MemoryView":448 + * cdef __Pyx_memviewslice dst_slice + * cdef __Pyx_memviewslice src_slice + * cdef __Pyx_memviewslice msrc = get_slice_from_memview(src, &src_slice)[0] # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice mdst = get_slice_from_memview(dst, &dst_slice)[0] * */ - __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0); - if (unlikely(__pyx_t_1)) { + if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) __PYX_ERR(1, 448, __pyx_L1_error) + __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(1, 448, __pyx_L1_error) + __pyx_v_msrc = (__pyx_t_1[0]); - /* "View.MemoryView":363 - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: - * raise MemoryError # <<<<<<<<<<<<<< + /* "View.MemoryView":449 + * cdef __Pyx_memviewslice src_slice + * cdef __Pyx_memviewslice msrc = get_slice_from_memview(src, &src_slice)[0] + * cdef __Pyx_memviewslice mdst = get_slice_from_memview(dst, &dst_slice)[0] # <<<<<<<<<<<<<< * - * if flags & PyBUF_FORMAT: + * memoryview_copy_contents(msrc, mdst, src.ndim, dst.ndim, self.dtype_is_object) */ - PyErr_NoMemory(); __PYX_ERR(2, 363, __pyx_L1_error) + if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) __PYX_ERR(1, 449, __pyx_L1_error) + __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(1, 449, __pyx_L1_error) + __pyx_v_mdst = (__pyx_t_1[0]); - /* "View.MemoryView":362 - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: # <<<<<<<<<<<<<< - * raise MemoryError + /* "View.MemoryView":451 + * cdef __Pyx_memviewslice mdst = get_slice_from_memview(dst, &dst_slice)[0] * + * memoryview_copy_contents(msrc, mdst, src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<< + * + * cdef setitem_slice_assign_scalar(self, memoryview dst, value): */ - } + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 451, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 451, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 451, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 451, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_5 = __pyx_memoryview_copy_contents(__pyx_v_msrc, __pyx_v_mdst, __pyx_t_3, __pyx_t_4, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(1, 451, __pyx_L1_error) - /* "View.MemoryView":360 - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: # <<<<<<<<<<<<<< - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: + /* "View.MemoryView":445 + * return obj + * + * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice dst_slice + * cdef __Pyx_memviewslice src_slice */ - } - /* "View.MemoryView":355 - * Py_INCREF(Py_None) + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "View.MemoryView":453 + * memoryview_copy_contents(msrc, mdst, src.ndim, dst.ndim, self.dtype_is_object) * - * if not __PYX_CYTHON_ATOMICS_ENABLED(): # <<<<<<<<<<<<<< - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: + * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<< + * cdef int array[128] + * cdef void *tmp = NULL */ - } - /* "View.MemoryView":365 - * raise MemoryError +static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) { + int __pyx_v_array[0x80]; + void *__pyx_v_tmp; + void *__pyx_v_item; + __Pyx_memviewslice *__pyx_v_dst_slice; + __Pyx_memviewslice __pyx_v_tmp_slice; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_memviewslice *__pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + char const *__pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 1); + + /* "View.MemoryView":455 + * cdef setitem_slice_assign_scalar(self, memoryview dst, value): + * cdef int array[128] + * cdef void *tmp = NULL # <<<<<<<<<<<<<< + * cdef void *item * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') - * else: */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); - if (__pyx_t_1) { + __pyx_v_tmp = NULL; - /* "View.MemoryView":366 + /* "View.MemoryView":460 + * cdef __Pyx_memviewslice *dst_slice + * cdef __Pyx_memviewslice tmp_slice + * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<< * - * if flags & PyBUF_FORMAT: - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') # <<<<<<<<<<<<<< - * else: - * self.dtype_is_object = dtype_is_object + * if self.view.itemsize > sizeof(array): */ - __pyx_t_2 = (((__pyx_v_self->view.format[0]) == 'O') != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L12_bool_binop_done; - } - __pyx_t_2 = (((__pyx_v_self->view.format[1]) == '\x00') != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L12_bool_binop_done:; - __pyx_v_self->dtype_is_object = __pyx_t_1; + __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(1, 460, __pyx_L1_error) + __pyx_v_dst_slice = __pyx_t_1; - /* "View.MemoryView":365 - * raise MemoryError + /* "View.MemoryView":462 + * dst_slice = get_slice_from_memview(dst, &tmp_slice) * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') - * else: + * if self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<< + * tmp = PyMem_Malloc(self.view.itemsize) + * if tmp == NULL: */ - goto __pyx_L11; - } + __pyx_t_2 = (((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))); + if (__pyx_t_2) { - /* "View.MemoryView":368 - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') - * else: - * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<< + /* "View.MemoryView":463 * - * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( + * if self.view.itemsize > sizeof(array): + * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<< + * if tmp == NULL: + * raise MemoryError */ - /*else*/ { - __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object; - } - __pyx_L11:; + __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize); - /* "View.MemoryView":370 - * self.dtype_is_object = dtype_is_object - * - * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<< - * &self.acquisition_count[0], sizeof(__pyx_atomic_int)) - * self.typeinfo = NULL + /* "View.MemoryView":464 + * if self.view.itemsize > sizeof(array): + * tmp = PyMem_Malloc(self.view.itemsize) + * if tmp == NULL: # <<<<<<<<<<<<<< + * raise MemoryError + * item = tmp */ - __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int)))); + __pyx_t_2 = (__pyx_v_tmp == NULL); + if (unlikely(__pyx_t_2)) { - /* "View.MemoryView":372 - * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( - * &self.acquisition_count[0], sizeof(__pyx_atomic_int)) - * self.typeinfo = NULL # <<<<<<<<<<<<<< - * - * def __dealloc__(memoryview self): + /* "View.MemoryView":465 + * tmp = PyMem_Malloc(self.view.itemsize) + * if tmp == NULL: + * raise MemoryError # <<<<<<<<<<<<<< + * item = tmp + * else: */ - __pyx_v_self->typeinfo = NULL; + PyErr_NoMemory(); __PYX_ERR(1, 465, __pyx_L1_error) - /* "View.MemoryView":346 - * cdef __Pyx_TypeInfo *typeinfo - * - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<< - * self.obj = obj - * self.flags = flags + /* "View.MemoryView":464 + * if self.view.itemsize > sizeof(array): + * tmp = PyMem_Malloc(self.view.itemsize) + * if tmp == NULL: # <<<<<<<<<<<<<< + * raise MemoryError + * item = tmp */ + } - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":466 + * if tmp == NULL: + * raise MemoryError + * item = tmp # <<<<<<<<<<<<<< + * else: + * item = array + */ + __pyx_v_item = __pyx_v_tmp; -/* "View.MemoryView":374 - * self.typeinfo = NULL + /* "View.MemoryView":462 + * dst_slice = get_slice_from_memview(dst, &tmp_slice) * - * def __dealloc__(memoryview self): # <<<<<<<<<<<<<< - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) + * if self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<< + * tmp = PyMem_Malloc(self.view.itemsize) + * if tmp == NULL: */ + goto __pyx_L3; + } -/* Python wrapper */ -static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) { - int __pyx_v_i; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - PyThread_type_lock __pyx_t_6; - PyThread_type_lock __pyx_t_7; - __Pyx_RefNannySetupContext("__dealloc__", 0); - - /* "View.MemoryView":375 + /* "View.MemoryView":468 + * item = tmp + * else: + * item = array # <<<<<<<<<<<<<< * - * def __dealloc__(memoryview self): - * if self.obj is not None: # <<<<<<<<<<<<<< - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: + * try: */ - __pyx_t_1 = (__pyx_v_self->obj != Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { + /*else*/ { + __pyx_v_item = ((void *)__pyx_v_array); + } + __pyx_L3:; - /* "View.MemoryView":376 - * def __dealloc__(memoryview self): - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<< - * elif (<__pyx_buffer *> &self.view).obj == Py_None: + /* "View.MemoryView":470 + * item = array * + * try: # <<<<<<<<<<<<<< + * if self.dtype_is_object: + * ( item)[0] = value */ - __Pyx_ReleaseBuffer((&__pyx_v_self->view)); + /*try:*/ { - /* "View.MemoryView":375 + /* "View.MemoryView":471 * - * def __dealloc__(memoryview self): - * if self.obj is not None: # <<<<<<<<<<<<<< - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: + * try: + * if self.dtype_is_object: # <<<<<<<<<<<<<< + * ( item)[0] = value + * else: */ - goto __pyx_L3; - } + if (__pyx_v_self->dtype_is_object) { - /* "View.MemoryView":377 - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: # <<<<<<<<<<<<<< + /* "View.MemoryView":472 + * try: + * if self.dtype_is_object: + * ( item)[0] = value # <<<<<<<<<<<<<< + * else: + * self.assign_item_from_object( item, value) + */ + (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value); + + /* "View.MemoryView":471 * - * (<__pyx_buffer *> &self.view).obj = NULL + * try: + * if self.dtype_is_object: # <<<<<<<<<<<<<< + * ( item)[0] = value + * else: */ - __pyx_t_2 = ((((Py_buffer *)(&__pyx_v_self->view))->obj == Py_None) != 0); - if (__pyx_t_2) { + goto __pyx_L8; + } - /* "View.MemoryView":379 - * elif (<__pyx_buffer *> &self.view).obj == Py_None: + /* "View.MemoryView":474 + * ( item)[0] = value + * else: + * self.assign_item_from_object( item, value) # <<<<<<<<<<<<<< * - * (<__pyx_buffer *> &self.view).obj = NULL # <<<<<<<<<<<<<< - * Py_DECREF(Py_None) * */ - ((Py_buffer *)(&__pyx_v_self->view))->obj = NULL; + /*else*/ { + __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 474, __pyx_L6_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_L8:; - /* "View.MemoryView":380 + /* "View.MemoryView":478 * - * (<__pyx_buffer *> &self.view).obj = NULL - * Py_DECREF(Py_None) # <<<<<<<<<<<<<< * - * cdef int i + * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<< + * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) + * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, */ - Py_DECREF(Py_None); + __pyx_t_2 = (__pyx_v_self->view.suboffsets != NULL); + if (__pyx_t_2) { - /* "View.MemoryView":377 - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: # <<<<<<<<<<<<<< + /* "View.MemoryView":479 * - * (<__pyx_buffer *> &self.view).obj = NULL - */ - } - __pyx_L3:; - - /* "View.MemoryView":384 - * cdef int i - * global __pyx_memoryview_thread_locks_used - * if self.lock != NULL: # <<<<<<<<<<<<<< - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: - */ - __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":385 - * global __pyx_memoryview_thread_locks_used - * if self.lock != NULL: - * for i in range(__pyx_memoryview_thread_locks_used): # <<<<<<<<<<<<<< - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 - */ - __pyx_t_3 = __pyx_memoryview_thread_locks_used; - __pyx_t_4 = __pyx_t_3; - for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { - __pyx_v_i = __pyx_t_5; - - /* "View.MemoryView":386 - * if self.lock != NULL: - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: + * if self.view.suboffsets != NULL: + * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<< + * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, + * item, self.dtype_is_object) */ - __pyx_t_2 = (((__pyx_memoryview_thread_locks[__pyx_v_i]) == __pyx_v_self->lock) != 0); - if (__pyx_t_2) { + __pyx_t_4 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 479, __pyx_L6_error) - /* "View.MemoryView":387 - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 # <<<<<<<<<<<<<< - * if i != __pyx_memoryview_thread_locks_used: - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( + /* "View.MemoryView":478 + * + * + * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<< + * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) + * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, */ - __pyx_memoryview_thread_locks_used = (__pyx_memoryview_thread_locks_used - 1); + } - /* "View.MemoryView":388 - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) + /* "View.MemoryView":480 + * if self.view.suboffsets != NULL: + * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) + * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<< + * item, self.dtype_is_object) + * finally: */ - __pyx_t_2 = ((__pyx_v_i != __pyx_memoryview_thread_locks_used) != 0); - if (__pyx_t_2) { + __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object); + } - /* "View.MemoryView":390 - * if i != __pyx_memoryview_thread_locks_used: - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) # <<<<<<<<<<<<<< - * break - * else: + /* "View.MemoryView":483 + * item, self.dtype_is_object) + * finally: + * PyMem_Free(tmp) # <<<<<<<<<<<<<< + * + * cdef setitem_indexed(self, index, value): */ - __pyx_t_6 = (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]); - __pyx_t_7 = (__pyx_memoryview_thread_locks[__pyx_v_i]); + /*finally:*/ { + /*normal exit:*/{ + PyMem_Free(__pyx_v_tmp); + goto __pyx_L7; + } + __pyx_L6_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9) < 0)) __Pyx_ErrFetch(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_9); + __Pyx_XGOTREF(__pyx_t_10); + __Pyx_XGOTREF(__pyx_t_11); + __Pyx_XGOTREF(__pyx_t_12); + __pyx_t_4 = __pyx_lineno; __pyx_t_5 = __pyx_clineno; __pyx_t_6 = __pyx_filename; + { + PyMem_Free(__pyx_v_tmp); + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_10); + __Pyx_XGIVEREF(__pyx_t_11); + __Pyx_XGIVEREF(__pyx_t_12); + __Pyx_ExceptionReset(__pyx_t_10, __pyx_t_11, __pyx_t_12); + } + __Pyx_XGIVEREF(__pyx_t_7); + __Pyx_XGIVEREF(__pyx_t_8); + __Pyx_XGIVEREF(__pyx_t_9); + __Pyx_ErrRestore(__pyx_t_7, __pyx_t_8, __pyx_t_9); + __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; + __pyx_lineno = __pyx_t_4; __pyx_clineno = __pyx_t_5; __pyx_filename = __pyx_t_6; + goto __pyx_L1_error; + } + __pyx_L7:; + } - /* "View.MemoryView":389 - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - * break + /* "View.MemoryView":453 + * memoryview_copy_contents(msrc, mdst, src.ndim, dst.ndim, self.dtype_is_object) + * + * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<< + * cdef int array[128] + * cdef void *tmp = NULL */ - (__pyx_memoryview_thread_locks[__pyx_v_i]) = __pyx_t_6; - (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]) = __pyx_t_7; - /* "View.MemoryView":388 - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - */ - } + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":391 - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - * break # <<<<<<<<<<<<<< - * else: - * PyThread_free_lock(self.lock) +/* "View.MemoryView":485 + * PyMem_Free(tmp) + * + * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<< + * cdef char *itemp = self.get_item_pointer(index) + * self.assign_item_from_object(itemp, value) */ - goto __pyx_L6_break; - /* "View.MemoryView":386 - * if self.lock != NULL: - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: - */ - } - } - /*else*/ { +static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { + char *__pyx_v_itemp; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + char *__pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("setitem_indexed", 1); - /* "View.MemoryView":393 - * break - * else: - * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<< + /* "View.MemoryView":486 + * + * cdef setitem_indexed(self, index, value): + * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<< + * self.assign_item_from_object(itemp, value) * - * cdef char *get_item_pointer(memoryview self, object index) except NULL: */ - PyThread_free_lock(__pyx_v_self->lock); - } - __pyx_L6_break:; + __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == ((char *)NULL))) __PYX_ERR(1, 486, __pyx_L1_error) + __pyx_v_itemp = __pyx_t_1; - /* "View.MemoryView":384 - * cdef int i - * global __pyx_memoryview_thread_locks_used - * if self.lock != NULL: # <<<<<<<<<<<<<< - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: + /* "View.MemoryView":487 + * cdef setitem_indexed(self, index, value): + * cdef char *itemp = self.get_item_pointer(index) + * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<< + * + * cdef convert_item_to_object(self, char *itemp): */ - } + __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 487, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "View.MemoryView":374 - * self.typeinfo = NULL + /* "View.MemoryView":485 + * PyMem_Free(tmp) * - * def __dealloc__(memoryview self): # <<<<<<<<<<<<<< - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) + * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<< + * cdef char *itemp = self.get_item_pointer(index) + * self.assign_item_from_object(itemp, value) */ /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); + return __pyx_r; } -/* "View.MemoryView":395 - * PyThread_free_lock(self.lock) +/* "View.MemoryView":489 + * self.assign_item_from_object(itemp, value) * - * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<< - * cdef Py_ssize_t dim - * cdef char *itemp = self.view.buf + * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< + * """Only used if instantiated manually by the user, or if Cython doesn't + * know how to convert the type""" */ -static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) { - Py_ssize_t __pyx_v_dim; - char *__pyx_v_itemp; - PyObject *__pyx_v_idx = NULL; - char *__pyx_r; +static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) { + PyObject *__pyx_v_struct = NULL; + PyObject *__pyx_v_bytesitem = 0; + PyObject *__pyx_v_result = NULL; + PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; + PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; - Py_ssize_t __pyx_t_3; - PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; - Py_ssize_t __pyx_t_6; - char *__pyx_t_7; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + Py_ssize_t __pyx_t_9; + int __pyx_t_10; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_item_pointer", 0); + __Pyx_RefNannySetupContext("convert_item_to_object", 1); - /* "View.MemoryView":397 - * cdef char *get_item_pointer(memoryview self, object index) except NULL: - * cdef Py_ssize_t dim - * cdef char *itemp = self.view.buf # <<<<<<<<<<<<<< + /* "View.MemoryView":492 + * """Only used if instantiated manually by the user, or if Cython doesn't + * know how to convert the type""" + * import struct # <<<<<<<<<<<<<< + * cdef bytes bytesitem * - * for dim, idx in enumerate(index): */ - __pyx_v_itemp = ((char *)__pyx_v_self->view.buf); - - /* "View.MemoryView":399 - * cdef char *itemp = self.view.buf - * - * for dim, idx in enumerate(index): # <<<<<<<<<<<<<< - * itemp = pybuffer_index(&self.view, itemp, idx, dim) + __pyx_t_1 = __Pyx_ImportDottedModule(__pyx_n_s_struct, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 492, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_struct = __pyx_t_1; + __pyx_t_1 = 0; + + /* "View.MemoryView":495 + * cdef bytes bytesitem * + * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<< + * try: + * result = struct.unpack(self.view.format, bytesitem) */ + __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 495, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_bytesitem = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; - if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) { - __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0; - __pyx_t_4 = NULL; - } else { - __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 399, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 399, __pyx_L1_error) - } - for (;;) { - if (likely(!__pyx_t_4)) { - if (likely(PyList_CheckExact(__pyx_t_2))) { - if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(2, 399, __pyx_L1_error) - #else - __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 399, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - } else { - if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(2, 399, __pyx_L1_error) - #else - __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 399, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - } - } else { - __pyx_t_5 = __pyx_t_4(__pyx_t_2); - if (unlikely(!__pyx_t_5)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(2, 399, __pyx_L1_error) + + /* "View.MemoryView":496 + * + * bytesitem = itemp[:self.view.itemsize] + * try: # <<<<<<<<<<<<<< + * result = struct.unpack(self.view.format, bytesitem) + * except struct.error: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "View.MemoryView":497 + * bytesitem = itemp[:self.view.itemsize] + * try: + * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<< + * except struct.error: + * raise ValueError, "Unable to convert item to object" + */ + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 497, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 497, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = NULL; + __pyx_t_8 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_7)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_8 = 1; } - break; } - __Pyx_GOTREF(__pyx_t_5); - } - __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5); - __pyx_t_5 = 0; - __pyx_v_dim = __pyx_t_1; - __pyx_t_1 = (__pyx_t_1 + 1); + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_7, __pyx_t_6, __pyx_v_bytesitem}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_8, 2+__pyx_t_8); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 497, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __pyx_v_result = __pyx_t_1; + __pyx_t_1 = 0; - /* "View.MemoryView":400 - * - * for dim, idx in enumerate(index): - * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<< + /* "View.MemoryView":496 * - * return itemp + * bytesitem = itemp[:self.view.itemsize] + * try: # <<<<<<<<<<<<<< + * result = struct.unpack(self.view.format, bytesitem) + * except struct.error: */ - __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 400, __pyx_L1_error) - __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == ((char *)NULL))) __PYX_ERR(2, 400, __pyx_L1_error) - __pyx_v_itemp = __pyx_t_7; + } - /* "View.MemoryView":399 - * cdef char *itemp = self.view.buf - * - * for dim, idx in enumerate(index): # <<<<<<<<<<<<<< - * itemp = pybuffer_index(&self.view, itemp, idx, dim) - * + /* "View.MemoryView":501 + * raise ValueError, "Unable to convert item to object" + * else: + * if len(self.view.format) == 1: # <<<<<<<<<<<<<< + * return result[0] + * return result */ - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + /*else:*/ { + __pyx_t_9 = __Pyx_ssize_strlen(__pyx_v_self->view.format); if (unlikely(__pyx_t_9 == ((Py_ssize_t)-1))) __PYX_ERR(1, 501, __pyx_L5_except_error) + __pyx_t_10 = (__pyx_t_9 == 1); + if (__pyx_t_10) { - /* "View.MemoryView":402 - * itemp = pybuffer_index(&self.view, itemp, idx, dim) + /* "View.MemoryView":502 + * else: + * if len(self.view.format) == 1: + * return result[0] # <<<<<<<<<<<<<< + * return result * - * return itemp # <<<<<<<<<<<<<< + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 502, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L6_except_return; + + /* "View.MemoryView":501 + * raise ValueError, "Unable to convert item to object" + * else: + * if len(self.view.format) == 1: # <<<<<<<<<<<<<< + * return result[0] + * return result + */ + } + + /* "View.MemoryView":503 + * if len(self.view.format) == 1: + * return result[0] + * return result # <<<<<<<<<<<<<< * + * cdef assign_item_from_object(self, char *itemp, object value): + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_result); + __pyx_r = __pyx_v_result; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "View.MemoryView":498 + * try: + * result = struct.unpack(self.view.format, bytesitem) + * except struct.error: # <<<<<<<<<<<<<< + * raise ValueError, "Unable to convert item to object" + * else: + */ + __Pyx_ErrFetch(&__pyx_t_1, &__pyx_t_5, &__pyx_t_6); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 498, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyErr_GivenExceptionMatches(__pyx_t_1, __pyx_t_7); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_ErrRestore(__pyx_t_1, __pyx_t_5, __pyx_t_6); + __pyx_t_1 = 0; __pyx_t_5 = 0; __pyx_t_6 = 0; + if (__pyx_t_8) { + __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_5, &__pyx_t_1) < 0) __PYX_ERR(1, 498, __pyx_L5_except_error) + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_1); + + /* "View.MemoryView":499 + * result = struct.unpack(self.view.format, bytesitem) + * except struct.error: + * raise ValueError, "Unable to convert item to object" # <<<<<<<<<<<<<< + * else: + * if len(self.view.format) == 1: + */ + __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Unable_to_convert_item_to_object, 0, 0); + __PYX_ERR(1, 499, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + + /* "View.MemoryView":496 * + * bytesitem = itemp[:self.view.itemsize] + * try: # <<<<<<<<<<<<<< + * result = struct.unpack(self.view.format, bytesitem) + * except struct.error: */ - __pyx_r = __pyx_v_itemp; - goto __pyx_L0; + __pyx_L5_except_error:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L0; + } - /* "View.MemoryView":395 - * PyThread_free_lock(self.lock) + /* "View.MemoryView":489 + * self.assign_item_from_object(itemp, value) * - * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<< - * cdef Py_ssize_t dim - * cdef char *itemp = self.view.buf + * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< + * """Only used if instantiated manually by the user, or if Cython doesn't + * know how to convert the type""" */ /* function exit code */ __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; __pyx_L0:; - __Pyx_XDECREF(__pyx_v_idx); + __Pyx_XDECREF(__pyx_v_struct); + __Pyx_XDECREF(__pyx_v_bytesitem); + __Pyx_XDECREF(__pyx_v_result); + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":405 - * +/* "View.MemoryView":505 + * return result * - * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<< - * if index is Ellipsis: - * return self + * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< + * """Only used if instantiated manually by the user, or if Cython doesn't + * know how to convert the type""" */ -/* Python wrapper */ -static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/ -static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) { - PyObject *__pyx_v_have_slices = NULL; - PyObject *__pyx_v_indices = NULL; - char *__pyx_v_itemp; +static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) { + PyObject *__pyx_v_struct = NULL; + char __pyx_v_c; + PyObject *__pyx_v_bytesvalue = 0; + Py_ssize_t __pyx_v_i; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - int __pyx_t_1; + PyObject *__pyx_t_1 = NULL; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; - char *__pyx_t_6; + int __pyx_t_6; + Py_ssize_t __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + char *__pyx_t_9; + char *__pyx_t_10; + char *__pyx_t_11; + char *__pyx_t_12; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__getitem__", 0); + __Pyx_RefNannySetupContext("assign_item_from_object", 1); - /* "View.MemoryView":406 - * - * def __getitem__(memoryview self, object index): - * if index is Ellipsis: # <<<<<<<<<<<<<< - * return self - * + /* "View.MemoryView":508 + * """Only used if instantiated manually by the user, or if Cython doesn't + * know how to convert the type""" + * import struct # <<<<<<<<<<<<<< + * cdef char c + * cdef bytes bytesvalue */ - __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":407 - * def __getitem__(memoryview self, object index): - * if index is Ellipsis: - * return self # <<<<<<<<<<<<<< - * - * have_slices, indices = _unellipsify(index, self.view.ndim) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __pyx_r = ((PyObject *)__pyx_v_self); - goto __pyx_L0; + __pyx_t_1 = __Pyx_ImportDottedModule(__pyx_n_s_struct, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 508, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_struct = __pyx_t_1; + __pyx_t_1 = 0; - /* "View.MemoryView":406 - * - * def __getitem__(memoryview self, object index): - * if index is Ellipsis: # <<<<<<<<<<<<<< - * return self + /* "View.MemoryView":513 + * cdef Py_ssize_t i * + * if isinstance(value, tuple): # <<<<<<<<<<<<<< + * bytesvalue = struct.pack(self.view.format, *value) + * else: */ - } + __pyx_t_2 = PyTuple_Check(__pyx_v_value); + if (__pyx_t_2) { - /* "View.MemoryView":409 - * return self - * - * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<< + /* "View.MemoryView":514 * - * cdef char *itemp + * if isinstance(value, tuple): + * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<< + * else: + * bytesvalue = struct.pack(self.view.format, value) */ - __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 409, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (likely(__pyx_t_3 != Py_None)) { - PyObject* sequence = __pyx_t_3; - 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(2, 409, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - #else - __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 409, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 514, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 514, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 514, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 409, __pyx_L1_error) + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3)) __PYX_ERR(1, 514, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 514, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyNumber_Add(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 514, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - #endif + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(2, 409, __pyx_L1_error) - } - __pyx_v_have_slices = __pyx_t_4; - __pyx_t_4 = 0; - __pyx_v_indices = __pyx_t_5; - __pyx_t_5 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 514, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (!(likely(PyBytes_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None) || __Pyx_RaiseUnexpectedTypeError("bytes", __pyx_t_3))) __PYX_ERR(1, 514, __pyx_L1_error) + __pyx_v_bytesvalue = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; - /* "View.MemoryView":412 + /* "View.MemoryView":513 + * cdef Py_ssize_t i * - * cdef char *itemp - * if have_slices: # <<<<<<<<<<<<<< - * return memview_slice(self, indices) + * if isinstance(value, tuple): # <<<<<<<<<<<<<< + * bytesvalue = struct.pack(self.view.format, *value) * else: */ - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(2, 412, __pyx_L1_error) - if (__pyx_t_2) { + goto __pyx_L3; + } - /* "View.MemoryView":413 - * cdef char *itemp - * if have_slices: - * return memview_slice(self, indices) # <<<<<<<<<<<<<< + /* "View.MemoryView":516 + * bytesvalue = struct.pack(self.view.format, *value) * else: - * itemp = self.get_item_pointer(indices) + * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<< + * + * for i, c in enumerate(bytesvalue): */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 413, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_r = __pyx_t_3; + /*else*/ { + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 516, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 516, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_t_1, __pyx_v_value}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 516, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + if (!(likely(PyBytes_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None) || __Pyx_RaiseUnexpectedTypeError("bytes", __pyx_t_3))) __PYX_ERR(1, 516, __pyx_L1_error) + __pyx_v_bytesvalue = ((PyObject*)__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L0; + } + __pyx_L3:; - /* "View.MemoryView":412 + /* "View.MemoryView":518 + * bytesvalue = struct.pack(self.view.format, value) + * + * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<< + * itemp[i] = c * - * cdef char *itemp - * if have_slices: # <<<<<<<<<<<<<< - * return memview_slice(self, indices) - * else: */ + __pyx_t_7 = 0; + if (unlikely(__pyx_v_bytesvalue == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable"); + __PYX_ERR(1, 518, __pyx_L1_error) } + __Pyx_INCREF(__pyx_v_bytesvalue); + __pyx_t_8 = __pyx_v_bytesvalue; + __pyx_t_10 = PyBytes_AS_STRING(__pyx_t_8); + __pyx_t_11 = (__pyx_t_10 + PyBytes_GET_SIZE(__pyx_t_8)); + for (__pyx_t_12 = __pyx_t_10; __pyx_t_12 < __pyx_t_11; __pyx_t_12++) { + __pyx_t_9 = __pyx_t_12; + __pyx_v_c = (__pyx_t_9[0]); - /* "View.MemoryView":415 - * return memview_slice(self, indices) - * else: - * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<< - * return self.convert_item_to_object(itemp) + /* "View.MemoryView":519 + * + * for i, c in enumerate(bytesvalue): + * itemp[i] = c # <<<<<<<<<<<<<< * + * @cname('getbuffer') */ - /*else*/ { - __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == ((char *)NULL))) __PYX_ERR(2, 415, __pyx_L1_error) - __pyx_v_itemp = __pyx_t_6; + __pyx_v_i = __pyx_t_7; - /* "View.MemoryView":416 - * else: - * itemp = self.get_item_pointer(indices) - * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<< + /* "View.MemoryView":518 + * bytesvalue = struct.pack(self.view.format, value) + * + * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<< + * itemp[i] = c * - * def __setitem__(memoryview self, object index, object value): */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 416, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - } + __pyx_t_7 = (__pyx_t_7 + 1); - /* "View.MemoryView":405 + /* "View.MemoryView":519 * + * for i, c in enumerate(bytesvalue): + * itemp[i] = c # <<<<<<<<<<<<<< * - * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<< - * if index is Ellipsis: - * return self + * @cname('getbuffer') + */ + (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c; + } + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "View.MemoryView":505 + * return result + * + * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< + * """Only used if instantiated manually by the user, or if Cython doesn't + * know how to convert the type""" */ /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; __pyx_L0:; - __Pyx_XDECREF(__pyx_v_have_slices); - __Pyx_XDECREF(__pyx_v_indices); + __Pyx_XDECREF(__pyx_v_struct); + __Pyx_XDECREF(__pyx_v_bytesvalue); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":418 - * return self.convert_item_to_object(itemp) +/* "View.MemoryView":521 + * itemp[i] = c * - * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<< - * if self.view.readonly: - * raise TypeError("Cannot assign to read-only memoryview") + * @cname('getbuffer') # <<<<<<<<<<<<<< + * def __getbuffer__(self, Py_buffer *info, int flags): + * if flags & PyBUF_WRITABLE and self.view.readonly: */ /* Python wrapper */ -static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/ -static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { +CYTHON_UNUSED static int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ +CYTHON_UNUSED static int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; int __pyx_r; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value)); + __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { - PyObject *__pyx_v_have_slices = NULL; - PyObject *__pyx_v_obj = NULL; +static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { int __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; + int __pyx_t_2; + Py_ssize_t *__pyx_t_3; + char *__pyx_t_4; + void *__pyx_t_5; + int __pyx_t_6; + Py_ssize_t __pyx_t_7; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setitem__", 0); - __Pyx_INCREF(__pyx_v_index); + if (unlikely(__pyx_v_info == NULL)) { + PyErr_SetString(PyExc_BufferError, "PyObject_GetBuffer: view==NULL argument is obsolete"); + return -1; + } + __Pyx_RefNannySetupContext("__getbuffer__", 0); + __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(__pyx_v_info->obj); - /* "View.MemoryView":419 - * - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: # <<<<<<<<<<<<<< - * raise TypeError("Cannot assign to read-only memoryview") + /* "View.MemoryView":523 + * @cname('getbuffer') + * def __getbuffer__(self, Py_buffer *info, int flags): + * if flags & PyBUF_WRITABLE and self.view.readonly: # <<<<<<<<<<<<<< + * raise ValueError, "Cannot create writable memory view from read-only memoryview" * */ - __pyx_t_1 = (__pyx_v_self->view.readonly != 0); + __pyx_t_2 = ((__pyx_v_flags & PyBUF_WRITABLE) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_1 = __pyx_v_self->view.readonly; + __pyx_L4_bool_binop_done:; if (unlikely(__pyx_t_1)) { - /* "View.MemoryView":420 - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: - * raise TypeError("Cannot assign to read-only memoryview") # <<<<<<<<<<<<<< - * - * have_slices, index = _unellipsify(index, self.view.ndim) - */ - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 420, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(2, 420, __pyx_L1_error) - - /* "View.MemoryView":419 - * - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: # <<<<<<<<<<<<<< - * raise TypeError("Cannot assign to read-only memoryview") + /* "View.MemoryView":524 + * def __getbuffer__(self, Py_buffer *info, int flags): + * if flags & PyBUF_WRITABLE and self.view.readonly: + * raise ValueError, "Cannot create writable memory view from read-only memoryview" # <<<<<<<<<<<<<< * + * if flags & PyBUF_ND: */ - } + __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Cannot_create_writable_memory_vi, 0, 0); + __PYX_ERR(1, 524, __pyx_L1_error) - /* "View.MemoryView":422 - * raise TypeError("Cannot assign to read-only memoryview") - * - * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<< + /* "View.MemoryView":523 + * @cname('getbuffer') + * def __getbuffer__(self, Py_buffer *info, int flags): + * if flags & PyBUF_WRITABLE and self.view.readonly: # <<<<<<<<<<<<<< + * raise ValueError, "Cannot create writable memory view from read-only memoryview" * - * if have_slices: */ - __pyx_t_2 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 422, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (likely(__pyx_t_2 != Py_None)) { - PyObject* sequence = __pyx_t_2; - 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(2, 422, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - #else - __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 422, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 422, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - #endif - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } else { - __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(2, 422, __pyx_L1_error) } - __pyx_v_have_slices = __pyx_t_3; - __pyx_t_3 = 0; - __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_4); - __pyx_t_4 = 0; - /* "View.MemoryView":424 - * have_slices, index = _unellipsify(index, self.view.ndim) + /* "View.MemoryView":526 + * raise ValueError, "Cannot create writable memory view from read-only memoryview" * - * if have_slices: # <<<<<<<<<<<<<< - * obj = self.is_slice(value) - * if obj: + * if flags & PyBUF_ND: # <<<<<<<<<<<<<< + * info.shape = self.view.shape + * else: */ - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 424, __pyx_L1_error) + __pyx_t_1 = ((__pyx_v_flags & PyBUF_ND) != 0); if (__pyx_t_1) { - /* "View.MemoryView":425 + /* "View.MemoryView":527 * - * if have_slices: - * obj = self.is_slice(value) # <<<<<<<<<<<<<< - * if obj: - * self.setitem_slice_assignment(self[index], obj) + * if flags & PyBUF_ND: + * info.shape = self.view.shape # <<<<<<<<<<<<<< + * else: + * info.shape = NULL */ - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 425, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v_obj = __pyx_t_2; - __pyx_t_2 = 0; + __pyx_t_3 = __pyx_v_self->view.shape; + __pyx_v_info->shape = __pyx_t_3; - /* "View.MemoryView":426 - * if have_slices: - * obj = self.is_slice(value) - * if obj: # <<<<<<<<<<<<<< - * self.setitem_slice_assignment(self[index], obj) - * else: + /* "View.MemoryView":526 + * raise ValueError, "Cannot create writable memory view from read-only memoryview" + * + * if flags & PyBUF_ND: # <<<<<<<<<<<<<< + * info.shape = self.view.shape + * else: */ - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 426, __pyx_L1_error) - if (__pyx_t_1) { + goto __pyx_L6; + } - /* "View.MemoryView":427 - * obj = self.is_slice(value) - * if obj: - * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<< - * else: - * self.setitem_slice_assign_scalar(self[index], value) + /* "View.MemoryView":529 + * info.shape = self.view.shape + * else: + * info.shape = NULL # <<<<<<<<<<<<<< + * + * if flags & PyBUF_STRIDES: */ - __pyx_t_2 = __Pyx_PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 427, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_2, __pyx_v_obj); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 427, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + /*else*/ { + __pyx_v_info->shape = NULL; + } + __pyx_L6:; - /* "View.MemoryView":426 - * if have_slices: - * obj = self.is_slice(value) - * if obj: # <<<<<<<<<<<<<< - * self.setitem_slice_assignment(self[index], obj) - * else: + /* "View.MemoryView":531 + * info.shape = NULL + * + * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< + * info.strides = self.view.strides + * else: */ - goto __pyx_L5; - } + __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0); + if (__pyx_t_1) { - /* "View.MemoryView":429 - * self.setitem_slice_assignment(self[index], obj) - * else: - * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<< + /* "View.MemoryView":532 + * + * if flags & PyBUF_STRIDES: + * info.strides = self.view.strides # <<<<<<<<<<<<<< * else: - * self.setitem_indexed(index, value) + * info.strides = NULL */ - /*else*/ { - __pyx_t_4 = __Pyx_PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 429, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_memoryview_type))))) __PYX_ERR(2, 429, __pyx_L1_error) - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_4), __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 429, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } - __pyx_L5:; + __pyx_t_3 = __pyx_v_self->view.strides; + __pyx_v_info->strides = __pyx_t_3; - /* "View.MemoryView":424 - * have_slices, index = _unellipsify(index, self.view.ndim) + /* "View.MemoryView":531 + * info.shape = NULL * - * if have_slices: # <<<<<<<<<<<<<< - * obj = self.is_slice(value) - * if obj: + * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< + * info.strides = self.view.strides + * else: */ - goto __pyx_L4; + goto __pyx_L7; } - /* "View.MemoryView":431 - * self.setitem_slice_assign_scalar(self[index], value) + /* "View.MemoryView":534 + * info.strides = self.view.strides * else: - * self.setitem_indexed(index, value) # <<<<<<<<<<<<<< + * info.strides = NULL # <<<<<<<<<<<<<< * - * cdef is_slice(self, obj): + * if flags & PyBUF_INDIRECT: */ /*else*/ { - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 431, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_info->strides = NULL; } - __pyx_L4:; + __pyx_L7:; - /* "View.MemoryView":418 - * return self.convert_item_to_object(itemp) + /* "View.MemoryView":536 + * info.strides = NULL * - * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<< - * if self.view.readonly: - * raise TypeError("Cannot assign to read-only memoryview") + * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<< + * info.suboffsets = self.view.suboffsets + * else: */ + __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0); + if (__pyx_t_1) { - /* 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_4); - __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_have_slices); - __Pyx_XDECREF(__pyx_v_obj); - __Pyx_XDECREF(__pyx_v_index); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":433 - * self.setitem_indexed(index, value) + /* "View.MemoryView":537 * - * cdef is_slice(self, obj): # <<<<<<<<<<<<<< - * if not isinstance(obj, memoryview): - * try: + * if flags & PyBUF_INDIRECT: + * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<< + * else: + * info.suboffsets = NULL */ + __pyx_t_3 = __pyx_v_self->view.suboffsets; + __pyx_v_info->suboffsets = __pyx_t_3; -static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("is_slice", 0); - __Pyx_INCREF(__pyx_v_obj); - - /* "View.MemoryView":434 + /* "View.MemoryView":536 + * info.strides = NULL * - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<< - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, + * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<< + * info.suboffsets = self.view.suboffsets + * else: */ - __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, __pyx_memoryview_type); - __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); - if (__pyx_t_2) { + goto __pyx_L8; + } - /* "View.MemoryView":435 - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): - * try: # <<<<<<<<<<<<<< - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) + /* "View.MemoryView":539 + * info.suboffsets = self.view.suboffsets + * else: + * info.suboffsets = NULL # <<<<<<<<<<<<<< + * + * if flags & PyBUF_FORMAT: */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - /*try:*/ { + /*else*/ { + __pyx_v_info->suboffsets = NULL; + } + __pyx_L8:; - /* "View.MemoryView":436 - * if not isinstance(obj, memoryview): - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<< - * self.dtype_is_object) - * except TypeError: + /* "View.MemoryView":541 + * info.suboffsets = NULL + * + * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< + * info.format = self.view.format + * else: */ - __pyx_t_6 = __Pyx_PyInt_From_int(((__pyx_v_self->flags & (~PyBUF_WRITABLE)) | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 436, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); + if (__pyx_t_1) { - /* "View.MemoryView":437 - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) # <<<<<<<<<<<<<< - * except TypeError: - * return None + /* "View.MemoryView":542 + * + * if flags & PyBUF_FORMAT: + * info.format = self.view.format # <<<<<<<<<<<<<< + * else: + * info.format = NULL */ - __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 437, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_7); + __pyx_t_4 = __pyx_v_self->view.format; + __pyx_v_info->format = __pyx_t_4; - /* "View.MemoryView":436 - * if not isinstance(obj, memoryview): - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<< - * self.dtype_is_object) - * except TypeError: + /* "View.MemoryView":541 + * info.suboffsets = NULL + * + * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< + * info.format = self.view.format + * else: */ - __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 436, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_INCREF(__pyx_v_obj); - __Pyx_GIVEREF(__pyx_v_obj); - PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7); - __pyx_t_6 = 0; - __pyx_t_7 = 0; - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 436, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7); - __pyx_t_7 = 0; + goto __pyx_L9; + } - /* "View.MemoryView":435 - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): - * try: # <<<<<<<<<<<<<< - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) + /* "View.MemoryView":544 + * info.format = self.view.format + * else: + * info.format = NULL # <<<<<<<<<<<<<< + * + * info.buf = self.view.buf */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - goto __pyx_L9_try_end; - __pyx_L4_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + /*else*/ { + __pyx_v_info->format = NULL; + } + __pyx_L9:; - /* "View.MemoryView":438 - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) - * except TypeError: # <<<<<<<<<<<<<< - * return None + /* "View.MemoryView":546 + * info.format = NULL * + * info.buf = self.view.buf # <<<<<<<<<<<<<< + * info.ndim = self.view.ndim + * info.itemsize = self.view.itemsize */ - __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError); - if (__pyx_t_9) { - __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) __PYX_ERR(2, 438, __pyx_L6_except_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GOTREF(__pyx_t_8); - __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = __pyx_v_self->view.buf; + __pyx_v_info->buf = __pyx_t_5; - /* "View.MemoryView":439 - * self.dtype_is_object) - * except TypeError: - * return None # <<<<<<<<<<<<<< + /* "View.MemoryView":547 * - * return obj + * info.buf = self.view.buf + * info.ndim = self.view.ndim # <<<<<<<<<<<<<< + * info.itemsize = self.view.itemsize + * info.len = self.view.len */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - goto __pyx_L7_except_return; - } - goto __pyx_L6_except_error; - __pyx_L6_except_error:; + __pyx_t_6 = __pyx_v_self->view.ndim; + __pyx_v_info->ndim = __pyx_t_6; - /* "View.MemoryView":435 - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): - * try: # <<<<<<<<<<<<<< - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) + /* "View.MemoryView":548 + * info.buf = self.view.buf + * info.ndim = self.view.ndim + * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<< + * info.len = self.view.len + * info.readonly = self.view.readonly */ - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L1_error; - __pyx_L7_except_return:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L0; - __pyx_L9_try_end:; - } + __pyx_t_7 = __pyx_v_self->view.itemsize; + __pyx_v_info->itemsize = __pyx_t_7; + + /* "View.MemoryView":549 + * info.ndim = self.view.ndim + * info.itemsize = self.view.itemsize + * info.len = self.view.len # <<<<<<<<<<<<<< + * info.readonly = self.view.readonly + * info.obj = self + */ + __pyx_t_7 = __pyx_v_self->view.len; + __pyx_v_info->len = __pyx_t_7; - /* "View.MemoryView":434 + /* "View.MemoryView":550 + * info.itemsize = self.view.itemsize + * info.len = self.view.len + * info.readonly = self.view.readonly # <<<<<<<<<<<<<< + * info.obj = self * - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<< - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, */ - } + __pyx_t_1 = __pyx_v_self->view.readonly; + __pyx_v_info->readonly = __pyx_t_1; - /* "View.MemoryView":441 - * return None + /* "View.MemoryView":551 + * info.len = self.view.len + * info.readonly = self.view.readonly + * info.obj = self # <<<<<<<<<<<<<< * - * return obj # <<<<<<<<<<<<<< * - * cdef setitem_slice_assignment(self, dst, src): */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_obj); - __pyx_r = __pyx_v_obj; - goto __pyx_L0; + __Pyx_INCREF((PyObject *)__pyx_v_self); + __Pyx_GIVEREF((PyObject *)__pyx_v_self); + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); + __pyx_v_info->obj = ((PyObject *)__pyx_v_self); - /* "View.MemoryView":433 - * self.setitem_indexed(index, value) + /* "View.MemoryView":521 + * itemp[i] = c * - * cdef is_slice(self, obj): # <<<<<<<<<<<<<< - * if not isinstance(obj, memoryview): - * try: + * @cname('getbuffer') # <<<<<<<<<<<<<< + * def __getbuffer__(self, Py_buffer *info, int flags): + * if flags & PyBUF_WRITABLE and self.view.readonly: */ /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_AddTraceback("View.MemoryView.memoryview.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + if (__pyx_v_info->obj != NULL) { + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; + } + goto __pyx_L2; __pyx_L0:; - __Pyx_XDECREF(__pyx_v_obj); - __Pyx_XGIVEREF(__pyx_r); + if (__pyx_v_info->obj == Py_None) { + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; + } + __pyx_L2:; __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":443 - * return obj +/* "View.MemoryView":554 * - * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice dst_slice - * cdef __Pyx_memviewslice src_slice + * + * @property # <<<<<<<<<<<<<< + * def T(self): + * cdef _memoryviewslice result = memoryview_copy(self) */ -static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) { - __Pyx_memviewslice __pyx_v_dst_slice; - __Pyx_memviewslice __pyx_v_src_slice; +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) { + struct __pyx_memoryviewslice_obj *__pyx_v_result = 0; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - __Pyx_memviewslice *__pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("setitem_slice_assignment", 0); + __Pyx_RefNannySetupContext("__get__", 1); - /* "View.MemoryView":447 - * cdef __Pyx_memviewslice src_slice - * - * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<< - * get_slice_from_memview(dst, &dst_slice)[0], - * src.ndim, dst.ndim, self.dtype_is_object) + /* "View.MemoryView":556 + * @property + * def T(self): + * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<< + * transpose_memslice(&result.from_slice) + * return result */ - if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) __PYX_ERR(2, 447, __pyx_L1_error) - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(2, 447, __pyx_L1_error) + __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 556, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) __PYX_ERR(1, 556, __pyx_L1_error) + __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1); + __pyx_t_1 = 0; - /* "View.MemoryView":448 - * - * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], - * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<< - * src.ndim, dst.ndim, self.dtype_is_object) + /* "View.MemoryView":557 + * def T(self): + * cdef _memoryviewslice result = memoryview_copy(self) + * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<< + * return result * */ - if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) __PYX_ERR(2, 448, __pyx_L1_error) - __pyx_t_2 = __pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice)); if (unlikely(__pyx_t_2 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(2, 448, __pyx_L1_error) + __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(1, 557, __pyx_L1_error) - /* "View.MemoryView":449 - * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], - * get_slice_from_memview(dst, &dst_slice)[0], - * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<< + /* "View.MemoryView":558 + * cdef _memoryviewslice result = memoryview_copy(self) + * transpose_memslice(&result.from_slice) + * return result # <<<<<<<<<<<<<< * - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): + * @property */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 449, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 449, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 449, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 449, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF((PyObject *)__pyx_v_result); + __pyx_r = ((PyObject *)__pyx_v_result); + goto __pyx_L0; - /* "View.MemoryView":447 - * cdef __Pyx_memviewslice src_slice + /* "View.MemoryView":554 * - * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<< - * get_slice_from_memview(dst, &dst_slice)[0], - * src.ndim, dst.ndim, self.dtype_is_object) - */ - __pyx_t_6 = __pyx_memoryview_copy_contents((__pyx_t_1[0]), (__pyx_t_2[0]), __pyx_t_4, __pyx_t_5, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(2, 447, __pyx_L1_error) - - /* "View.MemoryView":443 - * return obj * - * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice dst_slice - * cdef __Pyx_memviewslice src_slice + * @property # <<<<<<<<<<<<<< + * def T(self): + * cdef _memoryviewslice result = memoryview_copy(self) */ /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_result); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":451 - * src.ndim, dst.ndim, self.dtype_is_object) +/* "View.MemoryView":560 + * return result * - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<< - * cdef int array[128] - * cdef void *tmp = NULL + * @property # <<<<<<<<<<<<<< + * def base(self): + * return self._get_base() */ -static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) { - int __pyx_v_array[0x80]; - void *__pyx_v_tmp; - void *__pyx_v_item; - __Pyx_memviewslice *__pyx_v_dst_slice; - __Pyx_memviewslice __pyx_v_tmp_slice; +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - int __pyx_t_5; - char const *__pyx_t_6; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_1 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0); + __Pyx_RefNannySetupContext("__get__", 1); - /* "View.MemoryView":453 - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): - * cdef int array[128] - * cdef void *tmp = NULL # <<<<<<<<<<<<<< - * cdef void *item + /* "View.MemoryView":562 + * @property + * def base(self): + * return self._get_base() # <<<<<<<<<<<<<< * + * cdef _get_base(self): */ - __pyx_v_tmp = NULL; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->_get_base(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 562, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; - /* "View.MemoryView":458 - * cdef __Pyx_memviewslice *dst_slice - * cdef __Pyx_memviewslice tmp_slice - * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<< + /* "View.MemoryView":560 + * return result * - * if self.view.itemsize > sizeof(array): + * @property # <<<<<<<<<<<<<< + * def base(self): + * return self._get_base() */ - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(2, 458, __pyx_L1_error) - __pyx_v_dst_slice = __pyx_t_1; - /* "View.MemoryView":460 - * dst_slice = get_slice_from_memview(dst, &tmp_slice) - * - * if self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<< - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: - */ - __pyx_t_2 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0); - if (__pyx_t_2) { + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("View.MemoryView.memoryview.base.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":461 +/* "View.MemoryView":564 + * return self._get_base() + * + * cdef _get_base(self): # <<<<<<<<<<<<<< + * return self.obj * - * if self.view.itemsize > sizeof(array): - * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<< - * if tmp == NULL: - * raise MemoryError */ - __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize); - /* "View.MemoryView":462 - * if self.view.itemsize > sizeof(array): - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: # <<<<<<<<<<<<<< - * raise MemoryError - * item = tmp - */ - __pyx_t_2 = ((__pyx_v_tmp == NULL) != 0); - if (unlikely(__pyx_t_2)) { +static PyObject *__pyx_memoryview__get_base(struct __pyx_memoryview_obj *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_get_base", 1); - /* "View.MemoryView":463 - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: - * raise MemoryError # <<<<<<<<<<<<<< - * item = tmp - * else: + /* "View.MemoryView":565 + * + * cdef _get_base(self): + * return self.obj # <<<<<<<<<<<<<< + * + * @property */ - PyErr_NoMemory(); __PYX_ERR(2, 463, __pyx_L1_error) + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->obj); + __pyx_r = __pyx_v_self->obj; + goto __pyx_L0; - /* "View.MemoryView":462 - * if self.view.itemsize > sizeof(array): - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: # <<<<<<<<<<<<<< - * raise MemoryError - * item = tmp + /* "View.MemoryView":564 + * return self._get_base() + * + * cdef _get_base(self): # <<<<<<<<<<<<<< + * return self.obj + * */ - } - /* "View.MemoryView":464 - * if tmp == NULL: - * raise MemoryError - * item = tmp # <<<<<<<<<<<<<< - * else: - * item = array - */ - __pyx_v_item = __pyx_v_tmp; + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":460 - * dst_slice = get_slice_from_memview(dst, &tmp_slice) +/* "View.MemoryView":567 + * return self.obj * - * if self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<< - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: + * @property # <<<<<<<<<<<<<< + * def shape(self): + * return tuple([length for length in self.view.shape[:self.view.ndim]]) */ - goto __pyx_L3; - } - /* "View.MemoryView":466 - * item = tmp - * else: - * item = array # <<<<<<<<<<<<<< - * - * try: - */ - /*else*/ { - __pyx_v_item = ((void *)__pyx_v_array); - } - __pyx_L3:; +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - /* "View.MemoryView":468 - * item = array + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) { + Py_ssize_t __pyx_7genexpr__pyx_v_length; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t *__pyx_t_2; + Py_ssize_t *__pyx_t_3; + Py_ssize_t *__pyx_t_4; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 1); + + /* "View.MemoryView":569 + * @property + * def shape(self): + * return tuple([length for length in self.view.shape[:self.view.ndim]]) # <<<<<<<<<<<<<< * - * try: # <<<<<<<<<<<<<< - * if self.dtype_is_object: - * ( item)[0] = value + * @property */ - /*try:*/ { + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 569, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = (__pyx_v_self->view.shape + __pyx_v_self->view.ndim); + for (__pyx_t_4 = __pyx_v_self->view.shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { + __pyx_t_2 = __pyx_t_4; + __pyx_7genexpr__pyx_v_length = (__pyx_t_2[0]); + __pyx_t_5 = PyInt_FromSsize_t(__pyx_7genexpr__pyx_v_length); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 569, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(1, 569, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + } /* exit inner scope */ + __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 569, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; - /* "View.MemoryView":469 + /* "View.MemoryView":567 + * return self.obj * - * try: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * ( item)[0] = value - * else: + * @property # <<<<<<<<<<<<<< + * def shape(self): + * return tuple([length for length in self.view.shape[:self.view.ndim]]) */ - __pyx_t_2 = (__pyx_v_self->dtype_is_object != 0); - if (__pyx_t_2) { - /* "View.MemoryView":470 - * try: - * if self.dtype_is_object: - * ( item)[0] = value # <<<<<<<<<<<<<< - * else: - * self.assign_item_from_object( item, value) - */ - (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value); + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":469 +/* "View.MemoryView":571 + * return tuple([length for length in self.view.shape[:self.view.ndim]]) * - * try: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * ( item)[0] = value - * else: + * @property # <<<<<<<<<<<<<< + * def strides(self): + * if self.view.strides == NULL: */ - goto __pyx_L8; - } - /* "View.MemoryView":472 - * ( item)[0] = value - * else: - * self.assign_item_from_object( item, value) # <<<<<<<<<<<<<< - * +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) { + Py_ssize_t __pyx_8genexpr1__pyx_v_stride; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t *__pyx_t_3; + Py_ssize_t *__pyx_t_4; + Py_ssize_t *__pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 1); + + /* "View.MemoryView":573 + * @property + * def strides(self): + * if self.view.strides == NULL: # <<<<<<<<<<<<<< * + * raise ValueError, "Buffer view does not expose strides" */ - /*else*/ { - __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 472, __pyx_L6_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_L8:; + __pyx_t_1 = (__pyx_v_self->view.strides == NULL); + if (unlikely(__pyx_t_1)) { - /* "View.MemoryView":476 + /* "View.MemoryView":575 + * if self.view.strides == NULL: * + * raise ValueError, "Buffer view does not expose strides" # <<<<<<<<<<<<<< * - * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<< - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, + * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) */ - __pyx_t_2 = ((__pyx_v_self->view.suboffsets != NULL) != 0); - if (__pyx_t_2) { + __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Buffer_view_does_not_expose_stri, 0, 0); + __PYX_ERR(1, 575, __pyx_L1_error) - /* "View.MemoryView":477 + /* "View.MemoryView":573 + * @property + * def strides(self): + * if self.view.strides == NULL: # <<<<<<<<<<<<<< * - * if self.view.suboffsets != NULL: - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<< - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, - * item, self.dtype_is_object) + * raise ValueError, "Buffer view does not expose strides" */ - __pyx_t_3 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 477, __pyx_L6_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } - /* "View.MemoryView":476 + /* "View.MemoryView":577 + * raise ValueError, "Buffer view does not expose strides" * + * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) # <<<<<<<<<<<<<< * - * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<< - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, + * @property */ + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 577, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = (__pyx_v_self->view.strides + __pyx_v_self->view.ndim); + for (__pyx_t_5 = __pyx_v_self->view.strides; __pyx_t_5 < __pyx_t_4; __pyx_t_5++) { + __pyx_t_3 = __pyx_t_5; + __pyx_8genexpr1__pyx_v_stride = (__pyx_t_3[0]); + __pyx_t_6 = PyInt_FromSsize_t(__pyx_8genexpr1__pyx_v_stride); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 577, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) __PYX_ERR(1, 577, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } + } /* exit inner scope */ + __pyx_t_6 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 577, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; - /* "View.MemoryView":478 - * if self.view.suboffsets != NULL: - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<< - * item, self.dtype_is_object) - * finally: - */ - __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object); - } - - /* "View.MemoryView":481 - * item, self.dtype_is_object) - * finally: - * PyMem_Free(tmp) # <<<<<<<<<<<<<< - * - * cdef setitem_indexed(self, index, value): - */ - /*finally:*/ { - /*normal exit:*/{ - PyMem_Free(__pyx_v_tmp); - goto __pyx_L7; - } - __pyx_L6_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9) < 0)) __Pyx_ErrFetch(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_9); - __Pyx_XGOTREF(__pyx_t_10); - __Pyx_XGOTREF(__pyx_t_11); - __Pyx_XGOTREF(__pyx_t_12); - __pyx_t_4 = __pyx_lineno; __pyx_t_5 = __pyx_clineno; __pyx_t_6 = __pyx_filename; - { - PyMem_Free(__pyx_v_tmp); - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_10); - __Pyx_XGIVEREF(__pyx_t_11); - __Pyx_XGIVEREF(__pyx_t_12); - __Pyx_ExceptionReset(__pyx_t_10, __pyx_t_11, __pyx_t_12); - } - __Pyx_XGIVEREF(__pyx_t_7); - __Pyx_XGIVEREF(__pyx_t_8); - __Pyx_XGIVEREF(__pyx_t_9); - __Pyx_ErrRestore(__pyx_t_7, __pyx_t_8, __pyx_t_9); - __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; - __pyx_lineno = __pyx_t_4; __pyx_clineno = __pyx_t_5; __pyx_filename = __pyx_t_6; - goto __pyx_L1_error; - } - __pyx_L7:; - } - - /* "View.MemoryView":451 - * src.ndim, dst.ndim, self.dtype_is_object) - * - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<< - * cdef int array[128] - * cdef void *tmp = NULL + /* "View.MemoryView":571 + * return tuple([length for length in self.view.shape[:self.view.ndim]]) + * + * @property # <<<<<<<<<<<<<< + * def strides(self): + * if self.view.strides == NULL: */ /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":483 - * PyMem_Free(tmp) +/* "View.MemoryView":579 + * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) * - * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<< - * cdef char *itemp = self.get_item_pointer(index) - * self.assign_item_from_object(itemp, value) + * @property # <<<<<<<<<<<<<< + * def suboffsets(self): + * if self.view.suboffsets == NULL: */ -static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { - char *__pyx_v_itemp; +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) { + Py_ssize_t __pyx_8genexpr2__pyx_v_suboffset; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - char *__pyx_t_1; + int __pyx_t_1; PyObject *__pyx_t_2 = NULL; + Py_ssize_t *__pyx_t_3; + Py_ssize_t *__pyx_t_4; + Py_ssize_t *__pyx_t_5; + PyObject *__pyx_t_6 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("setitem_indexed", 0); + __Pyx_RefNannySetupContext("__get__", 1); - /* "View.MemoryView":484 + /* "View.MemoryView":581 + * @property + * def suboffsets(self): + * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<< + * return (-1,) * self.view.ndim * - * cdef setitem_indexed(self, index, value): - * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<< - * self.assign_item_from_object(itemp, value) + */ + __pyx_t_1 = (__pyx_v_self->view.suboffsets == NULL); + if (__pyx_t_1) { + + /* "View.MemoryView":582 + * def suboffsets(self): + * if self.view.suboffsets == NULL: + * return (-1,) * self.view.ndim # <<<<<<<<<<<<<< * + * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) */ - __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == ((char *)NULL))) __PYX_ERR(2, 484, __pyx_L1_error) - __pyx_v_itemp = __pyx_t_1; + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __Pyx_PySequence_Multiply(__pyx_tuple__4, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 582, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; - /* "View.MemoryView":485 - * cdef setitem_indexed(self, index, value): - * cdef char *itemp = self.get_item_pointer(index) - * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<< + /* "View.MemoryView":581 + * @property + * def suboffsets(self): + * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<< + * return (-1,) * self.view.ndim * - * cdef convert_item_to_object(self, char *itemp): */ - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 485, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + } + + /* "View.MemoryView":584 + * return (-1,) * self.view.ndim + * + * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) # <<<<<<<<<<<<<< + * + * @property + */ + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 584, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = (__pyx_v_self->view.suboffsets + __pyx_v_self->view.ndim); + for (__pyx_t_5 = __pyx_v_self->view.suboffsets; __pyx_t_5 < __pyx_t_4; __pyx_t_5++) { + __pyx_t_3 = __pyx_t_5; + __pyx_8genexpr2__pyx_v_suboffset = (__pyx_t_3[0]); + __pyx_t_6 = PyInt_FromSsize_t(__pyx_8genexpr2__pyx_v_suboffset); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 584, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) __PYX_ERR(1, 584, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + } /* exit inner scope */ + __pyx_t_6 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 584, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; - /* "View.MemoryView":483 - * PyMem_Free(tmp) + /* "View.MemoryView":579 + * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) * - * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<< - * cdef char *itemp = self.get_item_pointer(index) - * self.assign_item_from_object(itemp, value) + * @property # <<<<<<<<<<<<<< + * def suboffsets(self): + * if self.view.suboffsets == NULL: */ /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":487 - * self.assign_item_from_object(itemp, value) +/* "View.MemoryView":586 + * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" + * @property # <<<<<<<<<<<<<< + * def ndim(self): + * return self.view.ndim */ -static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) { - PyObject *__pyx_v_struct = NULL; - PyObject *__pyx_v_bytesitem = 0; - PyObject *__pyx_v_result = NULL; +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - PyObject *__pyx_t_9 = NULL; - size_t __pyx_t_10; - int __pyx_t_11; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("convert_item_to_object", 0); + __Pyx_RefNannySetupContext("__get__", 1); - /* "View.MemoryView":490 - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - * import struct # <<<<<<<<<<<<<< - * cdef bytes bytesitem + /* "View.MemoryView":588 + * @property + * def ndim(self): + * return self.view.ndim # <<<<<<<<<<<<<< * + * @property */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 490, __pyx_L1_error) + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 588, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_v_struct = __pyx_t_1; + __pyx_r = __pyx_t_1; __pyx_t_1 = 0; + goto __pyx_L0; - /* "View.MemoryView":493 - * cdef bytes bytesitem + /* "View.MemoryView":586 + * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) * - * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<< - * try: - * result = struct.unpack(self.view.format, bytesitem) + * @property # <<<<<<<<<<<<<< + * def ndim(self): + * return self.view.ndim */ - __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 493, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_bytesitem = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - /* "View.MemoryView":494 + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "View.MemoryView":590 + * return self.view.ndim * - * bytesitem = itemp[:self.view.itemsize] - * try: # <<<<<<<<<<<<<< - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: + * @property # <<<<<<<<<<<<<< + * def itemsize(self): + * return self.view.itemsize */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - /* "View.MemoryView":495 - * bytesitem = itemp[:self.view.itemsize] - * try: - * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<< - * except struct.error: - * raise ValueError("Unable to convert item to object") - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 495, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 495, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = NULL; - __pyx_t_8 = 0; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_7)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_7); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - __pyx_t_8 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_5)) { - PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_t_6, __pyx_v_bytesitem}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 495, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) { - PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_t_6, __pyx_v_bytesitem}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 495, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - { - __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 495, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_9); - if (__pyx_t_7) { - __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL; - } - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6); - __Pyx_INCREF(__pyx_v_bytesitem); - __Pyx_GIVEREF(__pyx_v_bytesitem); - PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem); - __pyx_t_6 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 495, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_result = __pyx_t_1; - __pyx_t_1 = 0; +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - /* "View.MemoryView":494 - * - * bytesitem = itemp[:self.view.itemsize] - * try: # <<<<<<<<<<<<<< - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - */ - } + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":499 - * raise ValueError("Unable to convert item to object") - * else: - * if len(self.view.format) == 1: # <<<<<<<<<<<<<< - * return result[0] - * return result - */ - /*else:*/ { - __pyx_t_10 = strlen(__pyx_v_self->view.format); - __pyx_t_11 = ((__pyx_t_10 == 1) != 0); - if (__pyx_t_11) { +static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 1); - /* "View.MemoryView":500 - * else: - * if len(self.view.format) == 1: - * return result[0] # <<<<<<<<<<<<<< - * return result + /* "View.MemoryView":592 + * @property + * def itemsize(self): + * return self.view.itemsize # <<<<<<<<<<<<<< * + * @property */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 500, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L6_except_return; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 592, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; - /* "View.MemoryView":499 - * raise ValueError("Unable to convert item to object") - * else: - * if len(self.view.format) == 1: # <<<<<<<<<<<<<< - * return result[0] - * return result + /* "View.MemoryView":590 + * return self.view.ndim + * + * @property # <<<<<<<<<<<<<< + * def itemsize(self): + * return self.view.itemsize */ - } - /* "View.MemoryView":501 - * if len(self.view.format) == 1: - * return result[0] - * return result # <<<<<<<<<<<<<< + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "View.MemoryView":594 + * return self.view.itemsize * - * cdef assign_item_from_object(self, char *itemp, object value): + * @property # <<<<<<<<<<<<<< + * def nbytes(self): + * return self.size * self.view.itemsize */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_result); - __pyx_r = __pyx_v_result; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - /* "View.MemoryView":496 - * try: - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: # <<<<<<<<<<<<<< - * raise ValueError("Unable to convert item to object") - * else: - */ - __Pyx_ErrFetch(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 496, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_8 = __Pyx_PyErr_GivenExceptionMatches(__pyx_t_1, __pyx_t_6); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_ErrRestore(__pyx_t_1, __pyx_t_5, __pyx_t_9); - __pyx_t_1 = 0; __pyx_t_5 = 0; __pyx_t_9 = 0; - if (__pyx_t_8) { - __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_9, &__pyx_t_5, &__pyx_t_1) < 0) __PYX_ERR(2, 496, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_1); +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - /* "View.MemoryView":497 - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<< - * else: - * if len(self.view.format) == 1: - */ - __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 497, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_Raise(__pyx_t_6, 0, 0, 0); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __PYX_ERR(2, 497, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 1); - /* "View.MemoryView":494 + /* "View.MemoryView":596 + * @property + * def nbytes(self): + * return self.size * self.view.itemsize # <<<<<<<<<<<<<< * - * bytesitem = itemp[:self.view.itemsize] - * try: # <<<<<<<<<<<<<< - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: + * @property */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 596, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 596, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 596, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; - /* "View.MemoryView":487 - * self.assign_item_from_object(itemp, value) + /* "View.MemoryView":594 + * return self.view.itemsize * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" + * @property # <<<<<<<<<<<<<< + * def nbytes(self): + * return self.size * self.view.itemsize */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; - __Pyx_XDECREF(__pyx_v_struct); - __Pyx_XDECREF(__pyx_v_bytesitem); - __Pyx_XDECREF(__pyx_v_result); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":503 - * return result +/* "View.MemoryView":598 + * return self.size * self.view.itemsize * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" + * @property # <<<<<<<<<<<<<< + * def size(self): + * if self._size is None: */ -static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) { - PyObject *__pyx_v_struct = NULL; - char __pyx_v_c; - PyObject *__pyx_v_bytesvalue = 0; - Py_ssize_t __pyx_v_i; +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) { + PyObject *__pyx_v_result = NULL; + PyObject *__pyx_v_length = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_t_3; - PyObject *__pyx_t_4 = NULL; + int __pyx_t_1; + Py_ssize_t *__pyx_t_2; + Py_ssize_t *__pyx_t_3; + Py_ssize_t *__pyx_t_4; PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; - PyObject *__pyx_t_8 = NULL; - Py_ssize_t __pyx_t_9; - PyObject *__pyx_t_10 = NULL; - char *__pyx_t_11; - char *__pyx_t_12; - char *__pyx_t_13; - char *__pyx_t_14; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("assign_item_from_object", 0); - - /* "View.MemoryView":506 - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - * import struct # <<<<<<<<<<<<<< - * cdef char c - * cdef bytes bytesvalue - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 506, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_struct = __pyx_t_1; - __pyx_t_1 = 0; + __Pyx_RefNannySetupContext("__get__", 1); - /* "View.MemoryView":511 - * cdef Py_ssize_t i + /* "View.MemoryView":600 + * @property + * def size(self): + * if self._size is None: # <<<<<<<<<<<<<< + * result = 1 * - * if isinstance(value, tuple): # <<<<<<<<<<<<<< - * bytesvalue = struct.pack(self.view.format, *value) - * else: */ - __pyx_t_2 = PyTuple_Check(__pyx_v_value); - __pyx_t_3 = (__pyx_t_2 != 0); - if (__pyx_t_3) { + __pyx_t_1 = (__pyx_v_self->_size == Py_None); + if (__pyx_t_1) { - /* "View.MemoryView":512 + /* "View.MemoryView":601 + * def size(self): + * if self._size is None: + * result = 1 # <<<<<<<<<<<<<< * - * if isinstance(value, tuple): - * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<< - * else: - * bytesvalue = struct.pack(self.view.format, value) + * for length in self.view.shape[:self.view.ndim]: */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); - __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||((void)PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) __PYX_ERR(2, 512, __pyx_L1_error) - __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4); - __pyx_t_4 = 0; + __Pyx_INCREF(__pyx_int_1); + __pyx_v_result = __pyx_int_1; - /* "View.MemoryView":511 - * cdef Py_ssize_t i + /* "View.MemoryView":603 + * result = 1 * - * if isinstance(value, tuple): # <<<<<<<<<<<<<< - * bytesvalue = struct.pack(self.view.format, *value) - * else: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":514 - * bytesvalue = struct.pack(self.view.format, *value) - * else: - * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<< + * for length in self.view.shape[:self.view.ndim]: # <<<<<<<<<<<<<< + * result *= length * - * for i, c in enumerate(bytesvalue): */ - /*else*/ { - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 514, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 514, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = NULL; - __pyx_t_7 = 0; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_6, function); - __pyx_t_7 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_6)) { - PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_1, __pyx_v_value}; - __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 514, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) { - PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_1, __pyx_v_value}; - __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 514, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } else - #endif - { - __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 514, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - if (__pyx_t_5) { - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL; - } - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1); - __Pyx_INCREF(__pyx_v_value); - __Pyx_GIVEREF(__pyx_v_value); - PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value); - __pyx_t_1 = 0; - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 514, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - } - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||((void)PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) __PYX_ERR(2, 514, __pyx_L1_error) - __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4); - __pyx_t_4 = 0; - } - __pyx_L3:; + __pyx_t_3 = (__pyx_v_self->view.shape + __pyx_v_self->view.ndim); + for (__pyx_t_4 = __pyx_v_self->view.shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { + __pyx_t_2 = __pyx_t_4; + __pyx_t_5 = PyInt_FromSsize_t((__pyx_t_2[0])); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 603, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_5); + __pyx_t_5 = 0; - /* "View.MemoryView":516 - * bytesvalue = struct.pack(self.view.format, value) + /* "View.MemoryView":604 * - * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<< - * itemp[i] = c + * for length in self.view.shape[:self.view.ndim]: + * result *= length # <<<<<<<<<<<<<< * + * self._size = result */ - __pyx_t_9 = 0; - if (unlikely(__pyx_v_bytesvalue == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable"); - __PYX_ERR(2, 516, __pyx_L1_error) - } - __Pyx_INCREF(__pyx_v_bytesvalue); - __pyx_t_10 = __pyx_v_bytesvalue; - __pyx_t_12 = PyBytes_AS_STRING(__pyx_t_10); - __pyx_t_13 = (__pyx_t_12 + PyBytes_GET_SIZE(__pyx_t_10)); - for (__pyx_t_14 = __pyx_t_12; __pyx_t_14 < __pyx_t_13; __pyx_t_14++) { - __pyx_t_11 = __pyx_t_14; - __pyx_v_c = (__pyx_t_11[0]); + __pyx_t_5 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 604, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_5); + __pyx_t_5 = 0; + } - /* "View.MemoryView":517 + /* "View.MemoryView":606 + * result *= length * - * for i, c in enumerate(bytesvalue): - * itemp[i] = c # <<<<<<<<<<<<<< + * self._size = result # <<<<<<<<<<<<<< * - * @cname('getbuffer') + * return self._size */ - __pyx_v_i = __pyx_t_9; + __Pyx_INCREF(__pyx_v_result); + __Pyx_GIVEREF(__pyx_v_result); + __Pyx_GOTREF(__pyx_v_self->_size); + __Pyx_DECREF(__pyx_v_self->_size); + __pyx_v_self->_size = __pyx_v_result; - /* "View.MemoryView":516 - * bytesvalue = struct.pack(self.view.format, value) - * - * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<< - * itemp[i] = c + /* "View.MemoryView":600 + * @property + * def size(self): + * if self._size is None: # <<<<<<<<<<<<<< + * result = 1 * */ - __pyx_t_9 = (__pyx_t_9 + 1); + } - /* "View.MemoryView":517 + /* "View.MemoryView":608 + * self._size = result * - * for i, c in enumerate(bytesvalue): - * itemp[i] = c # <<<<<<<<<<<<<< + * return self._size # <<<<<<<<<<<<<< * - * @cname('getbuffer') + * def __len__(self): */ - (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c; - } - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->_size); + __pyx_r = __pyx_v_self->_size; + goto __pyx_L0; - /* "View.MemoryView":503 - * return result + /* "View.MemoryView":598 + * return self.size * self.view.itemsize * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" + * @property # <<<<<<<<<<<<<< + * def size(self): + * if self._size is None: */ /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; + __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; - __Pyx_XDECREF(__pyx_v_struct); - __Pyx_XDECREF(__pyx_v_bytesvalue); + __Pyx_XDECREF(__pyx_v_result); + __Pyx_XDECREF(__pyx_v_length); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":520 +/* "View.MemoryView":610 + * return self._size * - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< - * if flags & PyBUF_WRITABLE and self.view.readonly: - * raise ValueError("Cannot create writable memory view from read-only memoryview") + * def __len__(self): # <<<<<<<<<<<<<< + * if self.view.ndim >= 1: + * return self.view.shape[0] */ /* Python wrapper */ -static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_r; +static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/ +static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + Py_ssize_t __pyx_r; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); + __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_r; - __Pyx_RefNannyDeclarations +static Py_ssize_t __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) { + Py_ssize_t __pyx_r; int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - Py_ssize_t *__pyx_t_4; - char *__pyx_t_5; - void *__pyx_t_6; - int __pyx_t_7; - Py_ssize_t __pyx_t_8; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - if (__pyx_v_info == NULL) { - PyErr_SetString(PyExc_BufferError, "PyObject_GetBuffer: view==NULL argument is obsolete"); - return -1; - } - __Pyx_RefNannySetupContext("__getbuffer__", 0); - __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(__pyx_v_info->obj); - /* "View.MemoryView":521 - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: # <<<<<<<<<<<<<< - * raise ValueError("Cannot create writable memory view from read-only memoryview") + /* "View.MemoryView":611 + * + * def __len__(self): + * if self.view.ndim >= 1: # <<<<<<<<<<<<<< + * return self.view.shape[0] * */ - __pyx_t_2 = ((__pyx_v_flags & PyBUF_WRITABLE) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = (__pyx_v_self->view.readonly != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - if (unlikely(__pyx_t_1)) { + __pyx_t_1 = (__pyx_v_self->view.ndim >= 1); + if (__pyx_t_1) { - /* "View.MemoryView":522 - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: - * raise ValueError("Cannot create writable memory view from read-only memoryview") # <<<<<<<<<<<<<< + /* "View.MemoryView":612 + * def __len__(self): + * if self.view.ndim >= 1: + * return self.view.shape[0] # <<<<<<<<<<<<<< * - * if flags & PyBUF_ND: + * return 0 */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 522, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 522, __pyx_L1_error) + __pyx_r = (__pyx_v_self->view.shape[0]); + goto __pyx_L0; - /* "View.MemoryView":521 - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: # <<<<<<<<<<<<<< - * raise ValueError("Cannot create writable memory view from read-only memoryview") + /* "View.MemoryView":611 + * + * def __len__(self): + * if self.view.ndim >= 1: # <<<<<<<<<<<<<< + * return self.view.shape[0] * */ } - /* "View.MemoryView":524 - * raise ValueError("Cannot create writable memory view from read-only memoryview") + /* "View.MemoryView":614 + * return self.view.shape[0] * - * if flags & PyBUF_ND: # <<<<<<<<<<<<<< - * info.shape = self.view.shape - * else: + * return 0 # <<<<<<<<<<<<<< + * + * def __repr__(self): */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_ND) != 0); - if (__pyx_t_1) { + __pyx_r = 0; + goto __pyx_L0; - /* "View.MemoryView":525 + /* "View.MemoryView":610 + * return self._size * - * if flags & PyBUF_ND: - * info.shape = self.view.shape # <<<<<<<<<<<<<< - * else: - * info.shape = NULL + * def __len__(self): # <<<<<<<<<<<<<< + * if self.view.ndim >= 1: + * return self.view.shape[0] */ - __pyx_t_4 = __pyx_v_self->view.shape; - __pyx_v_info->shape = __pyx_t_4; - /* "View.MemoryView":524 - * raise ValueError("Cannot create writable memory view from read-only memoryview") + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "View.MemoryView":616 + * return 0 * - * if flags & PyBUF_ND: # <<<<<<<<<<<<<< - * info.shape = self.view.shape - * else: + * def __repr__(self): # <<<<<<<<<<<<<< + * return "" % (self.base.__class__.__name__, + * id(self)) */ - goto __pyx_L6; - } - /* "View.MemoryView":527 - * info.shape = self.view.shape - * else: - * info.shape = NULL # <<<<<<<<<<<<<< - * - * if flags & PyBUF_STRIDES: - */ - /*else*/ { - __pyx_v_info->shape = NULL; - } - __pyx_L6:; - - /* "View.MemoryView":529 - * info.shape = NULL - * - * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< - * info.strides = self.view.strides - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":530 - * - * if flags & PyBUF_STRIDES: - * info.strides = self.view.strides # <<<<<<<<<<<<<< - * else: - * info.strides = NULL - */ - __pyx_t_4 = __pyx_v_self->view.strides; - __pyx_v_info->strides = __pyx_t_4; - - /* "View.MemoryView":529 - * info.shape = NULL - * - * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< - * info.strides = self.view.strides - * else: - */ - goto __pyx_L7; - } - - /* "View.MemoryView":532 - * info.strides = self.view.strides - * else: - * info.strides = NULL # <<<<<<<<<<<<<< - * - * if flags & PyBUF_INDIRECT: - */ - /*else*/ { - __pyx_v_info->strides = NULL; - } - __pyx_L7:; - - /* "View.MemoryView":534 - * info.strides = NULL - * - * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<< - * info.suboffsets = self.view.suboffsets - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":535 - * - * if flags & PyBUF_INDIRECT: - * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<< - * else: - * info.suboffsets = NULL - */ - __pyx_t_4 = __pyx_v_self->view.suboffsets; - __pyx_v_info->suboffsets = __pyx_t_4; - - /* "View.MemoryView":534 - * info.strides = NULL - * - * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<< - * info.suboffsets = self.view.suboffsets - * else: - */ - goto __pyx_L8; - } - - /* "View.MemoryView":537 - * info.suboffsets = self.view.suboffsets - * else: - * info.suboffsets = NULL # <<<<<<<<<<<<<< - * - * if flags & PyBUF_FORMAT: - */ - /*else*/ { - __pyx_v_info->suboffsets = NULL; - } - __pyx_L8:; - - /* "View.MemoryView":539 - * info.suboffsets = NULL - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * info.format = self.view.format - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); - if (__pyx_t_1) { +/* Python wrapper */ +static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - /* "View.MemoryView":540 - * - * if flags & PyBUF_FORMAT: - * info.format = self.view.format # <<<<<<<<<<<<<< - * else: - * info.format = NULL - */ - __pyx_t_5 = __pyx_v_self->view.format; - __pyx_v_info->format = __pyx_t_5; + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":539 - * info.suboffsets = NULL - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * info.format = self.view.format - * else: - */ - goto __pyx_L9; - } +static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__repr__", 1); - /* "View.MemoryView":542 - * info.format = self.view.format - * else: - * info.format = NULL # <<<<<<<<<<<<<< + /* "View.MemoryView":617 * - * info.buf = self.view.buf - */ - /*else*/ { - __pyx_v_info->format = NULL; - } - __pyx_L9:; - - /* "View.MemoryView":544 - * info.format = NULL + * def __repr__(self): + * return "" % (self.base.__class__.__name__, # <<<<<<<<<<<<<< + * id(self)) * - * info.buf = self.view.buf # <<<<<<<<<<<<<< - * info.ndim = self.view.ndim - * info.itemsize = self.view.itemsize */ - __pyx_t_6 = __pyx_v_self->view.buf; - __pyx_v_info->buf = __pyx_t_6; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 617, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 617, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 617, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "View.MemoryView":545 + /* "View.MemoryView":618 + * def __repr__(self): + * return "" % (self.base.__class__.__name__, + * id(self)) # <<<<<<<<<<<<<< * - * info.buf = self.view.buf - * info.ndim = self.view.ndim # <<<<<<<<<<<<<< - * info.itemsize = self.view.itemsize - * info.len = self.view.len - */ - __pyx_t_7 = __pyx_v_self->view.ndim; - __pyx_v_info->ndim = __pyx_t_7; - - /* "View.MemoryView":546 - * info.buf = self.view.buf - * info.ndim = self.view.ndim - * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<< - * info.len = self.view.len - * info.readonly = self.view.readonly - */ - __pyx_t_8 = __pyx_v_self->view.itemsize; - __pyx_v_info->itemsize = __pyx_t_8; - - /* "View.MemoryView":547 - * info.ndim = self.view.ndim - * info.itemsize = self.view.itemsize - * info.len = self.view.len # <<<<<<<<<<<<<< - * info.readonly = self.view.readonly - * info.obj = self + * def __str__(self): */ - __pyx_t_8 = __pyx_v_self->view.len; - __pyx_v_info->len = __pyx_t_8; + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 618, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); - /* "View.MemoryView":548 - * info.itemsize = self.view.itemsize - * info.len = self.view.len - * info.readonly = self.view.readonly # <<<<<<<<<<<<<< - * info.obj = self + /* "View.MemoryView":617 * - */ - __pyx_t_1 = __pyx_v_self->view.readonly; - __pyx_v_info->readonly = __pyx_t_1; - - /* "View.MemoryView":549 - * info.len = self.view.len - * info.readonly = self.view.readonly - * info.obj = self # <<<<<<<<<<<<<< + * def __repr__(self): + * return "" % (self.base.__class__.__name__, # <<<<<<<<<<<<<< + * id(self)) * - * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") */ - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); - __pyx_v_info->obj = ((PyObject *)__pyx_v_self); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 617, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(1, 617, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2)) __PYX_ERR(1, 617, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 617, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; - /* "View.MemoryView":520 + /* "View.MemoryView":616 + * return 0 * - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< - * if flags & PyBUF_WRITABLE and self.view.readonly: - * raise ValueError("Cannot create writable memory view from read-only memoryview") + * def __repr__(self): # <<<<<<<<<<<<<< + * return "" % (self.base.__class__.__name__, + * id(self)) */ /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - if (__pyx_v_info->obj != NULL) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - goto __pyx_L2; + __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; - if (__pyx_v_info->obj == Py_None) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":555 +/* "View.MemoryView":620 + * id(self)) + * + * def __str__(self): # <<<<<<<<<<<<<< + * return "" % (self.base.__class__.__name__,) * - * @property - * def T(self): # <<<<<<<<<<<<<< - * cdef _memoryviewslice result = memoryview_copy(self) - * transpose_memslice(&result.from_slice) */ /* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(PyObject *__pyx_v_self) { +static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - struct __pyx_memoryviewslice_obj *__pyx_v_result = 0; +static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; + PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_RefNannySetupContext("__str__", 1); - /* "View.MemoryView":556 - * @property - * def T(self): - * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<< - * transpose_memslice(&result.from_slice) - * return result - */ - __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 556, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) __PYX_ERR(2, 556, __pyx_L1_error) - __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "View.MemoryView":557 - * def T(self): - * cdef _memoryviewslice result = memoryview_copy(self) - * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<< - * return result + /* "View.MemoryView":621 + * + * def __str__(self): + * return "" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<< * - */ - __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 557, __pyx_L1_error) - - /* "View.MemoryView":558 - * cdef _memoryviewslice result = memoryview_copy(self) - * transpose_memslice(&result.from_slice) - * return result # <<<<<<<<<<<<<< * - * @property */ __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_result)); - __pyx_r = ((PyObject *)__pyx_v_result); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 621, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 621, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 621, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 621, __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(1, 621, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 621, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; goto __pyx_L0; - /* "View.MemoryView":555 + /* "View.MemoryView":620 + * id(self)) + * + * def __str__(self): # <<<<<<<<<<<<<< + * return "" % (self.base.__class__.__name__,) * - * @property - * def T(self): # <<<<<<<<<<<<<< - * cdef _memoryviewslice result = memoryview_copy(self) - * transpose_memslice(&result.from_slice) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":561 +/* "View.MemoryView":624 * - * @property - * def base(self): # <<<<<<<<<<<<<< - * return self.obj * + * def is_c_contig(self): # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice *mslice + * cdef __Pyx_memviewslice tmp */ /* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(PyObject *__pyx_v_self) { +static PyObject *__pyx_memoryview_is_c_contig(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*/ +static PyObject *__pyx_memoryview_is_c_contig(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 +) { + #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("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + __Pyx_RefNannySetupContext("is_c_contig (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); + if (unlikely(__pyx_nargs > 0)) { + __Pyx_RaiseArgtupleInvalid("is_c_contig", 1, 0, 0, __pyx_nargs); return NULL;} + if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "is_c_contig", 0))) return NULL; + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) { +static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) { + __Pyx_memviewslice *__pyx_v_mslice; + __Pyx_memviewslice __pyx_v_tmp; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_memviewslice *__pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("is_c_contig", 1); - /* "View.MemoryView":562 - * @property - * def base(self): - * return self.obj # <<<<<<<<<<<<<< + /* "View.MemoryView":627 + * cdef __Pyx_memviewslice *mslice + * cdef __Pyx_memviewslice tmp + * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<< + * return slice_is_contig(mslice[0], 'C', self.view.ndim) * - * @property + */ + __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(1, 627, __pyx_L1_error) + __pyx_v_mslice = __pyx_t_1; + + /* "View.MemoryView":628 + * cdef __Pyx_memviewslice tmp + * mslice = get_slice_from_memview(self, &tmp) + * return slice_is_contig(mslice[0], 'C', self.view.ndim) # <<<<<<<<<<<<<< + * + * def is_f_contig(self): */ __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->obj); - __pyx_r = __pyx_v_self->obj; + __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig((__pyx_v_mslice[0]), 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 628, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; goto __pyx_L0; - /* "View.MemoryView":561 + /* "View.MemoryView":624 * - * @property - * def base(self): # <<<<<<<<<<<<<< - * return self.obj * + * def is_c_contig(self): # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice *mslice + * cdef __Pyx_memviewslice tmp */ /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":565 - * - * @property - * def shape(self): # <<<<<<<<<<<<<< - * return tuple([length for length in self.view.shape[:self.view.ndim]]) +/* "View.MemoryView":630 + * return slice_is_contig(mslice[0], 'C', self.view.ndim) * + * def is_f_contig(self): # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice *mslice + * cdef __Pyx_memviewslice tmp */ /* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(PyObject *__pyx_v_self) { +static PyObject *__pyx_memoryview_is_f_contig(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*/ +static PyObject *__pyx_memoryview_is_f_contig(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 +) { + #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("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + __Pyx_RefNannySetupContext("is_f_contig (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); + if (unlikely(__pyx_nargs > 0)) { + __Pyx_RaiseArgtupleInvalid("is_f_contig", 1, 0, 0, __pyx_nargs); return NULL;} + if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "is_f_contig", 0))) return NULL; + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_v_length; +static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) { + __Pyx_memviewslice *__pyx_v_mslice; + __Pyx_memviewslice __pyx_v_tmp; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t *__pyx_t_2; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - PyObject *__pyx_t_5 = NULL; + __Pyx_memviewslice *__pyx_t_1; + PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_RefNannySetupContext("is_f_contig", 1); - /* "View.MemoryView":566 - * @property - * def shape(self): - * return tuple([length for length in self.view.shape[:self.view.ndim]]) # <<<<<<<<<<<<<< + /* "View.MemoryView":633 + * cdef __Pyx_memviewslice *mslice + * cdef __Pyx_memviewslice tmp + * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<< + * return slice_is_contig(mslice[0], 'F', self.view.ndim) * - * @property + */ + __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(1, 633, __pyx_L1_error) + __pyx_v_mslice = __pyx_t_1; + + /* "View.MemoryView":634 + * cdef __Pyx_memviewslice tmp + * mslice = get_slice_from_memview(self, &tmp) + * return slice_is_contig(mslice[0], 'F', self.view.ndim) # <<<<<<<<<<<<<< + * + * def copy(self): */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 566, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = (__pyx_v_self->view.shape + __pyx_v_self->view.ndim); - for (__pyx_t_4 = __pyx_v_self->view.shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { - __pyx_t_2 = __pyx_t_4; - __pyx_v_length = (__pyx_t_2[0]); - __pyx_t_5 = PyInt_FromSsize_t(__pyx_v_length); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 566, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(2, 566, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 566, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; + __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig((__pyx_v_mslice[0]), 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 634, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; goto __pyx_L0; - /* "View.MemoryView":565 - * - * @property - * def shape(self): # <<<<<<<<<<<<<< - * return tuple([length for length in self.view.shape[:self.view.ndim]]) + /* "View.MemoryView":630 + * return slice_is_contig(mslice[0], 'C', self.view.ndim) * + * def is_f_contig(self): # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice *mslice + * cdef __Pyx_memviewslice tmp */ /* function exit code */ __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); @@ -9647,113 +11151,120 @@ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(stru return __pyx_r; } -/* "View.MemoryView":569 - * - * @property - * def strides(self): # <<<<<<<<<<<<<< - * if self.view.strides == NULL: +/* "View.MemoryView":636 + * return slice_is_contig(mslice[0], 'F', self.view.ndim) * + * def copy(self): # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice mslice + * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS */ /* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(PyObject *__pyx_v_self) { +static PyObject *__pyx_memoryview_copy(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*/ +static PyObject *__pyx_memoryview_copy(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 +) { + #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("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + __Pyx_RefNannySetupContext("copy (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); + if (unlikely(__pyx_nargs > 0)) { + __Pyx_RaiseArgtupleInvalid("copy", 1, 0, 0, __pyx_nargs); return NULL;} + if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "copy", 0))) return NULL; + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_v_stride; +static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) { + __Pyx_memviewslice __pyx_v_mslice; + int __pyx_v_flags; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - int __pyx_t_1; + __Pyx_memviewslice __pyx_t_1; PyObject *__pyx_t_2 = NULL; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - Py_ssize_t *__pyx_t_5; - PyObject *__pyx_t_6 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_RefNannySetupContext("copy", 1); - /* "View.MemoryView":570 - * @property - * def strides(self): - * if self.view.strides == NULL: # <<<<<<<<<<<<<< + /* "View.MemoryView":638 + * def copy(self): + * cdef __Pyx_memviewslice mslice + * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<< * - * raise ValueError("Buffer view does not expose strides") + * slice_copy(self, &mslice) */ - __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0); - if (unlikely(__pyx_t_1)) { + __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS)); - /* "View.MemoryView":572 - * if self.view.strides == NULL: - * - * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<< + /* "View.MemoryView":640 + * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS * - * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) + * slice_copy(self, &mslice) # <<<<<<<<<<<<<< + * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, + * self.view.itemsize, */ - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 572, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(2, 572, __pyx_L1_error) + __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice)); - /* "View.MemoryView":570 - * @property - * def strides(self): - * if self.view.strides == NULL: # <<<<<<<<<<<<<< + /* "View.MemoryView":641 * - * raise ValueError("Buffer view does not expose strides") + * slice_copy(self, &mslice) + * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<< + * self.view.itemsize, + * flags|PyBUF_C_CONTIGUOUS, */ - } + __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), ((char *)"c"), __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 641, __pyx_L1_error) + __pyx_v_mslice = __pyx_t_1; - /* "View.MemoryView":574 - * raise ValueError("Buffer view does not expose strides") + /* "View.MemoryView":646 + * self.dtype_is_object) * - * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) # <<<<<<<<<<<<<< + * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<< * - * @property + * def copy_fortran(self): */ __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 574, __pyx_L1_error) + __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 646, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = (__pyx_v_self->view.strides + __pyx_v_self->view.ndim); - for (__pyx_t_5 = __pyx_v_self->view.strides; __pyx_t_5 < __pyx_t_4; __pyx_t_5++) { - __pyx_t_3 = __pyx_t_5; - __pyx_v_stride = (__pyx_t_3[0]); - __pyx_t_6 = PyInt_FromSsize_t(__pyx_v_stride); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 574, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) __PYX_ERR(2, 574, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - __pyx_t_6 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 574, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_6; - __pyx_t_6 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; goto __pyx_L0; - /* "View.MemoryView":569 - * - * @property - * def strides(self): # <<<<<<<<<<<<<< - * if self.view.strides == NULL: + /* "View.MemoryView":636 + * return slice_is_contig(mslice[0], 'F', self.view.ndim) * + * def copy(self): # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice mslice + * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); @@ -9761,117 +11272,121 @@ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(st return __pyx_r; } -/* "View.MemoryView":577 +/* "View.MemoryView":648 + * return memoryview_copy_from_slice(self, &mslice) * - * @property - * def suboffsets(self): # <<<<<<<<<<<<<< - * if self.view.suboffsets == NULL: - * return (-1,) * self.view.ndim + * def copy_fortran(self): # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice src, dst + * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS */ /* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(PyObject *__pyx_v_self) { +static PyObject *__pyx_memoryview_copy_fortran(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*/ +static PyObject *__pyx_memoryview_copy_fortran(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 +) { + #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("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + __Pyx_RefNannySetupContext("copy_fortran (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); + if (unlikely(__pyx_nargs > 0)) { + __Pyx_RaiseArgtupleInvalid("copy_fortran", 1, 0, 0, __pyx_nargs); return NULL;} + if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "copy_fortran", 0))) return NULL; + __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_v_suboffset; +static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) { + __Pyx_memviewslice __pyx_v_src; + __Pyx_memviewslice __pyx_v_dst; + int __pyx_v_flags; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - int __pyx_t_1; + __Pyx_memviewslice __pyx_t_1; PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - Py_ssize_t *__pyx_t_4; - Py_ssize_t *__pyx_t_5; - Py_ssize_t *__pyx_t_6; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_RefNannySetupContext("copy_fortran", 1); - /* "View.MemoryView":578 - * @property - * def suboffsets(self): - * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<< - * return (-1,) * self.view.ndim + /* "View.MemoryView":650 + * def copy_fortran(self): + * cdef __Pyx_memviewslice src, dst + * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<< * + * slice_copy(self, &src) */ - __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0); - if (__pyx_t_1) { + __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS)); - /* "View.MemoryView":579 - * def suboffsets(self): - * if self.view.suboffsets == NULL: - * return (-1,) * self.view.ndim # <<<<<<<<<<<<<< + /* "View.MemoryView":652 + * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS * - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) + * slice_copy(self, &src) # <<<<<<<<<<<<<< + * dst = slice_copy_contig(&src, "fortran", self.view.ndim, + * self.view.itemsize, */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 579, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyNumber_Multiply(__pyx_tuple__14, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 579, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; + __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src)); - /* "View.MemoryView":578 - * @property - * def suboffsets(self): - * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<< - * return (-1,) * self.view.ndim + /* "View.MemoryView":653 * + * slice_copy(self, &src) + * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<< + * self.view.itemsize, + * flags|PyBUF_F_CONTIGUOUS, */ - } + __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), ((char *)"fortran"), __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 653, __pyx_L1_error) + __pyx_v_dst = __pyx_t_1; - /* "View.MemoryView":581 - * return (-1,) * self.view.ndim + /* "View.MemoryView":658 + * self.dtype_is_object) + * + * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<< * - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) # <<<<<<<<<<<<<< * - * @property */ __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 581, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = (__pyx_v_self->view.suboffsets + __pyx_v_self->view.ndim); - for (__pyx_t_6 = __pyx_v_self->view.suboffsets; __pyx_t_6 < __pyx_t_5; __pyx_t_6++) { - __pyx_t_4 = __pyx_t_6; - __pyx_v_suboffset = (__pyx_t_4[0]); - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_suboffset); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 581, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_2))) __PYX_ERR(2, 581, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } - __pyx_t_2 = PyList_AsTuple(((PyObject*)__pyx_t_3)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 581, __pyx_L1_error) + __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 658, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; - /* "View.MemoryView":577 + /* "View.MemoryView":648 + * return memoryview_copy_from_slice(self, &mslice) * - * @property - * def suboffsets(self): # <<<<<<<<<<<<<< - * if self.view.suboffsets == NULL: - * return (-1,) * self.view.ndim + * def copy_fortran(self): # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice src, dst + * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); @@ -9879,154 +11394,228 @@ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get_ return __pyx_r; } -/* "View.MemoryView":584 - * - * @property - * def ndim(self): # <<<<<<<<<<<<<< - * return self.view.ndim - * +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): */ /* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(PyObject *__pyx_v_self) { +static PyObject *__pyx_pw___pyx_memoryview_1__reduce_cython__(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*/ +static PyObject *__pyx_pw___pyx_memoryview_1__reduce_cython__(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 +) { + #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("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + __Pyx_RefNannySetupContext("__reduce_cython__ (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); + if (unlikely(__pyx_nargs > 0)) { + __Pyx_RaiseArgtupleInvalid("__reduce_cython__", 1, 0, 0, __pyx_nargs); return NULL;} + if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__reduce_cython__", 0))) return NULL; + __pyx_r = __pyx_pf___pyx_memoryview___reduce_cython__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) { +static PyObject *__pyx_pf___pyx_memoryview___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_RefNannySetupContext("__reduce_cython__", 1); - /* "View.MemoryView":585 - * @property - * def ndim(self): - * return self.view.ndim # <<<<<<<<<<<<<< - * - * @property + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 585, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; + __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); + __PYX_ERR(1, 2, __pyx_L1_error) - /* "View.MemoryView":584 - * - * @property - * def ndim(self): # <<<<<<<<<<<<<< - * return self.view.ndim - * + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): */ /* function exit code */ __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("View.MemoryView.memoryview.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; - __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":588 - * - * @property - * def itemsize(self): # <<<<<<<<<<<<<< - * return self.view.itemsize - * +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" */ /* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(PyObject *__pyx_v_self) { +static PyObject *__pyx_pw___pyx_memoryview_3__setstate_cython__(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*/ +static PyObject *__pyx_pw___pyx_memoryview_3__setstate_cython__(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 +) { + CYTHON_UNUSED PyObject *__pyx_v___pyx_state = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + __Pyx_RefNannySetupContext("__setstate_cython__ (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_pyx_state,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + 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_pyx_state)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 3, __pyx_L3_error) + else goto __pyx_L5_argtuple_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, "__setstate_cython__") < 0)) __PYX_ERR(1, 3, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v___pyx_state = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__setstate_cython__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 3, __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("View.MemoryView.memoryview.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf___pyx_memoryview_2__setstate_cython__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v___pyx_state); /* 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_15View_dot_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) { +static PyObject *__pyx_pf___pyx_memoryview_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_RefNannySetupContext("__setstate_cython__", 1); - /* "View.MemoryView":589 - * @property - * def itemsize(self): - * return self.view.itemsize # <<<<<<<<<<<<<< - * - * @property + /* "(tree fragment)":4 + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 589, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; + __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); + __PYX_ERR(1, 4, __pyx_L1_error) - /* "View.MemoryView":588 - * - * @property - * def itemsize(self): # <<<<<<<<<<<<<< - * return self.view.itemsize - * + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" */ /* function exit code */ __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("View.MemoryView.memoryview.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; - __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":592 - * - * @property - * def nbytes(self): # <<<<<<<<<<<<<< - * return self.size * self.view.itemsize +/* "View.MemoryView":662 * + * @cname('__pyx_memoryview_new') + * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<< + * cdef memoryview result = memoryview(o, flags, dtype_is_object) + * result.typeinfo = typeinfo */ -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) { +static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) { + struct __pyx_memoryview_obj *__pyx_v_result = 0; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; @@ -10035,34 +11624,63 @@ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(str int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_RefNannySetupContext("memoryview_cwrapper", 1); - /* "View.MemoryView":593 - * @property - * def nbytes(self): - * return self.size * self.view.itemsize # <<<<<<<<<<<<<< - * - * @property + /* "View.MemoryView":663 + * @cname('__pyx_memoryview_new') + * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): + * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<< + * result.typeinfo = typeinfo + * return result */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 593, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 663, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 593, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 663, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 593, __pyx_L1_error) + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 663, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; + __Pyx_INCREF(__pyx_v_o); + __Pyx_GIVEREF(__pyx_v_o); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o)) __PYX_ERR(1, 663, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1)) __PYX_ERR(1, 663, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2)) __PYX_ERR(1, 663, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 663, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2); + __pyx_t_2 = 0; - /* "View.MemoryView":592 + /* "View.MemoryView":664 + * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): + * cdef memoryview result = memoryview(o, flags, dtype_is_object) + * result.typeinfo = typeinfo # <<<<<<<<<<<<<< + * return result * - * @property - * def nbytes(self): # <<<<<<<<<<<<<< - * return self.size * self.view.itemsize + */ + __pyx_v_result->typeinfo = __pyx_v_typeinfo; + + /* "View.MemoryView":665 + * cdef memoryview result = memoryview(o, flags, dtype_is_object) + * result.typeinfo = typeinfo + * return result # <<<<<<<<<<<<<< + * + * @cname('__pyx_memoryview_check') + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF((PyObject *)__pyx_v_result); + __pyx_r = ((PyObject *)__pyx_v_result); + goto __pyx_L0; + + /* "View.MemoryView":662 * + * @cname('__pyx_memoryview_new') + * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<< + * cdef memoryview result = memoryview(o, flags, dtype_is_object) + * result.typeinfo = typeinfo */ /* function exit code */ @@ -10070,4631 +11688,4346 @@ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(str __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; + __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_result); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":596 +/* "View.MemoryView":668 + * + * @cname('__pyx_memoryview_check') + * cdef inline bint memoryview_check(object o) noexcept: # <<<<<<<<<<<<<< + * return isinstance(o, memoryview) * - * @property - * def size(self): # <<<<<<<<<<<<<< - * if self._size is None: - * result = 1 */ -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); +static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) { + int __pyx_r; + int __pyx_t_1; + + /* "View.MemoryView":669 + * @cname('__pyx_memoryview_check') + * cdef inline bint memoryview_check(object o) noexcept: + * return isinstance(o, memoryview) # <<<<<<<<<<<<<< + * + * cdef tuple _unellipsify(object index, int ndim): + */ + __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, __pyx_memoryview_type); + __pyx_r = __pyx_t_1; + goto __pyx_L0; + + /* "View.MemoryView":668 + * + * @cname('__pyx_memoryview_check') + * cdef inline bint memoryview_check(object o) noexcept: # <<<<<<<<<<<<<< + * return isinstance(o, memoryview) + * + */ /* function exit code */ - __Pyx_RefNannyFinishContext(); + __pyx_L0:; return __pyx_r; } -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) { +/* "View.MemoryView":671 + * return isinstance(o, memoryview) + * + * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<< + * """ + * Replace all ellipses with full slices and fill incomplete indices with + */ + +static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) { + Py_ssize_t __pyx_v_idx; + PyObject *__pyx_v_tup = NULL; PyObject *__pyx_v_result = NULL; - PyObject *__pyx_v_length = NULL; + int __pyx_v_have_slices; + int __pyx_v_seen_ellipsis; + PyObject *__pyx_v_item = NULL; + Py_ssize_t __pyx_v_nslices; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - int __pyx_t_1; + PyObject *__pyx_t_1 = NULL; int __pyx_t_2; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - Py_ssize_t *__pyx_t_5; - PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_3 = NULL; + Py_ssize_t __pyx_t_4; + Py_ssize_t __pyx_t_5; + Py_UCS4 __pyx_t_6; + PyObject *__pyx_t_7 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_RefNannySetupContext("_unellipsify", 1); - /* "View.MemoryView":597 - * @property - * def size(self): - * if self._size is None: # <<<<<<<<<<<<<< - * result = 1 + /* "View.MemoryView":677 + * """ + * cdef Py_ssize_t idx + * tup = index if isinstance(index, tuple) else (index,) # <<<<<<<<<<<<<< * + * result = [slice(None)] * ndim */ - __pyx_t_1 = (__pyx_v_self->_size == Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); + __pyx_t_2 = PyTuple_Check(__pyx_v_index); if (__pyx_t_2) { + __Pyx_INCREF(((PyObject*)__pyx_v_index)); + __pyx_t_1 = __pyx_v_index; + } else { + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 677, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_index); + __Pyx_GIVEREF(__pyx_v_index); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index)) __PYX_ERR(1, 677, __pyx_L1_error); + __pyx_t_1 = __pyx_t_3; + __pyx_t_3 = 0; + } + __pyx_v_tup = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; - /* "View.MemoryView":598 - * def size(self): - * if self._size is None: - * result = 1 # <<<<<<<<<<<<<< + /* "View.MemoryView":679 + * tup = index if isinstance(index, tuple) else (index,) * - * for length in self.view.shape[:self.view.ndim]: + * result = [slice(None)] * ndim # <<<<<<<<<<<<<< + * have_slices = False + * seen_ellipsis = False */ - __Pyx_INCREF(__pyx_int_1); - __pyx_v_result = __pyx_int_1; + __pyx_t_1 = PyList_New(1 * ((__pyx_v_ndim<0) ? 0:__pyx_v_ndim)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 679, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + { Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < __pyx_v_ndim; __pyx_temp++) { + __Pyx_INCREF(__pyx_slice__5); + __Pyx_GIVEREF(__pyx_slice__5); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, __pyx_temp, __pyx_slice__5)) __PYX_ERR(1, 679, __pyx_L1_error); + } + } + __pyx_v_result = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; - /* "View.MemoryView":600 - * result = 1 - * - * for length in self.view.shape[:self.view.ndim]: # <<<<<<<<<<<<<< - * result *= length + /* "View.MemoryView":680 * + * result = [slice(None)] * ndim + * have_slices = False # <<<<<<<<<<<<<< + * seen_ellipsis = False + * idx = 0 */ - __pyx_t_4 = (__pyx_v_self->view.shape + __pyx_v_self->view.ndim); - for (__pyx_t_5 = __pyx_v_self->view.shape; __pyx_t_5 < __pyx_t_4; __pyx_t_5++) { - __pyx_t_3 = __pyx_t_5; - __pyx_t_6 = PyInt_FromSsize_t((__pyx_t_3[0])); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 600, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_6); - __pyx_t_6 = 0; + __pyx_v_have_slices = 0; - /* "View.MemoryView":601 - * - * for length in self.view.shape[:self.view.ndim]: - * result *= length # <<<<<<<<<<<<<< - * - * self._size = result + /* "View.MemoryView":681 + * result = [slice(None)] * ndim + * have_slices = False + * seen_ellipsis = False # <<<<<<<<<<<<<< + * idx = 0 + * for item in tup: */ - __pyx_t_6 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 601, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_6); - __pyx_t_6 = 0; - } + __pyx_v_seen_ellipsis = 0; - /* "View.MemoryView":603 - * result *= length - * - * self._size = result # <<<<<<<<<<<<<< - * - * return self._size + /* "View.MemoryView":682 + * have_slices = False + * seen_ellipsis = False + * idx = 0 # <<<<<<<<<<<<<< + * for item in tup: + * if item is Ellipsis: */ - __Pyx_INCREF(__pyx_v_result); - __Pyx_GIVEREF(__pyx_v_result); - __Pyx_GOTREF(__pyx_v_self->_size); - __Pyx_DECREF(__pyx_v_self->_size); - __pyx_v_self->_size = __pyx_v_result; + __pyx_v_idx = 0; - /* "View.MemoryView":597 - * @property - * def size(self): - * if self._size is None: # <<<<<<<<<<<<<< - * result = 1 - * + /* "View.MemoryView":683 + * seen_ellipsis = False + * idx = 0 + * for item in tup: # <<<<<<<<<<<<<< + * if item is Ellipsis: + * if not seen_ellipsis: */ + if (unlikely(__pyx_v_tup == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + __PYX_ERR(1, 683, __pyx_L1_error) } + __pyx_t_1 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_1); + __pyx_t_4 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 683, __pyx_L1_error) + #endif + if (__pyx_t_4 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_4); __Pyx_INCREF(__pyx_t_3); __pyx_t_4++; if (unlikely((0 < 0))) __PYX_ERR(1, 683, __pyx_L1_error) + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 683, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_3); + __pyx_t_3 = 0; - /* "View.MemoryView":605 - * self._size = result - * - * return self._size # <<<<<<<<<<<<<< - * - * def __len__(self): + /* "View.MemoryView":684 + * idx = 0 + * for item in tup: + * if item is Ellipsis: # <<<<<<<<<<<<<< + * if not seen_ellipsis: + * idx += ndim - len(tup) */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->_size); - __pyx_r = __pyx_v_self->_size; - goto __pyx_L0; + __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis); + if (__pyx_t_2) { - /* "View.MemoryView":596 - * - * @property - * def size(self): # <<<<<<<<<<<<<< - * if self._size is None: - * result = 1 + /* "View.MemoryView":685 + * for item in tup: + * if item is Ellipsis: + * if not seen_ellipsis: # <<<<<<<<<<<<<< + * idx += ndim - len(tup) + * seen_ellipsis = True */ + __pyx_t_2 = (!__pyx_v_seen_ellipsis); + if (__pyx_t_2) { - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_result); - __Pyx_XDECREF(__pyx_v_length); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":686 + * if item is Ellipsis: + * if not seen_ellipsis: + * idx += ndim - len(tup) # <<<<<<<<<<<<<< + * seen_ellipsis = True + * have_slices = True + */ + if (unlikely(__pyx_v_tup == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(1, 686, __pyx_L1_error) + } + __pyx_t_5 = __Pyx_PyTuple_GET_SIZE(__pyx_v_tup); if (unlikely(__pyx_t_5 == ((Py_ssize_t)-1))) __PYX_ERR(1, 686, __pyx_L1_error) + __pyx_v_idx = (__pyx_v_idx + (__pyx_v_ndim - __pyx_t_5)); -/* "View.MemoryView":607 - * return self._size - * - * def __len__(self): # <<<<<<<<<<<<<< - * if self.view.ndim >= 1: - * return self.view.shape[0] + /* "View.MemoryView":687 + * if not seen_ellipsis: + * idx += ndim - len(tup) + * seen_ellipsis = True # <<<<<<<<<<<<<< + * have_slices = True + * else: */ + __pyx_v_seen_ellipsis = 1; -/* Python wrapper */ -static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/ -static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self)); + /* "View.MemoryView":685 + * for item in tup: + * if item is Ellipsis: + * if not seen_ellipsis: # <<<<<<<<<<<<<< + * idx += ndim - len(tup) + * seen_ellipsis = True + */ + } - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":688 + * idx += ndim - len(tup) + * seen_ellipsis = True + * have_slices = True # <<<<<<<<<<<<<< + * else: + * if isinstance(item, slice): + */ + __pyx_v_have_slices = 1; -static Py_ssize_t __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("__len__", 0); + /* "View.MemoryView":684 + * idx = 0 + * for item in tup: + * if item is Ellipsis: # <<<<<<<<<<<<<< + * if not seen_ellipsis: + * idx += ndim - len(tup) + */ + goto __pyx_L5; + } - /* "View.MemoryView":608 - * - * def __len__(self): - * if self.view.ndim >= 1: # <<<<<<<<<<<<<< - * return self.view.shape[0] - * + /* "View.MemoryView":690 + * have_slices = True + * else: + * if isinstance(item, slice): # <<<<<<<<<<<<<< + * have_slices = True + * elif not PyIndex_Check(item): */ - __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0); - if (__pyx_t_1) { + /*else*/ { + __pyx_t_2 = PySlice_Check(__pyx_v_item); + if (__pyx_t_2) { - /* "View.MemoryView":609 - * def __len__(self): - * if self.view.ndim >= 1: - * return self.view.shape[0] # <<<<<<<<<<<<<< - * - * return 0 + /* "View.MemoryView":691 + * else: + * if isinstance(item, slice): + * have_slices = True # <<<<<<<<<<<<<< + * elif not PyIndex_Check(item): + * raise TypeError, f"Cannot index with type '{type(item)}'" */ - __pyx_r = (__pyx_v_self->view.shape[0]); - goto __pyx_L0; + __pyx_v_have_slices = 1; - /* "View.MemoryView":608 - * - * def __len__(self): - * if self.view.ndim >= 1: # <<<<<<<<<<<<<< - * return self.view.shape[0] - * + /* "View.MemoryView":690 + * have_slices = True + * else: + * if isinstance(item, slice): # <<<<<<<<<<<<<< + * have_slices = True + * elif not PyIndex_Check(item): */ - } + goto __pyx_L7; + } - /* "View.MemoryView":611 - * return self.view.shape[0] - * - * return 0 # <<<<<<<<<<<<<< - * - * def __repr__(self): + /* "View.MemoryView":692 + * if isinstance(item, slice): + * have_slices = True + * elif not PyIndex_Check(item): # <<<<<<<<<<<<<< + * raise TypeError, f"Cannot index with type '{type(item)}'" + * result[idx] = item + */ + __pyx_t_2 = (!(PyIndex_Check(__pyx_v_item) != 0)); + if (unlikely(__pyx_t_2)) { + + /* "View.MemoryView":693 + * have_slices = True + * elif not PyIndex_Check(item): + * raise TypeError, f"Cannot index with type '{type(item)}'" # <<<<<<<<<<<<<< + * result[idx] = item + * idx += 1 + */ + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 693, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 0; + __pyx_t_6 = 127; + __Pyx_INCREF(__pyx_kp_u_Cannot_index_with_type); + __pyx_t_5 += 24; + __Pyx_GIVEREF(__pyx_kp_u_Cannot_index_with_type); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Cannot_index_with_type); + __pyx_t_7 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_item)), __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 693, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_6; + __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_7); + __pyx_t_7 = 0; + __Pyx_INCREF(__pyx_kp_u__6); + __pyx_t_5 += 1; + __Pyx_GIVEREF(__pyx_kp_u__6); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__6); + __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 693, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_builtin_TypeError, __pyx_t_7, 0, 0); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __PYX_ERR(1, 693, __pyx_L1_error) + + /* "View.MemoryView":692 + * if isinstance(item, slice): + * have_slices = True + * elif not PyIndex_Check(item): # <<<<<<<<<<<<<< + * raise TypeError, f"Cannot index with type '{type(item)}'" + * result[idx] = item */ - __pyx_r = 0; - goto __pyx_L0; + } + __pyx_L7:; - /* "View.MemoryView":607 - * return self._size + /* "View.MemoryView":694 + * elif not PyIndex_Check(item): + * raise TypeError, f"Cannot index with type '{type(item)}'" + * result[idx] = item # <<<<<<<<<<<<<< + * idx += 1 * - * def __len__(self): # <<<<<<<<<<<<<< - * if self.view.ndim >= 1: - * return self.view.shape[0] */ + if (unlikely((__Pyx_SetItemInt(__pyx_v_result, __pyx_v_idx, __pyx_v_item, Py_ssize_t, 1, PyInt_FromSsize_t, 1, 1, 1) < 0))) __PYX_ERR(1, 694, __pyx_L1_error) + } + __pyx_L5:; - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":613 - * return 0 + /* "View.MemoryView":695 + * raise TypeError, f"Cannot index with type '{type(item)}'" + * result[idx] = item + * idx += 1 # <<<<<<<<<<<<<< * - * def __repr__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__, - * id(self)) + * nslices = ndim - idx */ + __pyx_v_idx = (__pyx_v_idx + 1); -/* Python wrapper */ -static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__repr__", 0); - - /* "View.MemoryView":614 - * - * def __repr__(self): - * return "" % (self.base.__class__.__name__, # <<<<<<<<<<<<<< - * id(self)) - * + /* "View.MemoryView":683 + * seen_ellipsis = False + * idx = 0 + * for item in tup: # <<<<<<<<<<<<<< + * if item is Ellipsis: + * if not seen_ellipsis: */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 614, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 614, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 614, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "View.MemoryView":615 - * def __repr__(self): - * return "" % (self.base.__class__.__name__, - * id(self)) # <<<<<<<<<<<<<< + /* "View.MemoryView":697 + * idx += 1 + * + * nslices = ndim - idx # <<<<<<<<<<<<<< + * return have_slices or nslices, tuple(result) * - * def __str__(self): */ - __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 615, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __pyx_v_nslices = (__pyx_v_ndim - __pyx_v_idx); - /* "View.MemoryView":614 + /* "View.MemoryView":698 * - * def __repr__(self): - * return "" % (self.base.__class__.__name__, # <<<<<<<<<<<<<< - * id(self)) + * nslices = ndim - idx + * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<< * + * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 614, __pyx_L1_error) + __Pyx_XDECREF(__pyx_r); + if (!__pyx_v_have_slices) { + } else { + __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_1 = __pyx_t_7; + __pyx_t_7 = 0; + goto __pyx_L9_bool_binop_done; + } + __pyx_t_7 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_1 = __pyx_t_7; + __pyx_t_7 = 0; + __pyx_L9_bool_binop_done:; + __pyx_t_7 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 698, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 698, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(1, 698, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_7)) __PYX_ERR(1, 698, __pyx_L1_error); __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 614, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; + __pyx_t_7 = 0; + __pyx_r = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; goto __pyx_L0; - /* "View.MemoryView":613 - * return 0 + /* "View.MemoryView":671 + * return isinstance(o, memoryview) * - * def __repr__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__, - * id(self)) + * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<< + * """ + * Replace all ellipses with full slices and fill incomplete indices with */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; __pyx_L0:; + __Pyx_XDECREF(__pyx_v_tup); + __Pyx_XDECREF(__pyx_v_result); + __Pyx_XDECREF(__pyx_v_item); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":617 - * id(self)) - * - * def __str__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__,) +/* "View.MemoryView":700 + * return have_slices or nslices, tuple(result) * + * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: # <<<<<<<<<<<<<< + * for suboffset in suboffsets[:ndim]: + * if suboffset >= 0: */ -/* Python wrapper */ -static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; +static int assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) { + Py_ssize_t __pyx_v_suboffset; + int __pyx_r; + Py_ssize_t *__pyx_t_1; + Py_ssize_t *__pyx_t_2; + Py_ssize_t *__pyx_t_3; + int __pyx_t_4; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__str__", 0); - /* "View.MemoryView":618 + /* "View.MemoryView":701 * - * def __str__(self): - * return "" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<< + * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: + * for suboffset in suboffsets[:ndim]: # <<<<<<<<<<<<<< + * if suboffset >= 0: + * raise ValueError, "Indirect dimensions not supported" + */ + __pyx_t_2 = (__pyx_v_suboffsets + __pyx_v_ndim); + for (__pyx_t_3 = __pyx_v_suboffsets; __pyx_t_3 < __pyx_t_2; __pyx_t_3++) { + __pyx_t_1 = __pyx_t_3; + __pyx_v_suboffset = (__pyx_t_1[0]); + + /* "View.MemoryView":702 + * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: + * for suboffset in suboffsets[:ndim]: + * if suboffset >= 0: # <<<<<<<<<<<<<< + * raise ValueError, "Indirect dimensions not supported" + * return 0 # return type just used as an error flag + */ + __pyx_t_4 = (__pyx_v_suboffset >= 0); + if (unlikely(__pyx_t_4)) { + + /* "View.MemoryView":703 + * for suboffset in suboffsets[:ndim]: + * if suboffset >= 0: + * raise ValueError, "Indirect dimensions not supported" # <<<<<<<<<<<<<< + * return 0 # return type just used as an error flag + * + */ + __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Indirect_dimensions_not_supporte, 0, 0); + __PYX_ERR(1, 703, __pyx_L1_error) + + /* "View.MemoryView":702 + * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: + * for suboffset in suboffsets[:ndim]: + * if suboffset >= 0: # <<<<<<<<<<<<<< + * raise ValueError, "Indirect dimensions not supported" + * return 0 # return type just used as an error flag + */ + } + } + + /* "View.MemoryView":704 + * if suboffset >= 0: + * raise ValueError, "Indirect dimensions not supported" + * return 0 # return type just used as an error flag # <<<<<<<<<<<<<< * * */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 618, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 618, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 618, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 618, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 618, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; + __pyx_r = 0; goto __pyx_L0; - /* "View.MemoryView":617 - * id(self)) - * - * def __str__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__,) + /* "View.MemoryView":700 + * return have_slices or nslices, tuple(result) * + * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: # <<<<<<<<<<<<<< + * for suboffset in suboffsets[:ndim]: + * if suboffset >= 0: */ /* function exit code */ __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; + __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":621 - * +/* "View.MemoryView":711 * - * def is_c_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp + * @cname('__pyx_memview_slice') + * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<< + * cdef int new_ndim = 0, suboffset_dim = -1, dim + * cdef bint negative_step */ -/* Python wrapper */ -static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice *__pyx_v_mslice; - __Pyx_memviewslice __pyx_v_tmp; - PyObject *__pyx_r = NULL; +static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) { + int __pyx_v_new_ndim; + int __pyx_v_suboffset_dim; + int __pyx_v_dim; + __Pyx_memviewslice __pyx_v_src; + __Pyx_memviewslice __pyx_v_dst; + __Pyx_memviewslice *__pyx_v_p_src; + struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0; + __Pyx_memviewslice *__pyx_v_p_dst; + int *__pyx_v_p_suboffset_dim; + Py_ssize_t __pyx_v_start; + Py_ssize_t __pyx_v_stop; + Py_ssize_t __pyx_v_step; + Py_ssize_t __pyx_v_cindex; + int __pyx_v_have_start; + int __pyx_v_have_stop; + int __pyx_v_have_step; + PyObject *__pyx_v_index = NULL; + struct __pyx_memoryview_obj *__pyx_r = NULL; __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; + int __pyx_t_1; PyObject *__pyx_t_2 = NULL; + struct __pyx_memoryview_obj *__pyx_t_3; + char *__pyx_t_4; + int __pyx_t_5; + Py_ssize_t __pyx_t_6; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + Py_ssize_t __pyx_t_9; + int __pyx_t_10; + Py_ssize_t __pyx_t_11; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("is_c_contig", 0); + __Pyx_RefNannySetupContext("memview_slice", 1); - /* "View.MemoryView":624 - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<< - * return slice_is_contig(mslice[0], 'C', self.view.ndim) - * + /* "View.MemoryView":712 + * @cname('__pyx_memview_slice') + * cdef memoryview memview_slice(memoryview memview, object indices): + * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<< + * cdef bint negative_step + * cdef __Pyx_memviewslice src, dst */ - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(2, 624, __pyx_L1_error) - __pyx_v_mslice = __pyx_t_1; + __pyx_v_new_ndim = 0; + __pyx_v_suboffset_dim = -1; - /* "View.MemoryView":625 - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) - * return slice_is_contig(mslice[0], 'C', self.view.ndim) # <<<<<<<<<<<<<< + /* "View.MemoryView":719 * - * def is_f_contig(self): + * + * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<< + * + * cdef _memoryviewslice memviewsliceobj */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig((__pyx_v_mslice[0]), 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 625, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; + (void)(memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)))); - /* "View.MemoryView":621 + /* "View.MemoryView":723 + * cdef _memoryviewslice memviewsliceobj * + * assert memview.view.ndim > 0 # <<<<<<<<<<<<<< * - * def is_c_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp + * if isinstance(memview, _memoryviewslice): */ + #ifndef CYTHON_WITHOUT_ASSERTIONS + if (unlikely(__pyx_assertions_enabled())) { + __pyx_t_1 = (__pyx_v_memview->view.ndim > 0); + if (unlikely(!__pyx_t_1)) { + __Pyx_Raise(__pyx_builtin_AssertionError, 0, 0, 0); + __PYX_ERR(1, 723, __pyx_L1_error) + } + } + #else + if ((1)); else __PYX_ERR(1, 723, __pyx_L1_error) + #endif - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":627 - * return slice_is_contig(mslice[0], 'C', self.view.ndim) + /* "View.MemoryView":725 + * assert memview.view.ndim > 0 * - * def is_f_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp + * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< + * memviewsliceobj = memview + * p_src = &memviewsliceobj.from_slice */ + __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); + if (__pyx_t_1) { -/* Python wrapper */ -static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":726 + * + * if isinstance(memview, _memoryviewslice): + * memviewsliceobj = memview # <<<<<<<<<<<<<< + * p_src = &memviewsliceobj.from_slice + * else: + */ + if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) __PYX_ERR(1, 726, __pyx_L1_error) + __pyx_t_2 = ((PyObject *)__pyx_v_memview); + __Pyx_INCREF(__pyx_t_2); + __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2); + __pyx_t_2 = 0; -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice *__pyx_v_mslice; - __Pyx_memviewslice __pyx_v_tmp; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("is_f_contig", 0); + /* "View.MemoryView":727 + * if isinstance(memview, _memoryviewslice): + * memviewsliceobj = memview + * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<< + * else: + * slice_copy(memview, &src) + */ + __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice); - /* "View.MemoryView":630 - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<< - * return slice_is_contig(mslice[0], 'F', self.view.ndim) + /* "View.MemoryView":725 + * assert memview.view.ndim > 0 * + * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< + * memviewsliceobj = memview + * p_src = &memviewsliceobj.from_slice */ - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(2, 630, __pyx_L1_error) - __pyx_v_mslice = __pyx_t_1; + goto __pyx_L3; + } - /* "View.MemoryView":631 - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) - * return slice_is_contig(mslice[0], 'F', self.view.ndim) # <<<<<<<<<<<<<< + /* "View.MemoryView":729 + * p_src = &memviewsliceobj.from_slice + * else: + * slice_copy(memview, &src) # <<<<<<<<<<<<<< + * p_src = &src * - * def copy(self): */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig((__pyx_v_mslice[0]), 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 631, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; + /*else*/ { + __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src)); - /* "View.MemoryView":627 - * return slice_is_contig(mslice[0], 'C', self.view.ndim) + /* "View.MemoryView":730 + * else: + * slice_copy(memview, &src) + * p_src = &src # <<<<<<<<<<<<<< + * * - * def is_f_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp */ + __pyx_v_p_src = (&__pyx_v_src); + } + __pyx_L3:; - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":633 - * return slice_is_contig(mslice[0], 'F', self.view.ndim) + /* "View.MemoryView":736 + * + * + * dst.memview = p_src.memview # <<<<<<<<<<<<<< + * dst.data = p_src.data * - * def copy(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice mslice - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS */ + __pyx_t_3 = __pyx_v_p_src->memview; + __pyx_v_dst.memview = __pyx_t_3; -/* Python wrapper */ -static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("copy (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice __pyx_v_mslice; - int __pyx_v_flags; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("copy", 0); - - /* "View.MemoryView":635 - * def copy(self): - * cdef __Pyx_memviewslice mslice - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<< + /* "View.MemoryView":737 + * + * dst.memview = p_src.memview + * dst.data = p_src.data # <<<<<<<<<<<<<< + * * - * slice_copy(self, &mslice) */ - __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS)); + __pyx_t_4 = __pyx_v_p_src->data; + __pyx_v_dst.data = __pyx_t_4; - /* "View.MemoryView":637 - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS + /* "View.MemoryView":742 * - * slice_copy(self, &mslice) # <<<<<<<<<<<<<< - * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, - * self.view.itemsize, + * + * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<< + * cdef int *p_suboffset_dim = &suboffset_dim + * cdef Py_ssize_t start, stop, step, cindex */ - __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice)); + __pyx_v_p_dst = (&__pyx_v_dst); - /* "View.MemoryView":638 + /* "View.MemoryView":743 * - * slice_copy(self, &mslice) - * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<< - * self.view.itemsize, - * flags|PyBUF_C_CONTIGUOUS, + * cdef __Pyx_memviewslice *p_dst = &dst + * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<< + * cdef Py_ssize_t start, stop, step, cindex + * cdef bint have_start, have_stop, have_step */ - __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), ((char *)"c"), __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 638, __pyx_L1_error) - __pyx_v_mslice = __pyx_t_1; + __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim); - /* "View.MemoryView":643 - * self.dtype_is_object) - * - * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<< + /* "View.MemoryView":747 + * cdef bint have_start, have_stop, have_step * - * def copy_fortran(self): + * for dim, index in enumerate(indices): # <<<<<<<<<<<<<< + * if PyIndex_Check(index): + * cindex = index */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 643, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; + __pyx_t_5 = 0; + if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) { + __pyx_t_2 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_2); + __pyx_t_6 = 0; + __pyx_t_7 = NULL; + } else { + __pyx_t_6 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 747, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 747, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_7)) { + if (likely(PyList_CheckExact(__pyx_t_2))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 747, __pyx_L1_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_8 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_t_8); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(1, 747, __pyx_L1_error) + #else + __pyx_t_8 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 747, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 747, __pyx_L1_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_t_8); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(1, 747, __pyx_L1_error) + #else + __pyx_t_8 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 747, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #endif + } + } else { + __pyx_t_8 = __pyx_t_7(__pyx_t_2); + if (unlikely(!__pyx_t_8)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(1, 747, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_8); + } + __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_8); + __pyx_t_8 = 0; + __pyx_v_dim = __pyx_t_5; + __pyx_t_5 = (__pyx_t_5 + 1); - /* "View.MemoryView":633 - * return slice_is_contig(mslice[0], 'F', self.view.ndim) + /* "View.MemoryView":748 * - * def copy(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice mslice - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS + * for dim, index in enumerate(indices): + * if PyIndex_Check(index): # <<<<<<<<<<<<<< + * cindex = index + * slice_memviewslice( */ + __pyx_t_1 = (PyIndex_Check(__pyx_v_index) != 0); + if (__pyx_t_1) { - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":749 + * for dim, index in enumerate(indices): + * if PyIndex_Check(index): + * cindex = index # <<<<<<<<<<<<<< + * slice_memviewslice( + * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], + */ + __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 749, __pyx_L1_error) + __pyx_v_cindex = __pyx_t_9; -/* "View.MemoryView":645 - * return memoryview_copy_from_slice(self, &mslice) + /* "View.MemoryView":750 + * if PyIndex_Check(index): + * cindex = index + * slice_memviewslice( # <<<<<<<<<<<<<< + * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], + * dim, new_ndim, p_suboffset_dim, + */ + __pyx_t_10 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_cindex, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(1, 750, __pyx_L1_error) + + /* "View.MemoryView":748 * - * def copy_fortran(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice src, dst - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS + * for dim, index in enumerate(indices): + * if PyIndex_Check(index): # <<<<<<<<<<<<<< + * cindex = index + * slice_memviewslice( */ + goto __pyx_L6; + } -/* Python wrapper */ -static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self)); + /* "View.MemoryView":756 + * 0, 0, 0, # have_{start,stop,step} + * False) + * elif index is None: # <<<<<<<<<<<<<< + * p_dst.shape[new_ndim] = 1 + * p_dst.strides[new_ndim] = 0 + */ + __pyx_t_1 = (__pyx_v_index == Py_None); + if (__pyx_t_1) { - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":757 + * False) + * elif index is None: + * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<< + * p_dst.strides[new_ndim] = 0 + * p_dst.suboffsets[new_ndim] = -1 + */ + (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1; -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice __pyx_v_src; - __Pyx_memviewslice __pyx_v_dst; - int __pyx_v_flags; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("copy_fortran", 0); + /* "View.MemoryView":758 + * elif index is None: + * p_dst.shape[new_ndim] = 1 + * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<< + * p_dst.suboffsets[new_ndim] = -1 + * new_ndim += 1 + */ + (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0; - /* "View.MemoryView":647 - * def copy_fortran(self): - * cdef __Pyx_memviewslice src, dst - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<< - * - * slice_copy(self, &src) + /* "View.MemoryView":759 + * p_dst.shape[new_ndim] = 1 + * p_dst.strides[new_ndim] = 0 + * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<< + * new_ndim += 1 + * else: */ - __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS)); + (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1L; - /* "View.MemoryView":649 - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS - * - * slice_copy(self, &src) # <<<<<<<<<<<<<< - * dst = slice_copy_contig(&src, "fortran", self.view.ndim, - * self.view.itemsize, + /* "View.MemoryView":760 + * p_dst.strides[new_ndim] = 0 + * p_dst.suboffsets[new_ndim] = -1 + * new_ndim += 1 # <<<<<<<<<<<<<< + * else: + * start = index.start or 0 */ - __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src)); + __pyx_v_new_ndim = (__pyx_v_new_ndim + 1); - /* "View.MemoryView":650 - * - * slice_copy(self, &src) - * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<< - * self.view.itemsize, - * flags|PyBUF_F_CONTIGUOUS, + /* "View.MemoryView":756 + * 0, 0, 0, # have_{start,stop,step} + * False) + * elif index is None: # <<<<<<<<<<<<<< + * p_dst.shape[new_ndim] = 1 + * p_dst.strides[new_ndim] = 0 */ - __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), ((char *)"fortran"), __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 650, __pyx_L1_error) - __pyx_v_dst = __pyx_t_1; + goto __pyx_L6; + } - /* "View.MemoryView":655 - * self.dtype_is_object) + /* "View.MemoryView":762 + * new_ndim += 1 + * else: + * start = index.start or 0 # <<<<<<<<<<<<<< + * stop = index.stop or 0 + * step = index.step or 0 + */ + /*else*/ { + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 762, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 762, __pyx_L1_error) + if (!__pyx_t_1) { + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else { + __pyx_t_11 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_11 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 762, __pyx_L1_error) + __pyx_t_9 = __pyx_t_11; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + goto __pyx_L7_bool_binop_done; + } + __pyx_t_9 = 0; + __pyx_L7_bool_binop_done:; + __pyx_v_start = __pyx_t_9; + + /* "View.MemoryView":763 + * else: + * start = index.start or 0 + * stop = index.stop or 0 # <<<<<<<<<<<<<< + * step = index.step or 0 * - * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<< + */ + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 763, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 763, __pyx_L1_error) + if (!__pyx_t_1) { + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else { + __pyx_t_11 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_11 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 763, __pyx_L1_error) + __pyx_t_9 = __pyx_t_11; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + goto __pyx_L9_bool_binop_done; + } + __pyx_t_9 = 0; + __pyx_L9_bool_binop_done:; + __pyx_v_stop = __pyx_t_9; + + /* "View.MemoryView":764 + * start = index.start or 0 + * stop = index.stop or 0 + * step = index.step or 0 # <<<<<<<<<<<<<< * + * have_start = index.start is not None + */ + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 764, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 764, __pyx_L1_error) + if (!__pyx_t_1) { + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else { + __pyx_t_11 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_11 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 764, __pyx_L1_error) + __pyx_t_9 = __pyx_t_11; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + goto __pyx_L11_bool_binop_done; + } + __pyx_t_9 = 0; + __pyx_L11_bool_binop_done:; + __pyx_v_step = __pyx_t_9; + + /* "View.MemoryView":766 + * step = index.step or 0 * + * have_start = index.start is not None # <<<<<<<<<<<<<< + * have_stop = index.stop is not None + * have_step = index.step is not None */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 655, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 766, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = (__pyx_t_8 != Py_None); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_v_have_start = __pyx_t_1; - /* "View.MemoryView":645 - * return memoryview_copy_from_slice(self, &mslice) + /* "View.MemoryView":767 + * + * have_start = index.start is not None + * have_stop = index.stop is not None # <<<<<<<<<<<<<< + * have_step = index.step is not None * - * def copy_fortran(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice src, dst - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS */ + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 767, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = (__pyx_t_8 != Py_None); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_v_have_stop = __pyx_t_1; - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): + /* "View.MemoryView":768 + * have_start = index.start is not None + * have_stop = index.stop is not None + * have_step = index.step is not None # <<<<<<<<<<<<<< + * + * slice_memviewslice( */ + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 768, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = (__pyx_t_8 != Py_None); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_v_have_step = __pyx_t_1; -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryview_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw___pyx_memoryview_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_memoryview___reduce_cython__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_memoryview___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + /* "View.MemoryView":770 + * have_step = index.step is not None + * + * slice_memviewslice( # <<<<<<<<<<<<<< + * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], + * dim, new_ndim, p_suboffset_dim, */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 2, __pyx_L1_error) + __pyx_t_10 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(1, 770, __pyx_L1_error) - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): + /* "View.MemoryView":776 + * have_start, have_stop, have_step, + * True) + * new_ndim += 1 # <<<<<<<<<<<<<< + * + * if isinstance(memview, _memoryviewslice): */ + __pyx_v_new_ndim = (__pyx_v_new_ndim + 1); + } + __pyx_L6:; - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + /* "View.MemoryView":747 + * cdef bint have_start, have_stop, have_step + * + * for dim, index in enumerate(indices): # <<<<<<<<<<<<<< + * if PyIndex_Check(index): + * cindex = index */ + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryview_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw___pyx_memoryview_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_memoryview_2__setstate_cython__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_memoryview_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); + /* "View.MemoryView":778 + * new_ndim += 1 + * + * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< + * return memoryview_fromslice(dst, new_ndim, + * memviewsliceobj.to_object_func, + */ + __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); + if (__pyx_t_1) { - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + /* "View.MemoryView":779 + * + * if isinstance(memview, _memoryviewslice): + * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<< + * memviewsliceobj.to_object_func, + * memviewsliceobj.to_dtype_func, */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 4, __pyx_L1_error) + __Pyx_XDECREF((PyObject *)__pyx_r); - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + /* "View.MemoryView":780 + * if isinstance(memview, _memoryviewslice): + * return memoryview_fromslice(dst, new_ndim, + * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<< + * memviewsliceobj.to_dtype_func, + * memview.dtype_is_object) */ + if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); __PYX_ERR(1, 780, __pyx_L1_error) } - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":781 + * return memoryview_fromslice(dst, new_ndim, + * memviewsliceobj.to_object_func, + * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<< + * memview.dtype_is_object) + * else: + */ + if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); __PYX_ERR(1, 781, __pyx_L1_error) } -/* "View.MemoryView":659 + /* "View.MemoryView":779 * - * @cname('__pyx_memoryview_new') - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<< - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo + * if isinstance(memview, _memoryviewslice): + * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<< + * memviewsliceobj.to_object_func, + * memviewsliceobj.to_dtype_func, */ + __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 779, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_memoryview_type))))) __PYX_ERR(1, 779, __pyx_L1_error) + __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_2); + __pyx_t_2 = 0; + goto __pyx_L0; -static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) { - struct __pyx_memoryview_obj *__pyx_v_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_cwrapper", 0); + /* "View.MemoryView":778 + * new_ndim += 1 + * + * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< + * return memoryview_fromslice(dst, new_ndim, + * memviewsliceobj.to_object_func, + */ + } - /* "View.MemoryView":660 - * @cname('__pyx_memoryview_new') - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): - * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<< - * result.typeinfo = typeinfo - * return result + /* "View.MemoryView":784 + * memview.dtype_is_object) + * else: + * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<< + * memview.dtype_is_object) + * */ - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 660, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 660, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 660, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_o); - __Pyx_GIVEREF(__pyx_v_o); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 660, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2); - __pyx_t_2 = 0; + /*else*/ { + __Pyx_XDECREF((PyObject *)__pyx_r); - /* "View.MemoryView":661 - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo # <<<<<<<<<<<<<< - * return result + /* "View.MemoryView":785 + * else: + * return memoryview_fromslice(dst, new_ndim, NULL, NULL, + * memview.dtype_is_object) # <<<<<<<<<<<<<< + * * */ - __pyx_v_result->typeinfo = __pyx_v_typeinfo; + __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 784, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); - /* "View.MemoryView":662 - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo - * return result # <<<<<<<<<<<<<< + /* "View.MemoryView":784 + * memview.dtype_is_object) + * else: + * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<< + * memview.dtype_is_object) * - * @cname('__pyx_memoryview_check') */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_result)); - __pyx_r = ((PyObject *)__pyx_v_result); - goto __pyx_L0; + if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_memoryview_type))))) __PYX_ERR(1, 784, __pyx_L1_error) + __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_2); + __pyx_t_2 = 0; + goto __pyx_L0; + } - /* "View.MemoryView":659 + /* "View.MemoryView":711 * - * @cname('__pyx_memoryview_new') - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<< - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo + * @cname('__pyx_memview_slice') + * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<< + * cdef int new_ndim = 0, suboffset_dim = -1, dim + * cdef bint negative_step */ /* function exit code */ __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XGIVEREF(__pyx_r); + __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj); + __Pyx_XDECREF(__pyx_v_index); + __Pyx_XGIVEREF((PyObject *)__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":665 - * - * @cname('__pyx_memoryview_check') - * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<< - * return isinstance(o, memoryview) +/* "View.MemoryView":793 * + * @cname('__pyx_memoryview_slice_memviewslice') + * cdef int slice_memviewslice( # <<<<<<<<<<<<<< + * __Pyx_memviewslice *dst, + * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, */ -static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) { +static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) { + Py_ssize_t __pyx_v_new_shape; + int __pyx_v_negative_step; int __pyx_r; - __Pyx_RefNannyDeclarations int __pyx_t_1; - __Pyx_RefNannySetupContext("memoryview_check", 0); - - /* "View.MemoryView":666 - * @cname('__pyx_memoryview_check') - * cdef inline bint memoryview_check(object o): - * return isinstance(o, memoryview) # <<<<<<<<<<<<<< - * - * cdef tuple _unellipsify(object index, int ndim): - */ - __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, __pyx_memoryview_type); - __pyx_r = __pyx_t_1; - goto __pyx_L0; + int __pyx_t_2; + int __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save; + #endif - /* "View.MemoryView":665 + /* "View.MemoryView":813 + * cdef bint negative_step * - * @cname('__pyx_memoryview_check') - * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<< - * return isinstance(o, memoryview) + * if not is_slice: # <<<<<<<<<<<<<< * + * if start < 0: */ + __pyx_t_1 = (!__pyx_v_is_slice); + if (__pyx_t_1) { - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":668 - * return isinstance(o, memoryview) + /* "View.MemoryView":815 + * if not is_slice: * - * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<< - * """ - * Replace all ellipses with full slices and fill incomplete indices with + * if start < 0: # <<<<<<<<<<<<<< + * start += shape + * if not 0 <= start < shape: */ + __pyx_t_1 = (__pyx_v_start < 0); + if (__pyx_t_1) { -static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) { - PyObject *__pyx_v_tup = NULL; - PyObject *__pyx_v_result = NULL; - int __pyx_v_have_slices; - int __pyx_v_seen_ellipsis; - CYTHON_UNUSED PyObject *__pyx_v_idx = NULL; - PyObject *__pyx_v_item = NULL; - Py_ssize_t __pyx_v_nslices; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - Py_ssize_t __pyx_t_5; - PyObject *(*__pyx_t_6)(PyObject *); - PyObject *__pyx_t_7 = NULL; - Py_ssize_t __pyx_t_8; - int __pyx_t_9; - int __pyx_t_10; - PyObject *__pyx_t_11 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_unellipsify", 0); - - /* "View.MemoryView":673 - * full slices. - * """ - * if not isinstance(index, tuple): # <<<<<<<<<<<<<< - * tup = (index,) - * else: + /* "View.MemoryView":816 + * + * if start < 0: + * start += shape # <<<<<<<<<<<<<< + * if not 0 <= start < shape: + * _err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim) */ - __pyx_t_1 = PyTuple_Check(__pyx_v_index); - __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); - if (__pyx_t_2) { + __pyx_v_start = (__pyx_v_start + __pyx_v_shape); - /* "View.MemoryView":674 - * """ - * if not isinstance(index, tuple): - * tup = (index,) # <<<<<<<<<<<<<< - * else: - * tup = index + /* "View.MemoryView":815 + * if not is_slice: + * + * if start < 0: # <<<<<<<<<<<<<< + * start += shape + * if not 0 <= start < shape: */ - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 674, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_index); - __Pyx_GIVEREF(__pyx_v_index); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index); - __pyx_v_tup = __pyx_t_3; - __pyx_t_3 = 0; + } - /* "View.MemoryView":673 - * full slices. - * """ - * if not isinstance(index, tuple): # <<<<<<<<<<<<<< - * tup = (index,) + /* "View.MemoryView":817 + * if start < 0: + * start += shape + * if not 0 <= start < shape: # <<<<<<<<<<<<<< + * _err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim) * else: */ - goto __pyx_L3; - } + __pyx_t_1 = (0 <= __pyx_v_start); + if (__pyx_t_1) { + __pyx_t_1 = (__pyx_v_start < __pyx_v_shape); + } + __pyx_t_2 = (!__pyx_t_1); + if (__pyx_t_2) { - /* "View.MemoryView":676 - * tup = (index,) + /* "View.MemoryView":818 + * start += shape + * if not 0 <= start < shape: + * _err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<< * else: - * tup = index # <<<<<<<<<<<<<< * - * result = [] */ - /*else*/ { - __Pyx_INCREF(__pyx_v_index); - __pyx_v_tup = __pyx_v_index; - } - __pyx_L3:; + __pyx_t_3 = __pyx_memoryview_err_dim(PyExc_IndexError, __pyx_kp_s_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(1, 818, __pyx_L1_error) - /* "View.MemoryView":678 - * tup = index - * - * result = [] # <<<<<<<<<<<<<< - * have_slices = False - * seen_ellipsis = False + /* "View.MemoryView":817 + * if start < 0: + * start += shape + * if not 0 <= start < shape: # <<<<<<<<<<<<<< + * _err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim) + * else: */ - __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 678, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_v_result = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; + } - /* "View.MemoryView":679 + /* "View.MemoryView":813 + * cdef bint negative_step * - * result = [] - * have_slices = False # <<<<<<<<<<<<<< - * seen_ellipsis = False - * for idx, item in enumerate(tup): - */ - __pyx_v_have_slices = 0; - - /* "View.MemoryView":680 - * result = [] - * have_slices = False - * seen_ellipsis = False # <<<<<<<<<<<<<< - * for idx, item in enumerate(tup): - * if item is Ellipsis: - */ - __pyx_v_seen_ellipsis = 0; - - /* "View.MemoryView":681 - * have_slices = False - * seen_ellipsis = False - * for idx, item in enumerate(tup): # <<<<<<<<<<<<<< - * if item is Ellipsis: - * if not seen_ellipsis: + * if not is_slice: # <<<<<<<<<<<<<< + * + * if start < 0: */ - __Pyx_INCREF(__pyx_int_0); - __pyx_t_3 = __pyx_int_0; - if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) { - __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0; - __pyx_t_6 = NULL; - } else { - __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 681, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 681, __pyx_L1_error) + goto __pyx_L3; } - for (;;) { - if (likely(!__pyx_t_6)) { - if (likely(PyList_CheckExact(__pyx_t_4))) { - if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(2, 681, __pyx_L1_error) - #else - __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 681, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - #endif - } else { - if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(2, 681, __pyx_L1_error) - #else - __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 681, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - #endif - } - } else { - __pyx_t_7 = __pyx_t_6(__pyx_t_4); - if (unlikely(!__pyx_t_7)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(2, 681, __pyx_L1_error) - } - break; - } - __Pyx_GOTREF(__pyx_t_7); - } - __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7); - __pyx_t_7 = 0; - __Pyx_INCREF(__pyx_t_3); - __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3); - __pyx_t_7 = __Pyx_PyInt_AddObjC(__pyx_t_3, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 681, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_3); - __pyx_t_3 = __pyx_t_7; - __pyx_t_7 = 0; - - /* "View.MemoryView":682 - * seen_ellipsis = False - * for idx, item in enumerate(tup): - * if item is Ellipsis: # <<<<<<<<<<<<<< - * if not seen_ellipsis: - * result.extend([slice(None)] * (ndim - len(tup) + 1)) - */ - __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis); - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":683 - * for idx, item in enumerate(tup): - * if item is Ellipsis: - * if not seen_ellipsis: # <<<<<<<<<<<<<< - * result.extend([slice(None)] * (ndim - len(tup) + 1)) - * seen_ellipsis = True - */ - __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0); - if (__pyx_t_1) { - /* "View.MemoryView":684 - * if item is Ellipsis: - * if not seen_ellipsis: - * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<< - * seen_ellipsis = True - * else: + /* "View.MemoryView":821 + * else: + * + * if have_step: # <<<<<<<<<<<<<< + * negative_step = step < 0 + * if step == 0: */ - __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == ((Py_ssize_t)-1))) __PYX_ERR(2, 684, __pyx_L1_error) - __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 684, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - { Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) { - __Pyx_INCREF(__pyx_slice__17); - __Pyx_GIVEREF(__pyx_slice__17); - PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__17); - } - } - __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 684, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + /*else*/ { + __pyx_t_2 = (__pyx_v_have_step != 0); + if (__pyx_t_2) { - /* "View.MemoryView":685 - * if not seen_ellipsis: - * result.extend([slice(None)] * (ndim - len(tup) + 1)) - * seen_ellipsis = True # <<<<<<<<<<<<<< - * else: - * result.append(slice(None)) + /* "View.MemoryView":822 + * + * if have_step: + * negative_step = step < 0 # <<<<<<<<<<<<<< + * if step == 0: + * _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim) */ - __pyx_v_seen_ellipsis = 1; + __pyx_v_negative_step = (__pyx_v_step < 0); - /* "View.MemoryView":683 - * for idx, item in enumerate(tup): - * if item is Ellipsis: - * if not seen_ellipsis: # <<<<<<<<<<<<<< - * result.extend([slice(None)] * (ndim - len(tup) + 1)) - * seen_ellipsis = True + /* "View.MemoryView":823 + * if have_step: + * negative_step = step < 0 + * if step == 0: # <<<<<<<<<<<<<< + * _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim) + * else: */ - goto __pyx_L7; - } + __pyx_t_2 = (__pyx_v_step == 0); + if (__pyx_t_2) { - /* "View.MemoryView":687 - * seen_ellipsis = True - * else: - * result.append(slice(None)) # <<<<<<<<<<<<<< - * have_slices = True + /* "View.MemoryView":824 + * negative_step = step < 0 + * if step == 0: + * _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<< * else: + * negative_step = False */ - /*else*/ { - __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__17); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 687, __pyx_L1_error) - } - __pyx_L7:; + __pyx_t_3 = __pyx_memoryview_err_dim(PyExc_ValueError, __pyx_kp_s_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(1, 824, __pyx_L1_error) - /* "View.MemoryView":688 - * else: - * result.append(slice(None)) - * have_slices = True # <<<<<<<<<<<<<< + /* "View.MemoryView":823 + * if have_step: + * negative_step = step < 0 + * if step == 0: # <<<<<<<<<<<<<< + * _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim) * else: - * if not isinstance(item, slice) and not PyIndex_Check(item): */ - __pyx_v_have_slices = 1; + } - /* "View.MemoryView":682 - * seen_ellipsis = False - * for idx, item in enumerate(tup): - * if item is Ellipsis: # <<<<<<<<<<<<<< - * if not seen_ellipsis: - * result.extend([slice(None)] * (ndim - len(tup) + 1)) + /* "View.MemoryView":821 + * else: + * + * if have_step: # <<<<<<<<<<<<<< + * negative_step = step < 0 + * if step == 0: */ goto __pyx_L6; } - /* "View.MemoryView":690 - * have_slices = True + /* "View.MemoryView":826 + * _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim) * else: - * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<< - * raise TypeError("Cannot index with type '%s'" % type(item)) + * negative_step = False # <<<<<<<<<<<<<< + * step = 1 * */ /*else*/ { - __pyx_t_2 = PySlice_Check(__pyx_v_item); - __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0); - if (__pyx_t_10) { - } else { - __pyx_t_1 = __pyx_t_10; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0); - __pyx_t_1 = __pyx_t_10; - __pyx_L9_bool_binop_done:; - if (unlikely(__pyx_t_1)) { + __pyx_v_negative_step = 0; - /* "View.MemoryView":691 + /* "View.MemoryView":827 * else: - * if not isinstance(item, slice) and not PyIndex_Check(item): - * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<< + * negative_step = False + * step = 1 # <<<<<<<<<<<<<< * - * have_slices = have_slices or isinstance(item, slice) - */ - __pyx_t_7 = __Pyx_PyString_FormatSafe(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 691, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_7); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 691, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_Raise(__pyx_t_11, 0, 0, 0); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - __PYX_ERR(2, 691, __pyx_L1_error) - - /* "View.MemoryView":690 - * have_slices = True - * else: - * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<< - * raise TypeError("Cannot index with type '%s'" % type(item)) * */ - } + __pyx_v_step = 1; + } + __pyx_L6:; - /* "View.MemoryView":693 - * raise TypeError("Cannot index with type '%s'" % type(item)) + /* "View.MemoryView":830 * - * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<< - * result.append(item) * + * if have_start: # <<<<<<<<<<<<<< + * if start < 0: + * start += shape */ - __pyx_t_10 = (__pyx_v_have_slices != 0); - if (!__pyx_t_10) { - } else { - __pyx_t_1 = __pyx_t_10; - goto __pyx_L11_bool_binop_done; - } - __pyx_t_10 = PySlice_Check(__pyx_v_item); - __pyx_t_2 = (__pyx_t_10 != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L11_bool_binop_done:; - __pyx_v_have_slices = __pyx_t_1; + __pyx_t_2 = (__pyx_v_have_start != 0); + if (__pyx_t_2) { - /* "View.MemoryView":694 - * - * have_slices = have_slices or isinstance(item, slice) - * result.append(item) # <<<<<<<<<<<<<< + /* "View.MemoryView":831 * - * nslices = ndim - len(result) + * if have_start: + * if start < 0: # <<<<<<<<<<<<<< + * start += shape + * if start < 0: */ - __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 694, __pyx_L1_error) - } - __pyx_L6:; + __pyx_t_2 = (__pyx_v_start < 0); + if (__pyx_t_2) { - /* "View.MemoryView":681 - * have_slices = False - * seen_ellipsis = False - * for idx, item in enumerate(tup): # <<<<<<<<<<<<<< - * if item is Ellipsis: - * if not seen_ellipsis: + /* "View.MemoryView":832 + * if have_start: + * if start < 0: + * start += shape # <<<<<<<<<<<<<< + * if start < 0: + * start = 0 */ - } - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_start = (__pyx_v_start + __pyx_v_shape); - /* "View.MemoryView":696 - * result.append(item) - * - * nslices = ndim - len(result) # <<<<<<<<<<<<<< - * if nslices: - * result.extend([slice(None)] * nslices) + /* "View.MemoryView":833 + * if start < 0: + * start += shape + * if start < 0: # <<<<<<<<<<<<<< + * start = 0 + * elif start >= shape: */ - __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == ((Py_ssize_t)-1))) __PYX_ERR(2, 696, __pyx_L1_error) - __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5); + __pyx_t_2 = (__pyx_v_start < 0); + if (__pyx_t_2) { - /* "View.MemoryView":697 - * - * nslices = ndim - len(result) - * if nslices: # <<<<<<<<<<<<<< - * result.extend([slice(None)] * nslices) - * + /* "View.MemoryView":834 + * start += shape + * if start < 0: + * start = 0 # <<<<<<<<<<<<<< + * elif start >= shape: + * if negative_step: */ - __pyx_t_1 = (__pyx_v_nslices != 0); - if (__pyx_t_1) { + __pyx_v_start = 0; + + /* "View.MemoryView":833 + * if start < 0: + * start += shape + * if start < 0: # <<<<<<<<<<<<<< + * start = 0 + * elif start >= shape: + */ + } - /* "View.MemoryView":698 - * nslices = ndim - len(result) - * if nslices: - * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<< + /* "View.MemoryView":831 * - * return have_slices or nslices, tuple(result) + * if have_start: + * if start < 0: # <<<<<<<<<<<<<< + * start += shape + * if start < 0: */ - __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 698, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - { Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) { - __Pyx_INCREF(__pyx_slice__17); - __Pyx_GIVEREF(__pyx_slice__17); - PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__17); + goto __pyx_L9; } - } - __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 698, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "View.MemoryView":697 - * - * nslices = ndim - len(result) - * if nslices: # <<<<<<<<<<<<<< - * result.extend([slice(None)] * nslices) - * + /* "View.MemoryView":835 + * if start < 0: + * start = 0 + * elif start >= shape: # <<<<<<<<<<<<<< + * if negative_step: + * start = shape - 1 */ - } + __pyx_t_2 = (__pyx_v_start >= __pyx_v_shape); + if (__pyx_t_2) { - /* "View.MemoryView":700 - * result.extend([slice(None)] * nslices) - * - * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<< - * - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): + /* "View.MemoryView":836 + * start = 0 + * elif start >= shape: + * if negative_step: # <<<<<<<<<<<<<< + * start = shape - 1 + * else: */ - __Pyx_XDECREF(__pyx_r); - if (!__pyx_v_have_slices) { - } else { - __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 700, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = __pyx_t_4; - __pyx_t_4 = 0; - goto __pyx_L14_bool_binop_done; - } - __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 700, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = __pyx_t_4; - __pyx_t_4 = 0; - __pyx_L14_bool_binop_done:; - __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 700, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 700, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_4); - __pyx_t_3 = 0; - __pyx_t_4 = 0; - __pyx_r = ((PyObject*)__pyx_t_11); - __pyx_t_11 = 0; - goto __pyx_L0; + if (__pyx_v_negative_step) { - /* "View.MemoryView":668 - * return isinstance(o, memoryview) - * - * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<< - * """ - * Replace all ellipses with full slices and fill incomplete indices with + /* "View.MemoryView":837 + * elif start >= shape: + * if negative_step: + * start = shape - 1 # <<<<<<<<<<<<<< + * else: + * start = shape */ + __pyx_v_start = (__pyx_v_shape - 1); - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_tup); - __Pyx_XDECREF(__pyx_v_result); - __Pyx_XDECREF(__pyx_v_idx); - __Pyx_XDECREF(__pyx_v_item); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":836 + * start = 0 + * elif start >= shape: + * if negative_step: # <<<<<<<<<<<<<< + * start = shape - 1 + * else: + */ + goto __pyx_L11; + } -/* "View.MemoryView":702 - * return have_slices or nslices, tuple(result) - * - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<< - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: + /* "View.MemoryView":839 + * start = shape - 1 + * else: + * start = shape # <<<<<<<<<<<<<< + * else: + * if negative_step: */ + /*else*/ { + __pyx_v_start = __pyx_v_shape; + } + __pyx_L11:; -static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) { - Py_ssize_t __pyx_v_suboffset; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - Py_ssize_t *__pyx_t_1; - Py_ssize_t *__pyx_t_2; - Py_ssize_t *__pyx_t_3; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("assert_direct_dimensions", 0); + /* "View.MemoryView":835 + * if start < 0: + * start = 0 + * elif start >= shape: # <<<<<<<<<<<<<< + * if negative_step: + * start = shape - 1 + */ + } + __pyx_L9:; - /* "View.MemoryView":703 + /* "View.MemoryView":830 * - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): - * for suboffset in suboffsets[:ndim]: # <<<<<<<<<<<<<< - * if suboffset >= 0: - * raise ValueError("Indirect dimensions not supported") + * + * if have_start: # <<<<<<<<<<<<<< + * if start < 0: + * start += shape */ - __pyx_t_2 = (__pyx_v_suboffsets + __pyx_v_ndim); - for (__pyx_t_3 = __pyx_v_suboffsets; __pyx_t_3 < __pyx_t_2; __pyx_t_3++) { - __pyx_t_1 = __pyx_t_3; - __pyx_v_suboffset = (__pyx_t_1[0]); + goto __pyx_L8; + } - /* "View.MemoryView":704 - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * raise ValueError("Indirect dimensions not supported") - * + /* "View.MemoryView":841 + * start = shape + * else: + * if negative_step: # <<<<<<<<<<<<<< + * start = shape - 1 + * else: */ - __pyx_t_4 = ((__pyx_v_suboffset >= 0) != 0); - if (unlikely(__pyx_t_4)) { + /*else*/ { + if (__pyx_v_negative_step) { - /* "View.MemoryView":705 - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: - * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<< - * - * + /* "View.MemoryView":842 + * else: + * if negative_step: + * start = shape - 1 # <<<<<<<<<<<<<< + * else: + * start = 0 */ - __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 705, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_Raise(__pyx_t_5, 0, 0, 0); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __PYX_ERR(2, 705, __pyx_L1_error) + __pyx_v_start = (__pyx_v_shape - 1); - /* "View.MemoryView":704 - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * raise ValueError("Indirect dimensions not supported") + /* "View.MemoryView":841 + * start = shape + * else: + * if negative_step: # <<<<<<<<<<<<<< + * start = shape - 1 + * else: + */ + goto __pyx_L12; + } + + /* "View.MemoryView":844 + * start = shape - 1 + * else: + * start = 0 # <<<<<<<<<<<<<< * + * if have_stop: */ + /*else*/ { + __pyx_v_start = 0; + } + __pyx_L12:; } - } + __pyx_L8:; - /* "View.MemoryView":702 - * return have_slices or nslices, tuple(result) + /* "View.MemoryView":846 + * start = 0 * - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<< - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: + * if have_stop: # <<<<<<<<<<<<<< + * if stop < 0: + * stop += shape */ + __pyx_t_2 = (__pyx_v_have_stop != 0); + if (__pyx_t_2) { - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":712 + /* "View.MemoryView":847 * - * @cname('__pyx_memview_slice') - * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<< - * cdef int new_ndim = 0, suboffset_dim = -1, dim - * cdef bint negative_step + * if have_stop: + * if stop < 0: # <<<<<<<<<<<<<< + * stop += shape + * if stop < 0: */ + __pyx_t_2 = (__pyx_v_stop < 0); + if (__pyx_t_2) { -static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) { - int __pyx_v_new_ndim; - int __pyx_v_suboffset_dim; - int __pyx_v_dim; - __Pyx_memviewslice __pyx_v_src; - __Pyx_memviewslice __pyx_v_dst; - __Pyx_memviewslice *__pyx_v_p_src; - struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0; - __Pyx_memviewslice *__pyx_v_p_dst; - int *__pyx_v_p_suboffset_dim; - Py_ssize_t __pyx_v_start; - Py_ssize_t __pyx_v_stop; - Py_ssize_t __pyx_v_step; - int __pyx_v_have_start; - int __pyx_v_have_stop; - int __pyx_v_have_step; - PyObject *__pyx_v_index = NULL; - struct __pyx_memoryview_obj *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - struct __pyx_memoryview_obj *__pyx_t_4; - char *__pyx_t_5; - int __pyx_t_6; - Py_ssize_t __pyx_t_7; - PyObject *(*__pyx_t_8)(PyObject *); - PyObject *__pyx_t_9 = NULL; - Py_ssize_t __pyx_t_10; - int __pyx_t_11; - Py_ssize_t __pyx_t_12; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memview_slice", 0); + /* "View.MemoryView":848 + * if have_stop: + * if stop < 0: + * stop += shape # <<<<<<<<<<<<<< + * if stop < 0: + * stop = 0 + */ + __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape); - /* "View.MemoryView":713 - * @cname('__pyx_memview_slice') - * cdef memoryview memview_slice(memoryview memview, object indices): - * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<< - * cdef bint negative_step - * cdef __Pyx_memviewslice src, dst + /* "View.MemoryView":849 + * if stop < 0: + * stop += shape + * if stop < 0: # <<<<<<<<<<<<<< + * stop = 0 + * elif stop > shape: */ - __pyx_v_new_ndim = 0; - __pyx_v_suboffset_dim = -1; + __pyx_t_2 = (__pyx_v_stop < 0); + if (__pyx_t_2) { - /* "View.MemoryView":720 - * - * - * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<< - * - * cdef _memoryviewslice memviewsliceobj + /* "View.MemoryView":850 + * stop += shape + * if stop < 0: + * stop = 0 # <<<<<<<<<<<<<< + * elif stop > shape: + * stop = shape */ - (void)(memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)))); + __pyx_v_stop = 0; - /* "View.MemoryView":724 - * cdef _memoryviewslice memviewsliceobj - * - * assert memview.view.ndim > 0 # <<<<<<<<<<<<<< - * - * if isinstance(memview, _memoryviewslice): + /* "View.MemoryView":849 + * if stop < 0: + * stop += shape + * if stop < 0: # <<<<<<<<<<<<<< + * stop = 0 + * elif stop > shape: */ - #ifndef CYTHON_WITHOUT_ASSERTIONS - if (unlikely(!Py_OptimizeFlag)) { - if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) { - PyErr_SetNone(PyExc_AssertionError); - __PYX_ERR(2, 724, __pyx_L1_error) - } - } - #endif + } - /* "View.MemoryView":726 - * assert memview.view.ndim > 0 + /* "View.MemoryView":847 * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * memviewsliceobj = memview - * p_src = &memviewsliceobj.from_slice + * if have_stop: + * if stop < 0: # <<<<<<<<<<<<<< + * stop += shape + * if stop < 0: */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { + goto __pyx_L14; + } - /* "View.MemoryView":727 - * - * if isinstance(memview, _memoryviewslice): - * memviewsliceobj = memview # <<<<<<<<<<<<<< - * p_src = &memviewsliceobj.from_slice - * else: + /* "View.MemoryView":851 + * if stop < 0: + * stop = 0 + * elif stop > shape: # <<<<<<<<<<<<<< + * stop = shape + * else: */ - if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) __PYX_ERR(2, 727, __pyx_L1_error) - __pyx_t_3 = ((PyObject *)__pyx_v_memview); - __Pyx_INCREF(__pyx_t_3); - __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3); - __pyx_t_3 = 0; + __pyx_t_2 = (__pyx_v_stop > __pyx_v_shape); + if (__pyx_t_2) { - /* "View.MemoryView":728 - * if isinstance(memview, _memoryviewslice): - * memviewsliceobj = memview - * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<< - * else: - * slice_copy(memview, &src) + /* "View.MemoryView":852 + * stop = 0 + * elif stop > shape: + * stop = shape # <<<<<<<<<<<<<< + * else: + * if negative_step: */ - __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice); + __pyx_v_stop = __pyx_v_shape; - /* "View.MemoryView":726 - * assert memview.view.ndim > 0 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * memviewsliceobj = memview - * p_src = &memviewsliceobj.from_slice + /* "View.MemoryView":851 + * if stop < 0: + * stop = 0 + * elif stop > shape: # <<<<<<<<<<<<<< + * stop = shape + * else: */ - goto __pyx_L3; - } + } + __pyx_L14:; - /* "View.MemoryView":730 - * p_src = &memviewsliceobj.from_slice - * else: - * slice_copy(memview, &src) # <<<<<<<<<<<<<< - * p_src = &src + /* "View.MemoryView":846 + * start = 0 * + * if have_stop: # <<<<<<<<<<<<<< + * if stop < 0: + * stop += shape */ - /*else*/ { - __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src)); + goto __pyx_L13; + } - /* "View.MemoryView":731 - * else: - * slice_copy(memview, &src) - * p_src = &src # <<<<<<<<<<<<<< - * - * + /* "View.MemoryView":854 + * stop = shape + * else: + * if negative_step: # <<<<<<<<<<<<<< + * stop = -1 + * else: */ - __pyx_v_p_src = (&__pyx_v_src); - } - __pyx_L3:; + /*else*/ { + if (__pyx_v_negative_step) { - /* "View.MemoryView":737 - * + /* "View.MemoryView":855 + * else: + * if negative_step: + * stop = -1 # <<<<<<<<<<<<<< + * else: + * stop = shape + */ + __pyx_v_stop = -1L; + + /* "View.MemoryView":854 + * stop = shape + * else: + * if negative_step: # <<<<<<<<<<<<<< + * stop = -1 + * else: + */ + goto __pyx_L16; + } + + /* "View.MemoryView":857 + * stop = -1 + * else: + * stop = shape # <<<<<<<<<<<<<< * - * dst.memview = p_src.memview # <<<<<<<<<<<<<< - * dst.data = p_src.data * */ - __pyx_t_4 = __pyx_v_p_src->memview; - __pyx_v_dst.memview = __pyx_t_4; + /*else*/ { + __pyx_v_stop = __pyx_v_shape; + } + __pyx_L16:; + } + __pyx_L13:; - /* "View.MemoryView":738 - * - * dst.memview = p_src.memview - * dst.data = p_src.data # <<<<<<<<<<<<<< + /* "View.MemoryView":861 * + * with cython.cdivision(True): + * new_shape = (stop - start) // step # <<<<<<<<<<<<<< * + * if (stop - start) - step * new_shape: */ - __pyx_t_5 = __pyx_v_p_src->data; - __pyx_v_dst.data = __pyx_t_5; + __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step); - /* "View.MemoryView":743 + /* "View.MemoryView":863 + * new_shape = (stop - start) // step * + * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<< + * new_shape += 1 * - * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<< - * cdef int *p_suboffset_dim = &suboffset_dim - * cdef Py_ssize_t start, stop, step */ - __pyx_v_p_dst = (&__pyx_v_dst); + __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0); + if (__pyx_t_2) { - /* "View.MemoryView":744 + /* "View.MemoryView":864 * - * cdef __Pyx_memviewslice *p_dst = &dst - * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<< - * cdef Py_ssize_t start, stop, step - * cdef bint have_start, have_stop, have_step + * if (stop - start) - step * new_shape: + * new_shape += 1 # <<<<<<<<<<<<<< + * + * if new_shape < 0: */ - __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim); + __pyx_v_new_shape = (__pyx_v_new_shape + 1); - /* "View.MemoryView":748 - * cdef bint have_start, have_stop, have_step + /* "View.MemoryView":863 + * new_shape = (stop - start) // step + * + * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<< + * new_shape += 1 * - * for dim, index in enumerate(indices): # <<<<<<<<<<<<<< - * if PyIndex_Check(index): - * slice_memviewslice( */ - __pyx_t_6 = 0; - if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) { - __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0; - __pyx_t_8 = NULL; - } else { - __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 748, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 748, __pyx_L1_error) - } - for (;;) { - if (likely(!__pyx_t_8)) { - if (likely(PyList_CheckExact(__pyx_t_3))) { - if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) __PYX_ERR(2, 748, __pyx_L1_error) - #else - __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 748, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - #endif - } else { - if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) __PYX_ERR(2, 748, __pyx_L1_error) - #else - __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 748, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - #endif - } - } else { - __pyx_t_9 = __pyx_t_8(__pyx_t_3); - if (unlikely(!__pyx_t_9)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(2, 748, __pyx_L1_error) - } - break; - } - __Pyx_GOTREF(__pyx_t_9); } - __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9); - __pyx_t_9 = 0; - __pyx_v_dim = __pyx_t_6; - __pyx_t_6 = (__pyx_t_6 + 1); - /* "View.MemoryView":749 + /* "View.MemoryView":866 + * new_shape += 1 + * + * if new_shape < 0: # <<<<<<<<<<<<<< + * new_shape = 0 * - * for dim, index in enumerate(indices): - * if PyIndex_Check(index): # <<<<<<<<<<<<<< - * slice_memviewslice( - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], */ - __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0); + __pyx_t_2 = (__pyx_v_new_shape < 0); if (__pyx_t_2) { - /* "View.MemoryView":753 - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - * dim, new_ndim, p_suboffset_dim, - * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<< - * 0, 0, 0, # have_{start,stop,step} - * False) - */ - __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 753, __pyx_L1_error) - - /* "View.MemoryView":750 - * for dim, index in enumerate(indices): - * if PyIndex_Check(index): - * slice_memviewslice( # <<<<<<<<<<<<<< - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - * dim, new_ndim, p_suboffset_dim, + /* "View.MemoryView":867 + * + * if new_shape < 0: + * new_shape = 0 # <<<<<<<<<<<<<< + * + * */ - __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(2, 750, __pyx_L1_error) + __pyx_v_new_shape = 0; - /* "View.MemoryView":749 + /* "View.MemoryView":866 + * new_shape += 1 + * + * if new_shape < 0: # <<<<<<<<<<<<<< + * new_shape = 0 * - * for dim, index in enumerate(indices): - * if PyIndex_Check(index): # <<<<<<<<<<<<<< - * slice_memviewslice( - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], */ - goto __pyx_L6; } - /* "View.MemoryView":756 - * 0, 0, 0, # have_{start,stop,step} - * False) - * elif index is None: # <<<<<<<<<<<<<< - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 - */ - __pyx_t_2 = (__pyx_v_index == Py_None); - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":757 - * False) - * elif index is None: - * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<< - * p_dst.strides[new_ndim] = 0 - * p_dst.suboffsets[new_ndim] = -1 - */ - (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1; - - /* "View.MemoryView":758 - * elif index is None: - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<< - * p_dst.suboffsets[new_ndim] = -1 - * new_ndim += 1 - */ - (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0; - - /* "View.MemoryView":759 - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 - * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<< - * new_ndim += 1 - * else: - */ - (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1L; - - /* "View.MemoryView":760 - * p_dst.strides[new_ndim] = 0 - * p_dst.suboffsets[new_ndim] = -1 - * new_ndim += 1 # <<<<<<<<<<<<<< - * else: - * start = index.start or 0 - */ - __pyx_v_new_ndim = (__pyx_v_new_ndim + 1); - - /* "View.MemoryView":756 - * 0, 0, 0, # have_{start,stop,step} - * False) - * elif index is None: # <<<<<<<<<<<<<< - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 - */ - goto __pyx_L6; - } - - /* "View.MemoryView":762 - * new_ndim += 1 - * else: - * start = index.start or 0 # <<<<<<<<<<<<<< - * stop = index.stop or 0 - * step = index.step or 0 - */ - /*else*/ { - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 762, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 762, __pyx_L1_error) - if (!__pyx_t_1) { - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } else { - __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 762, __pyx_L1_error) - __pyx_t_10 = __pyx_t_12; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - goto __pyx_L7_bool_binop_done; - } - __pyx_t_10 = 0; - __pyx_L7_bool_binop_done:; - __pyx_v_start = __pyx_t_10; - - /* "View.MemoryView":763 - * else: - * start = index.start or 0 - * stop = index.stop or 0 # <<<<<<<<<<<<<< - * step = index.step or 0 + /* "View.MemoryView":870 * - */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 763, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 763, __pyx_L1_error) - if (!__pyx_t_1) { - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } else { - __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 763, __pyx_L1_error) - __pyx_t_10 = __pyx_t_12; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_10 = 0; - __pyx_L9_bool_binop_done:; - __pyx_v_stop = __pyx_t_10; - - /* "View.MemoryView":764 - * start = index.start or 0 - * stop = index.stop or 0 - * step = index.step or 0 # <<<<<<<<<<<<<< * - * have_start = index.start is not None + * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<< + * dst.shape[new_ndim] = new_shape + * dst.suboffsets[new_ndim] = suboffset */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 764, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 764, __pyx_L1_error) - if (!__pyx_t_1) { - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } else { - __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 764, __pyx_L1_error) - __pyx_t_10 = __pyx_t_12; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - goto __pyx_L11_bool_binop_done; - } - __pyx_t_10 = 0; - __pyx_L11_bool_binop_done:; - __pyx_v_step = __pyx_t_10; + (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step); - /* "View.MemoryView":766 - * step = index.step or 0 + /* "View.MemoryView":871 + * + * dst.strides[new_ndim] = stride * step + * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<< + * dst.suboffsets[new_ndim] = suboffset * - * have_start = index.start is not None # <<<<<<<<<<<<<< - * have_stop = index.stop is not None - * have_step = index.step is not None */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 766, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = (__pyx_t_9 != Py_None); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __pyx_v_have_start = __pyx_t_1; + (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape; - /* "View.MemoryView":767 + /* "View.MemoryView":872 + * dst.strides[new_ndim] = stride * step + * dst.shape[new_ndim] = new_shape + * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<< * - * have_start = index.start is not None - * have_stop = index.stop is not None # <<<<<<<<<<<<<< - * have_step = index.step is not None * */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 767, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = (__pyx_t_9 != Py_None); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __pyx_v_have_stop = __pyx_t_1; + (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset; + } + __pyx_L3:; - /* "View.MemoryView":768 - * have_start = index.start is not None - * have_stop = index.stop is not None - * have_step = index.step is not None # <<<<<<<<<<<<<< + /* "View.MemoryView":875 * - * slice_memviewslice( + * + * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<< + * dst.data += start * stride + * else: */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 768, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = (__pyx_t_9 != Py_None); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __pyx_v_have_step = __pyx_t_1; + __pyx_t_2 = ((__pyx_v_suboffset_dim[0]) < 0); + if (__pyx_t_2) { - /* "View.MemoryView":770 - * have_step = index.step is not None + /* "View.MemoryView":876 * - * slice_memviewslice( # <<<<<<<<<<<<<< - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - * dim, new_ndim, p_suboffset_dim, + * if suboffset_dim[0] < 0: + * dst.data += start * stride # <<<<<<<<<<<<<< + * else: + * dst.suboffsets[suboffset_dim[0]] += start * stride */ - __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(2, 770, __pyx_L1_error) + __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride)); - /* "View.MemoryView":776 - * have_start, have_stop, have_step, - * True) - * new_ndim += 1 # <<<<<<<<<<<<<< + /* "View.MemoryView":875 * - * if isinstance(memview, _memoryviewslice): + * + * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<< + * dst.data += start * stride + * else: */ - __pyx_v_new_ndim = (__pyx_v_new_ndim + 1); - } - __pyx_L6:; + goto __pyx_L19; + } - /* "View.MemoryView":748 - * cdef bint have_start, have_stop, have_step + /* "View.MemoryView":878 + * dst.data += start * stride + * else: + * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<< * - * for dim, index in enumerate(indices): # <<<<<<<<<<<<<< - * if PyIndex_Check(index): - * slice_memviewslice( + * if suboffset >= 0: */ + /*else*/ { + __pyx_t_3 = (__pyx_v_suboffset_dim[0]); + (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride)); } - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_L19:; - /* "View.MemoryView":778 - * new_ndim += 1 + /* "View.MemoryView":880 + * dst.suboffsets[suboffset_dim[0]] += start * stride * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, + * if suboffset >= 0: # <<<<<<<<<<<<<< + * if not is_slice: + * if new_ndim == 0: */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - __pyx_t_2 = (__pyx_t_1 != 0); + __pyx_t_2 = (__pyx_v_suboffset >= 0); if (__pyx_t_2) { - /* "View.MemoryView":779 + /* "View.MemoryView":881 * - * if isinstance(memview, _memoryviewslice): - * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<< - * memviewsliceobj.to_object_func, - * memviewsliceobj.to_dtype_func, + * if suboffset >= 0: + * if not is_slice: # <<<<<<<<<<<<<< + * if new_ndim == 0: + * dst.data = ( dst.data)[0] + suboffset */ - __Pyx_XDECREF(((PyObject *)__pyx_r)); + __pyx_t_2 = (!__pyx_v_is_slice); + if (__pyx_t_2) { - /* "View.MemoryView":780 - * if isinstance(memview, _memoryviewslice): - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<< - * memviewsliceobj.to_dtype_func, - * memview.dtype_is_object) + /* "View.MemoryView":882 + * if suboffset >= 0: + * if not is_slice: + * if new_ndim == 0: # <<<<<<<<<<<<<< + * dst.data = ( dst.data)[0] + suboffset + * else: */ - if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); __PYX_ERR(2, 780, __pyx_L1_error) } + __pyx_t_2 = (__pyx_v_new_ndim == 0); + if (__pyx_t_2) { - /* "View.MemoryView":781 - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, - * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<< - * memview.dtype_is_object) - * else: + /* "View.MemoryView":883 + * if not is_slice: + * if new_ndim == 0: + * dst.data = ( dst.data)[0] + suboffset # <<<<<<<<<<<<<< + * else: + * _err_dim(PyExc_IndexError, "All dimensions preceding dimension %d " */ - if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); __PYX_ERR(2, 781, __pyx_L1_error) } + __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset); - /* "View.MemoryView":779 - * - * if isinstance(memview, _memoryviewslice): - * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<< - * memviewsliceobj.to_object_func, - * memviewsliceobj.to_dtype_func, + /* "View.MemoryView":882 + * if suboffset >= 0: + * if not is_slice: + * if new_ndim == 0: # <<<<<<<<<<<<<< + * dst.data = ( dst.data)[0] + suboffset + * else: */ - __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 779, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) __PYX_ERR(2, 779, __pyx_L1_error) - __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3); - __pyx_t_3 = 0; - goto __pyx_L0; + goto __pyx_L22; + } - /* "View.MemoryView":778 - * new_ndim += 1 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, + /* "View.MemoryView":885 + * dst.data = ( dst.data)[0] + suboffset + * else: + * _err_dim(PyExc_IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<< + * "must be indexed and not sliced", dim) + * else: */ - } + /*else*/ { - /* "View.MemoryView":784 - * memview.dtype_is_object) - * else: - * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<< - * memview.dtype_is_object) - * + /* "View.MemoryView":886 + * else: + * _err_dim(PyExc_IndexError, "All dimensions preceding dimension %d " + * "must be indexed and not sliced", dim) # <<<<<<<<<<<<<< + * else: + * suboffset_dim[0] = new_ndim */ - /*else*/ { - __Pyx_XDECREF(((PyObject *)__pyx_r)); + __pyx_t_3 = __pyx_memoryview_err_dim(PyExc_IndexError, __pyx_kp_s_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(1, 885, __pyx_L1_error) + } + __pyx_L22:; - /* "View.MemoryView":785 - * else: - * return memoryview_fromslice(dst, new_ndim, NULL, NULL, - * memview.dtype_is_object) # <<<<<<<<<<<<<< - * + /* "View.MemoryView":881 * + * if suboffset >= 0: + * if not is_slice: # <<<<<<<<<<<<<< + * if new_ndim == 0: + * dst.data = ( dst.data)[0] + suboffset */ - __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 784, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); + goto __pyx_L21; + } - /* "View.MemoryView":784 - * memview.dtype_is_object) - * else: - * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<< - * memview.dtype_is_object) + /* "View.MemoryView":888 + * "must be indexed and not sliced", dim) + * else: + * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<< * + * return 0 + */ + /*else*/ { + (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim; + } + __pyx_L21:; + + /* "View.MemoryView":880 + * dst.suboffsets[suboffset_dim[0]] += start * stride + * + * if suboffset >= 0: # <<<<<<<<<<<<<< + * if not is_slice: + * if new_ndim == 0: */ - if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) __PYX_ERR(2, 784, __pyx_L1_error) - __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3); - __pyx_t_3 = 0; - goto __pyx_L0; } - /* "View.MemoryView":712 + /* "View.MemoryView":890 + * suboffset_dim[0] = new_ndim * - * @cname('__pyx_memview_slice') - * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<< - * cdef int new_ndim = 0, suboffset_dim = -1, dim - * cdef bint negative_step + * return 0 # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "View.MemoryView":793 + * + * @cname('__pyx_memoryview_slice_memviewslice') + * cdef int slice_memviewslice( # <<<<<<<<<<<<<< + * __Pyx_memviewslice *dst, + * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, */ /* function exit code */ __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; + #ifdef WITH_THREAD + __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj); - __Pyx_XDECREF(__pyx_v_index); - __Pyx_XGIVEREF((PyObject *)__pyx_r); - __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":809 +/* "View.MemoryView":896 * - * @cname('__pyx_memoryview_slice_memviewslice') - * cdef int slice_memviewslice( # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, + * @cname('__pyx_pybuffer_index') + * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<< + * Py_ssize_t dim) except NULL: + * cdef Py_ssize_t shape, stride, suboffset = -1 */ -static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) { - Py_ssize_t __pyx_v_new_shape; - int __pyx_v_negative_step; - int __pyx_r; - int __pyx_t_1; +static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) { + Py_ssize_t __pyx_v_shape; + Py_ssize_t __pyx_v_stride; + Py_ssize_t __pyx_v_suboffset; + Py_ssize_t __pyx_v_itemsize; + char *__pyx_v_resultp; + char *__pyx_r; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; int __pyx_t_2; - int __pyx_t_3; + PyObject *__pyx_t_3 = NULL; + Py_UCS4 __pyx_t_4; + PyObject *__pyx_t_5 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("pybuffer_index", 1); - /* "View.MemoryView":829 - * cdef bint negative_step - * - * if not is_slice: # <<<<<<<<<<<<<< - * - * if start < 0: + /* "View.MemoryView":898 + * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, + * Py_ssize_t dim) except NULL: + * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<< + * cdef Py_ssize_t itemsize = view.itemsize + * cdef char *resultp */ - __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0); - if (__pyx_t_1) { + __pyx_v_suboffset = -1L; - /* "View.MemoryView":831 - * if not is_slice: + /* "View.MemoryView":899 + * Py_ssize_t dim) except NULL: + * cdef Py_ssize_t shape, stride, suboffset = -1 + * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<< + * cdef char *resultp * - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if not 0 <= start < shape: */ - __pyx_t_1 = ((__pyx_v_start < 0) != 0); - if (__pyx_t_1) { + __pyx_t_1 = __pyx_v_view->itemsize; + __pyx_v_itemsize = __pyx_t_1; - /* "View.MemoryView":832 + /* "View.MemoryView":902 + * cdef char *resultp * - * if start < 0: - * start += shape # <<<<<<<<<<<<<< - * if not 0 <= start < shape: - * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) + * if view.ndim == 0: # <<<<<<<<<<<<<< + * shape = view.len // itemsize + * stride = itemsize */ - __pyx_v_start = (__pyx_v_start + __pyx_v_shape); + __pyx_t_2 = (__pyx_v_view->ndim == 0); + if (__pyx_t_2) { - /* "View.MemoryView":831 - * if not is_slice: + /* "View.MemoryView":903 * - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if not 0 <= start < shape: - */ - } - - /* "View.MemoryView":833 - * if start < 0: - * start += shape - * if not 0 <= start < shape: # <<<<<<<<<<<<<< - * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) + * if view.ndim == 0: + * shape = view.len // itemsize # <<<<<<<<<<<<<< + * stride = itemsize * else: */ - __pyx_t_1 = (0 <= __pyx_v_start); - if (__pyx_t_1) { - __pyx_t_1 = (__pyx_v_start < __pyx_v_shape); + if (unlikely(__pyx_v_itemsize == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); + __PYX_ERR(1, 903, __pyx_L1_error) } - __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":834 - * start += shape - * if not 0 <= start < shape: - * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<< - * else: - * - */ - __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, ((char *)"Index out of bounds (axis %d)"), __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(2, 834, __pyx_L1_error) + else if (sizeof(Py_ssize_t) == sizeof(long) && (!(((Py_ssize_t)-1) > 0)) && unlikely(__pyx_v_itemsize == (Py_ssize_t)-1) && unlikely(__Pyx_UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) { + PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); + __PYX_ERR(1, 903, __pyx_L1_error) + } + __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize); - /* "View.MemoryView":833 - * if start < 0: - * start += shape - * if not 0 <= start < shape: # <<<<<<<<<<<<<< - * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) + /* "View.MemoryView":904 + * if view.ndim == 0: + * shape = view.len // itemsize + * stride = itemsize # <<<<<<<<<<<<<< * else: + * shape = view.shape[dim] */ - } + __pyx_v_stride = __pyx_v_itemsize; - /* "View.MemoryView":829 - * cdef bint negative_step - * - * if not is_slice: # <<<<<<<<<<<<<< + /* "View.MemoryView":902 + * cdef char *resultp * - * if start < 0: + * if view.ndim == 0: # <<<<<<<<<<<<<< + * shape = view.len // itemsize + * stride = itemsize */ goto __pyx_L3; } - /* "View.MemoryView":837 + /* "View.MemoryView":906 + * stride = itemsize * else: - * - * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<< - * - * if have_step and step == 0: + * shape = view.shape[dim] # <<<<<<<<<<<<<< + * stride = view.strides[dim] + * if view.suboffsets != NULL: */ /*else*/ { - __pyx_t_1 = ((__pyx_v_have_step != 0) != 0); - if (__pyx_t_1) { - } else { - __pyx_t_2 = __pyx_t_1; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_1 = ((__pyx_v_step < 0) != 0); - __pyx_t_2 = __pyx_t_1; - __pyx_L6_bool_binop_done:; - __pyx_v_negative_step = __pyx_t_2; + __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]); - /* "View.MemoryView":839 - * negative_step = have_step != 0 and step < 0 - * - * if have_step and step == 0: # <<<<<<<<<<<<<< - * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) + /* "View.MemoryView":907 + * else: + * shape = view.shape[dim] + * stride = view.strides[dim] # <<<<<<<<<<<<<< + * if view.suboffsets != NULL: + * suboffset = view.suboffsets[dim] + */ + __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]); + + /* "View.MemoryView":908 + * shape = view.shape[dim] + * stride = view.strides[dim] + * if view.suboffsets != NULL: # <<<<<<<<<<<<<< + * suboffset = view.suboffsets[dim] * */ - __pyx_t_1 = (__pyx_v_have_step != 0); - if (__pyx_t_1) { - } else { - __pyx_t_2 = __pyx_t_1; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_1 = ((__pyx_v_step == 0) != 0); - __pyx_t_2 = __pyx_t_1; - __pyx_L9_bool_binop_done:; + __pyx_t_2 = (__pyx_v_view->suboffsets != NULL); if (__pyx_t_2) { - /* "View.MemoryView":840 - * - * if have_step and step == 0: - * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<< - * + /* "View.MemoryView":909 + * stride = view.strides[dim] + * if view.suboffsets != NULL: + * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<< * + * if index < 0: */ - __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, ((char *)"Step may not be zero (axis %d)"), __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(2, 840, __pyx_L1_error) + __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]); - /* "View.MemoryView":839 - * negative_step = have_step != 0 and step < 0 - * - * if have_step and step == 0: # <<<<<<<<<<<<<< - * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) + /* "View.MemoryView":908 + * shape = view.shape[dim] + * stride = view.strides[dim] + * if view.suboffsets != NULL: # <<<<<<<<<<<<<< + * suboffset = view.suboffsets[dim] * */ } + } + __pyx_L3:; - /* "View.MemoryView":843 - * + /* "View.MemoryView":911 + * suboffset = view.suboffsets[dim] * - * if have_start: # <<<<<<<<<<<<<< - * if start < 0: - * start += shape + * if index < 0: # <<<<<<<<<<<<<< + * index += view.shape[dim] + * if index < 0: */ - __pyx_t_2 = (__pyx_v_have_start != 0); - if (__pyx_t_2) { + __pyx_t_2 = (__pyx_v_index < 0); + if (__pyx_t_2) { - /* "View.MemoryView":844 + /* "View.MemoryView":912 * - * if have_start: - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if start < 0: + * if index < 0: + * index += view.shape[dim] # <<<<<<<<<<<<<< + * if index < 0: + * raise IndexError, f"Out of bounds on buffer access (axis {dim})" */ - __pyx_t_2 = ((__pyx_v_start < 0) != 0); - if (__pyx_t_2) { + __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim])); - /* "View.MemoryView":845 - * if have_start: - * if start < 0: - * start += shape # <<<<<<<<<<<<<< - * if start < 0: - * start = 0 + /* "View.MemoryView":913 + * if index < 0: + * index += view.shape[dim] + * if index < 0: # <<<<<<<<<<<<<< + * raise IndexError, f"Out of bounds on buffer access (axis {dim})" + * */ - __pyx_v_start = (__pyx_v_start + __pyx_v_shape); + __pyx_t_2 = (__pyx_v_index < 0); + if (unlikely(__pyx_t_2)) { - /* "View.MemoryView":846 - * if start < 0: - * start += shape - * if start < 0: # <<<<<<<<<<<<<< - * start = 0 - * elif start >= shape: + /* "View.MemoryView":914 + * index += view.shape[dim] + * if index < 0: + * raise IndexError, f"Out of bounds on buffer access (axis {dim})" # <<<<<<<<<<<<<< + * + * if index >= shape: */ - __pyx_t_2 = ((__pyx_v_start < 0) != 0); - if (__pyx_t_2) { + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = 0; + __pyx_t_4 = 127; + __Pyx_INCREF(__pyx_kp_u_Out_of_bounds_on_buffer_access_a); + __pyx_t_1 += 37; + __Pyx_GIVEREF(__pyx_kp_u_Out_of_bounds_on_buffer_access_a); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Out_of_bounds_on_buffer_access_a); + __pyx_t_5 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_dim, 0, ' ', 'd'); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5); + __pyx_t_5 = 0; + __Pyx_INCREF(__pyx_kp_u__7); + __pyx_t_1 += 1; + __Pyx_GIVEREF(__pyx_kp_u__7); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__7); + __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_builtin_IndexError, __pyx_t_5, 0, 0); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __PYX_ERR(1, 914, __pyx_L1_error) - /* "View.MemoryView":847 - * start += shape - * if start < 0: - * start = 0 # <<<<<<<<<<<<<< - * elif start >= shape: - * if negative_step: + /* "View.MemoryView":913 + * if index < 0: + * index += view.shape[dim] + * if index < 0: # <<<<<<<<<<<<<< + * raise IndexError, f"Out of bounds on buffer access (axis {dim})" + * */ - __pyx_v_start = 0; + } - /* "View.MemoryView":846 - * if start < 0: - * start += shape - * if start < 0: # <<<<<<<<<<<<<< - * start = 0 - * elif start >= shape: + /* "View.MemoryView":911 + * suboffset = view.suboffsets[dim] + * + * if index < 0: # <<<<<<<<<<<<<< + * index += view.shape[dim] + * if index < 0: */ - } + } - /* "View.MemoryView":844 + /* "View.MemoryView":916 + * raise IndexError, f"Out of bounds on buffer access (axis {dim})" + * + * if index >= shape: # <<<<<<<<<<<<<< + * raise IndexError, f"Out of bounds on buffer access (axis {dim})" * - * if have_start: - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if start < 0: */ - goto __pyx_L12; - } + __pyx_t_2 = (__pyx_v_index >= __pyx_v_shape); + if (unlikely(__pyx_t_2)) { - /* "View.MemoryView":848 - * if start < 0: - * start = 0 - * elif start >= shape: # <<<<<<<<<<<<<< - * if negative_step: - * start = shape - 1 + /* "View.MemoryView":917 + * + * if index >= shape: + * raise IndexError, f"Out of bounds on buffer access (axis {dim})" # <<<<<<<<<<<<<< + * + * resultp = bufp + index * stride */ - __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0); - if (__pyx_t_2) { + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 917, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_1 = 0; + __pyx_t_4 = 127; + __Pyx_INCREF(__pyx_kp_u_Out_of_bounds_on_buffer_access_a); + __pyx_t_1 += 37; + __Pyx_GIVEREF(__pyx_kp_u_Out_of_bounds_on_buffer_access_a); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_Out_of_bounds_on_buffer_access_a); + __pyx_t_3 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_dim, 0, ' ', 'd'); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 917, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_3); + __pyx_t_3 = 0; + __Pyx_INCREF(__pyx_kp_u__7); + __pyx_t_1 += 1; + __Pyx_GIVEREF(__pyx_kp_u__7); + PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u__7); + __pyx_t_3 = __Pyx_PyUnicode_Join(__pyx_t_5, 3, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 917, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_Raise(__pyx_builtin_IndexError, __pyx_t_3, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 917, __pyx_L1_error) - /* "View.MemoryView":849 - * start = 0 - * elif start >= shape: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: + /* "View.MemoryView":916 + * raise IndexError, f"Out of bounds on buffer access (axis {dim})" + * + * if index >= shape: # <<<<<<<<<<<<<< + * raise IndexError, f"Out of bounds on buffer access (axis {dim})" + * */ - __pyx_t_2 = (__pyx_v_negative_step != 0); - if (__pyx_t_2) { + } - /* "View.MemoryView":850 - * elif start >= shape: - * if negative_step: - * start = shape - 1 # <<<<<<<<<<<<<< - * else: - * start = shape + /* "View.MemoryView":919 + * raise IndexError, f"Out of bounds on buffer access (axis {dim})" + * + * resultp = bufp + index * stride # <<<<<<<<<<<<<< + * if suboffset >= 0: + * resultp = ( resultp)[0] + suboffset */ - __pyx_v_start = (__pyx_v_shape - 1); + __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride)); - /* "View.MemoryView":849 - * start = 0 - * elif start >= shape: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: + /* "View.MemoryView":920 + * + * resultp = bufp + index * stride + * if suboffset >= 0: # <<<<<<<<<<<<<< + * resultp = ( resultp)[0] + suboffset + * */ - goto __pyx_L14; - } + __pyx_t_2 = (__pyx_v_suboffset >= 0); + if (__pyx_t_2) { - /* "View.MemoryView":852 - * start = shape - 1 - * else: - * start = shape # <<<<<<<<<<<<<< - * else: - * if negative_step: + /* "View.MemoryView":921 + * resultp = bufp + index * stride + * if suboffset >= 0: + * resultp = ( resultp)[0] + suboffset # <<<<<<<<<<<<<< + * + * return resultp */ - /*else*/ { - __pyx_v_start = __pyx_v_shape; - } - __pyx_L14:; + __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset); - /* "View.MemoryView":848 - * if start < 0: - * start = 0 - * elif start >= shape: # <<<<<<<<<<<<<< - * if negative_step: - * start = shape - 1 + /* "View.MemoryView":920 + * + * resultp = bufp + index * stride + * if suboffset >= 0: # <<<<<<<<<<<<<< + * resultp = ( resultp)[0] + suboffset + * */ - } - __pyx_L12:; + } - /* "View.MemoryView":843 + /* "View.MemoryView":923 + * resultp = ( resultp)[0] + suboffset + * + * return resultp # <<<<<<<<<<<<<< * * - * if have_start: # <<<<<<<<<<<<<< - * if start < 0: - * start += shape */ - goto __pyx_L11; - } + __pyx_r = __pyx_v_resultp; + goto __pyx_L0; - /* "View.MemoryView":854 - * start = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: + /* "View.MemoryView":896 + * + * @cname('__pyx_pybuffer_index') + * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<< + * Py_ssize_t dim) except NULL: + * cdef Py_ssize_t shape, stride, suboffset = -1 */ - /*else*/ { - __pyx_t_2 = (__pyx_v_negative_step != 0); - if (__pyx_t_2) { - /* "View.MemoryView":855 - * else: - * if negative_step: - * start = shape - 1 # <<<<<<<<<<<<<< - * else: - * start = 0 - */ - __pyx_v_start = (__pyx_v_shape - 1); + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":854 - * start = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: +/* "View.MemoryView":929 + * + * @cname('__pyx_memslice_transpose') + * cdef int transpose_memslice(__Pyx_memviewslice *memslice) except -1 nogil: # <<<<<<<<<<<<<< + * cdef int ndim = memslice.memview.view.ndim + * */ - goto __pyx_L15; - } - /* "View.MemoryView":857 - * start = shape - 1 - * else: - * start = 0 # <<<<<<<<<<<<<< +static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) { + int __pyx_v_ndim; + Py_ssize_t *__pyx_v_shape; + Py_ssize_t *__pyx_v_strides; + int __pyx_v_i; + int __pyx_v_j; + int __pyx_r; + int __pyx_t_1; + Py_ssize_t *__pyx_t_2; + long __pyx_t_3; + long __pyx_t_4; + Py_ssize_t __pyx_t_5; + Py_ssize_t __pyx_t_6; + int __pyx_t_7; + int __pyx_t_8; + int __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save; + #endif + + /* "View.MemoryView":930 + * @cname('__pyx_memslice_transpose') + * cdef int transpose_memslice(__Pyx_memviewslice *memslice) except -1 nogil: + * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<< * - * if have_stop: + * cdef Py_ssize_t *shape = memslice.shape */ - /*else*/ { - __pyx_v_start = 0; - } - __pyx_L15:; - } - __pyx_L11:; + __pyx_t_1 = __pyx_v_memslice->memview->view.ndim; + __pyx_v_ndim = __pyx_t_1; - /* "View.MemoryView":859 - * start = 0 + /* "View.MemoryView":932 + * cdef int ndim = memslice.memview.view.ndim + * + * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<< + * cdef Py_ssize_t *strides = memslice.strides * - * if have_stop: # <<<<<<<<<<<<<< - * if stop < 0: - * stop += shape */ - __pyx_t_2 = (__pyx_v_have_stop != 0); - if (__pyx_t_2) { + __pyx_t_2 = __pyx_v_memslice->shape; + __pyx_v_shape = __pyx_t_2; - /* "View.MemoryView":860 + /* "View.MemoryView":933 + * + * cdef Py_ssize_t *shape = memslice.shape + * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<< + * * - * if have_stop: - * if stop < 0: # <<<<<<<<<<<<<< - * stop += shape - * if stop < 0: */ - __pyx_t_2 = ((__pyx_v_stop < 0) != 0); - if (__pyx_t_2) { + __pyx_t_2 = __pyx_v_memslice->strides; + __pyx_v_strides = __pyx_t_2; - /* "View.MemoryView":861 - * if have_stop: - * if stop < 0: - * stop += shape # <<<<<<<<<<<<<< - * if stop < 0: - * stop = 0 + /* "View.MemoryView":937 + * + * cdef int i, j + * for i in range(ndim // 2): # <<<<<<<<<<<<<< + * j = ndim - 1 - i + * strides[i], strides[j] = strides[j], strides[i] */ - __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape); + __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2); + __pyx_t_4 = __pyx_t_3; + for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_4; __pyx_t_1+=1) { + __pyx_v_i = __pyx_t_1; - /* "View.MemoryView":862 - * if stop < 0: - * stop += shape - * if stop < 0: # <<<<<<<<<<<<<< - * stop = 0 - * elif stop > shape: + /* "View.MemoryView":938 + * cdef int i, j + * for i in range(ndim // 2): + * j = ndim - 1 - i # <<<<<<<<<<<<<< + * strides[i], strides[j] = strides[j], strides[i] + * shape[i], shape[j] = shape[j], shape[i] */ - __pyx_t_2 = ((__pyx_v_stop < 0) != 0); - if (__pyx_t_2) { + __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i); - /* "View.MemoryView":863 - * stop += shape - * if stop < 0: - * stop = 0 # <<<<<<<<<<<<<< - * elif stop > shape: - * stop = shape + /* "View.MemoryView":939 + * for i in range(ndim // 2): + * j = ndim - 1 - i + * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<< + * shape[i], shape[j] = shape[j], shape[i] + * */ - __pyx_v_stop = 0; + __pyx_t_5 = (__pyx_v_strides[__pyx_v_j]); + __pyx_t_6 = (__pyx_v_strides[__pyx_v_i]); + (__pyx_v_strides[__pyx_v_i]) = __pyx_t_5; + (__pyx_v_strides[__pyx_v_j]) = __pyx_t_6; - /* "View.MemoryView":862 - * if stop < 0: - * stop += shape - * if stop < 0: # <<<<<<<<<<<<<< - * stop = 0 - * elif stop > shape: - */ - } - - /* "View.MemoryView":860 + /* "View.MemoryView":940 + * j = ndim - 1 - i + * strides[i], strides[j] = strides[j], strides[i] + * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<< * - * if have_stop: - * if stop < 0: # <<<<<<<<<<<<<< - * stop += shape - * if stop < 0: - */ - goto __pyx_L17; - } - - /* "View.MemoryView":864 - * if stop < 0: - * stop = 0 - * elif stop > shape: # <<<<<<<<<<<<<< - * stop = shape - * else: - */ - __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":865 - * stop = 0 - * elif stop > shape: - * stop = shape # <<<<<<<<<<<<<< - * else: - * if negative_step: - */ - __pyx_v_stop = __pyx_v_shape; - - /* "View.MemoryView":864 - * if stop < 0: - * stop = 0 - * elif stop > shape: # <<<<<<<<<<<<<< - * stop = shape - * else: + * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: */ - } - __pyx_L17:; + __pyx_t_6 = (__pyx_v_shape[__pyx_v_j]); + __pyx_t_5 = (__pyx_v_shape[__pyx_v_i]); + (__pyx_v_shape[__pyx_v_i]) = __pyx_t_6; + (__pyx_v_shape[__pyx_v_j]) = __pyx_t_5; - /* "View.MemoryView":859 - * start = 0 + /* "View.MemoryView":942 + * shape[i], shape[j] = shape[j], shape[i] * - * if have_stop: # <<<<<<<<<<<<<< - * if stop < 0: - * stop += shape - */ - goto __pyx_L16; - } - - /* "View.MemoryView":867 - * stop = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * stop = -1 - * else: - */ - /*else*/ { - __pyx_t_2 = (__pyx_v_negative_step != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":868 - * else: - * if negative_step: - * stop = -1 # <<<<<<<<<<<<<< - * else: - * stop = shape - */ - __pyx_v_stop = -1L; - - /* "View.MemoryView":867 - * stop = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * stop = -1 - * else: - */ - goto __pyx_L19; - } - - /* "View.MemoryView":870 - * stop = -1 - * else: - * stop = shape # <<<<<<<<<<<<<< + * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<< + * _err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions") * - * if not have_step: */ - /*else*/ { - __pyx_v_stop = __pyx_v_shape; - } - __pyx_L19:; + __pyx_t_8 = ((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0); + if (!__pyx_t_8) { + } else { + __pyx_t_7 = __pyx_t_8; + goto __pyx_L6_bool_binop_done; } - __pyx_L16:; - - /* "View.MemoryView":872 - * stop = shape - * - * if not have_step: # <<<<<<<<<<<<<< - * step = 1 - * - */ - __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0); - if (__pyx_t_2) { + __pyx_t_8 = ((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0); + __pyx_t_7 = __pyx_t_8; + __pyx_L6_bool_binop_done:; + if (__pyx_t_7) { - /* "View.MemoryView":873 - * - * if not have_step: - * step = 1 # <<<<<<<<<<<<<< + /* "View.MemoryView":943 * + * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: + * _err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<< * + * return 0 */ - __pyx_v_step = 1; + __pyx_t_9 = __pyx_memoryview_err(PyExc_ValueError, __pyx_kp_s_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(1, 943, __pyx_L1_error) - /* "View.MemoryView":872 - * stop = shape + /* "View.MemoryView":942 + * shape[i], shape[j] = shape[j], shape[i] * - * if not have_step: # <<<<<<<<<<<<<< - * step = 1 + * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<< + * _err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions") * */ } + } - /* "View.MemoryView":877 + /* "View.MemoryView":945 + * _err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions") + * + * return 0 # <<<<<<<<<<<<<< * - * with cython.cdivision(True): - * new_shape = (stop - start) // step # <<<<<<<<<<<<<< * - * if (stop - start) - step * new_shape: */ - __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step); + __pyx_r = 0; + goto __pyx_L0; - /* "View.MemoryView":879 - * new_shape = (stop - start) // step + /* "View.MemoryView":929 * - * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<< - * new_shape += 1 + * @cname('__pyx_memslice_transpose') + * cdef int transpose_memslice(__Pyx_memviewslice *memslice) except -1 nogil: # <<<<<<<<<<<<<< + * cdef int ndim = memslice.memview.view.ndim * */ - __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0); - if (__pyx_t_2) { - /* "View.MemoryView":880 + /* function exit code */ + __pyx_L1_error:; + #ifdef WITH_THREAD + __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + __pyx_L0:; + return __pyx_r; +} + +/* "View.MemoryView":963 + * cdef int (*to_dtype_func)(char *, object) except 0 * - * if (stop - start) - step * new_shape: - * new_shape += 1 # <<<<<<<<<<<<<< + * def __dealloc__(self): # <<<<<<<<<<<<<< + * __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1) * - * if new_shape < 0: */ - __pyx_v_new_shape = (__pyx_v_new_shape + 1); - /* "View.MemoryView":879 - * new_shape = (stop - start) // step +/* Python wrapper */ +static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/ +static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +static void __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) { + + /* "View.MemoryView":964 * - * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<< - * new_shape += 1 + * def __dealloc__(self): + * __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<< * + * cdef convert_item_to_object(self, char *itemp): */ - } + __PYX_XCLEAR_MEMVIEW((&__pyx_v_self->from_slice), 1); - /* "View.MemoryView":882 - * new_shape += 1 + /* "View.MemoryView":963 + * cdef int (*to_dtype_func)(char *, object) except 0 * - * if new_shape < 0: # <<<<<<<<<<<<<< - * new_shape = 0 + * def __dealloc__(self): # <<<<<<<<<<<<<< + * __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1) * */ - __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0); - if (__pyx_t_2) { - /* "View.MemoryView":883 - * - * if new_shape < 0: - * new_shape = 0 # <<<<<<<<<<<<<< - * + /* function exit code */ +} + +/* "View.MemoryView":966 + * __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1) * + * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< + * if self.to_object_func != NULL: + * return self.to_object_func(itemp) */ - __pyx_v_new_shape = 0; - /* "View.MemoryView":882 - * new_shape += 1 - * - * if new_shape < 0: # <<<<<<<<<<<<<< - * new_shape = 0 +static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("convert_item_to_object", 1); + + /* "View.MemoryView":967 * + * cdef convert_item_to_object(self, char *itemp): + * if self.to_object_func != NULL: # <<<<<<<<<<<<<< + * return self.to_object_func(itemp) + * else: */ - } + __pyx_t_1 = (__pyx_v_self->to_object_func != NULL); + if (__pyx_t_1) { - /* "View.MemoryView":886 - * - * - * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<< - * dst.shape[new_ndim] = new_shape - * dst.suboffsets[new_ndim] = suboffset + /* "View.MemoryView":968 + * cdef convert_item_to_object(self, char *itemp): + * if self.to_object_func != NULL: + * return self.to_object_func(itemp) # <<<<<<<<<<<<<< + * else: + * return memoryview.convert_item_to_object(self, itemp) */ - (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step); + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 968, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; - /* "View.MemoryView":887 - * - * dst.strides[new_ndim] = stride * step - * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<< - * dst.suboffsets[new_ndim] = suboffset + /* "View.MemoryView":967 * + * cdef convert_item_to_object(self, char *itemp): + * if self.to_object_func != NULL: # <<<<<<<<<<<<<< + * return self.to_object_func(itemp) + * else: */ - (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape; + } - /* "View.MemoryView":888 - * dst.strides[new_ndim] = stride * step - * dst.shape[new_ndim] = new_shape - * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<< - * + /* "View.MemoryView":970 + * return self.to_object_func(itemp) + * else: + * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<< * + * cdef assign_item_from_object(self, char *itemp, object value): */ - (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset; + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 970, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; } - __pyx_L3:; - /* "View.MemoryView":891 + /* "View.MemoryView":966 + * __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1) * - * - * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<< - * dst.data += start * stride - * else: + * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< + * if self.to_object_func != NULL: + * return self.to_object_func(itemp) */ - __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0); - if (__pyx_t_2) { - /* "View.MemoryView":892 - * - * if suboffset_dim[0] < 0: - * dst.data += start * stride # <<<<<<<<<<<<<< - * else: - * dst.suboffsets[suboffset_dim[0]] += start * stride - */ - __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride)); - - /* "View.MemoryView":891 - * - * - * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<< - * dst.data += start * stride - * else: - */ - goto __pyx_L23; - } + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":894 - * dst.data += start * stride - * else: - * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<< +/* "View.MemoryView":972 + * return memoryview.convert_item_to_object(self, itemp) * - * if suboffset >= 0: + * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< + * if self.to_dtype_func != NULL: + * self.to_dtype_func(itemp, value) */ - /*else*/ { - __pyx_t_3 = (__pyx_v_suboffset_dim[0]); - (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride)); - } - __pyx_L23:; - /* "View.MemoryView":896 - * dst.suboffsets[suboffset_dim[0]] += start * stride - * - * if suboffset >= 0: # <<<<<<<<<<<<<< - * if not is_slice: - * if new_ndim == 0: - */ - __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0); - if (__pyx_t_2) { +static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("assign_item_from_object", 1); - /* "View.MemoryView":897 + /* "View.MemoryView":973 * - * if suboffset >= 0: - * if not is_slice: # <<<<<<<<<<<<<< - * if new_ndim == 0: - * dst.data = ( dst.data)[0] + suboffset - */ - __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":898 - * if suboffset >= 0: - * if not is_slice: - * if new_ndim == 0: # <<<<<<<<<<<<<< - * dst.data = ( dst.data)[0] + suboffset - * else: - */ - __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":899 - * if not is_slice: - * if new_ndim == 0: - * dst.data = ( dst.data)[0] + suboffset # <<<<<<<<<<<<<< - * else: - * _err_dim(IndexError, "All dimensions preceding dimension %d " - */ - __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset); - - /* "View.MemoryView":898 - * if suboffset >= 0: - * if not is_slice: - * if new_ndim == 0: # <<<<<<<<<<<<<< - * dst.data = ( dst.data)[0] + suboffset - * else: + * cdef assign_item_from_object(self, char *itemp, object value): + * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<< + * self.to_dtype_func(itemp, value) + * else: */ - goto __pyx_L26; - } + __pyx_t_1 = (__pyx_v_self->to_dtype_func != NULL); + if (__pyx_t_1) { - /* "View.MemoryView":901 - * dst.data = ( dst.data)[0] + suboffset - * else: - * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<< - * "must be indexed and not sliced", dim) + /* "View.MemoryView":974 + * cdef assign_item_from_object(self, char *itemp, object value): + * if self.to_dtype_func != NULL: + * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<< * else: + * memoryview.assign_item_from_object(self, itemp, value) */ - /*else*/ { + __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(1, 974, __pyx_L1_error) - /* "View.MemoryView":902 - * else: - * _err_dim(IndexError, "All dimensions preceding dimension %d " - * "must be indexed and not sliced", dim) # <<<<<<<<<<<<<< + /* "View.MemoryView":973 + * + * cdef assign_item_from_object(self, char *itemp, object value): + * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<< + * self.to_dtype_func(itemp, value) * else: - * suboffset_dim[0] = new_ndim */ - __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, ((char *)"All dimensions preceding dimension %d must be indexed and not sliced"), __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(2, 901, __pyx_L1_error) - } - __pyx_L26:; + goto __pyx_L3; + } - /* "View.MemoryView":897 + /* "View.MemoryView":976 + * self.to_dtype_func(itemp, value) + * else: + * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<< * - * if suboffset >= 0: - * if not is_slice: # <<<<<<<<<<<<<< - * if new_ndim == 0: - * dst.data = ( dst.data)[0] + suboffset + * cdef _get_base(self): */ - goto __pyx_L25; - } + /*else*/ { + __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 976, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_L3:; - /* "View.MemoryView":904 - * "must be indexed and not sliced", dim) - * else: - * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<< + /* "View.MemoryView":972 + * return memoryview.convert_item_to_object(self, itemp) * - * return 0 + * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< + * if self.to_dtype_func != NULL: + * self.to_dtype_func(itemp, value) */ - /*else*/ { - (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim; - } - __pyx_L25:; - /* "View.MemoryView":896 - * dst.suboffsets[suboffset_dim[0]] += start * stride + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "View.MemoryView":978 + * memoryview.assign_item_from_object(self, itemp, value) + * + * cdef _get_base(self): # <<<<<<<<<<<<<< + * return self.from_object * - * if suboffset >= 0: # <<<<<<<<<<<<<< - * if not is_slice: - * if new_ndim == 0: */ - } - /* "View.MemoryView":906 - * suboffset_dim[0] = new_ndim +static PyObject *__pyx_memoryviewslice__get_base(struct __pyx_memoryviewslice_obj *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_get_base", 1); + + /* "View.MemoryView":979 * - * return 0 # <<<<<<<<<<<<<< + * cdef _get_base(self): + * return self.from_object # <<<<<<<<<<<<<< * * */ - __pyx_r = 0; + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->from_object); + __pyx_r = __pyx_v_self->from_object; goto __pyx_L0; - /* "View.MemoryView":809 + /* "View.MemoryView":978 + * memoryview.assign_item_from_object(self, itemp, value) + * + * cdef _get_base(self): # <<<<<<<<<<<<<< + * return self.from_object * - * @cname('__pyx_memoryview_slice_memviewslice') - * cdef int slice_memviewslice( # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, */ /* function exit code */ - __pyx_L1_error:; - { - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - } - __pyx_r = -1; __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":912 - * - * @cname('__pyx_pybuffer_index') - * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<< - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): */ -static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) { - Py_ssize_t __pyx_v_shape; - Py_ssize_t __pyx_v_stride; - Py_ssize_t __pyx_v_suboffset; - Py_ssize_t __pyx_v_itemsize; - char *__pyx_v_resultp; - char *__pyx_r; +/* Python wrapper */ +static PyObject *__pyx_pw___pyx_memoryviewslice_1__reduce_cython__(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*/ +static PyObject *__pyx_pw___pyx_memoryviewslice_1__reduce_cython__(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 +) { + #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("__reduce_cython__ (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); + if (unlikely(__pyx_nargs > 0)) { + __Pyx_RaiseArgtupleInvalid("__reduce_cython__", 1, 0, 0, __pyx_nargs); return NULL;} + if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__reduce_cython__", 0))) return NULL; + __pyx_r = __pyx_pf___pyx_memoryviewslice___reduce_cython__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf___pyx_memoryviewslice___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self) { + PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("pybuffer_index", 0); + __Pyx_RefNannySetupContext("__reduce_cython__", 1); - /* "View.MemoryView":914 - * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<< - * cdef Py_ssize_t itemsize = view.itemsize - * cdef char *resultp + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" */ - __pyx_v_suboffset = -1L; + __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); + __PYX_ERR(1, 2, __pyx_L1_error) - /* "View.MemoryView":915 - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 - * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<< - * cdef char *resultp - * + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): */ - __pyx_t_1 = __pyx_v_view->itemsize; - __pyx_v_itemsize = __pyx_t_1; - /* "View.MemoryView":918 - * cdef char *resultp - * - * if view.ndim == 0: # <<<<<<<<<<<<<< - * shape = view.len / itemsize - * stride = itemsize - */ - __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0); - if (__pyx_t_2) { + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("View.MemoryView._memoryviewslice.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":919 - * - * if view.ndim == 0: - * shape = view.len / itemsize # <<<<<<<<<<<<<< - * stride = itemsize - * else: +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" */ - if (unlikely(__pyx_v_itemsize == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); - __PYX_ERR(2, 919, __pyx_L1_error) + +/* Python wrapper */ +static PyObject *__pyx_pw___pyx_memoryviewslice_3__setstate_cython__(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*/ +static PyObject *__pyx_pw___pyx_memoryviewslice_3__setstate_cython__(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 +) { + CYTHON_UNUSED PyObject *__pyx_v___pyx_state = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (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_pyx_state,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + 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_pyx_state)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 3, __pyx_L3_error) + else goto __pyx_L5_argtuple_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, "__setstate_cython__") < 0)) __PYX_ERR(1, 3, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); } - else if (sizeof(Py_ssize_t) == sizeof(long) && (!(((Py_ssize_t)-1) > 0)) && unlikely(__pyx_v_itemsize == (Py_ssize_t)-1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) { - PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); - __PYX_ERR(2, 919, __pyx_L1_error) + __pyx_v___pyx_state = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__setstate_cython__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 3, __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_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize); - - /* "View.MemoryView":920 - * if view.ndim == 0: - * shape = view.len / itemsize - * stride = itemsize # <<<<<<<<<<<<<< - * else: - * shape = view.shape[dim] - */ - __pyx_v_stride = __pyx_v_itemsize; + } + __Pyx_AddTraceback("View.MemoryView._memoryviewslice.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf___pyx_memoryviewslice_2__setstate_cython__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self), __pyx_v___pyx_state); - /* "View.MemoryView":918 - * cdef char *resultp - * - * if view.ndim == 0: # <<<<<<<<<<<<<< - * shape = view.len / itemsize - * stride = itemsize - */ - goto __pyx_L3; + /* 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; +} - /* "View.MemoryView":922 - * stride = itemsize - * else: - * shape = view.shape[dim] # <<<<<<<<<<<<<< - * stride = view.strides[dim] - * if view.suboffsets != NULL: - */ - /*else*/ { - __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]); +static PyObject *__pyx_pf___pyx_memoryviewslice_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 1); - /* "View.MemoryView":923 - * else: - * shape = view.shape[dim] - * stride = view.strides[dim] # <<<<<<<<<<<<<< - * if view.suboffsets != NULL: - * suboffset = view.suboffsets[dim] + /* "(tree fragment)":4 + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< */ - __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]); + __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); + __PYX_ERR(1, 4, __pyx_L1_error) - /* "View.MemoryView":924 - * shape = view.shape[dim] - * stride = view.strides[dim] - * if view.suboffsets != NULL: # <<<<<<<<<<<<<< - * suboffset = view.suboffsets[dim] - * + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" */ - __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0); - if (__pyx_t_2) { - /* "View.MemoryView":925 - * stride = view.strides[dim] - * if view.suboffsets != NULL: - * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<< - * - * if index < 0: - */ - __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]); + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("View.MemoryView._memoryviewslice.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":924 - * shape = view.shape[dim] - * stride = view.strides[dim] - * if view.suboffsets != NULL: # <<<<<<<<<<<<<< - * suboffset = view.suboffsets[dim] +/* "View.MemoryView":999 * + * @cname('__pyx_memoryview_fromslice') + * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<< + * int ndim, + * object (*to_object_func)(char *), */ - } - } - __pyx_L3:; - /* "View.MemoryView":927 - * suboffset = view.suboffsets[dim] - * - * if index < 0: # <<<<<<<<<<<<<< - * index += view.shape[dim] - * if index < 0: - */ - __pyx_t_2 = ((__pyx_v_index < 0) != 0); - if (__pyx_t_2) { +static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) { + struct __pyx_memoryviewslice_obj *__pyx_v_result = 0; + Py_ssize_t __pyx_v_suboffset; + PyObject *__pyx_v_length = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + __Pyx_TypeInfo *__pyx_t_4; + Py_buffer __pyx_t_5; + Py_ssize_t *__pyx_t_6; + Py_ssize_t *__pyx_t_7; + Py_ssize_t *__pyx_t_8; + Py_ssize_t __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("memoryview_fromslice", 1); - /* "View.MemoryView":928 + /* "View.MemoryView":1007 + * cdef _memoryviewslice result * - * if index < 0: - * index += view.shape[dim] # <<<<<<<<<<<<<< - * if index < 0: - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) - */ - __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim])); - - /* "View.MemoryView":929 - * if index < 0: - * index += view.shape[dim] - * if index < 0: # <<<<<<<<<<<<<< - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) + * if memviewslice.memview == Py_None: # <<<<<<<<<<<<<< + * return None * */ - __pyx_t_2 = ((__pyx_v_index < 0) != 0); - if (unlikely(__pyx_t_2)) { + __pyx_t_1 = (((PyObject *)__pyx_v_memviewslice.memview) == Py_None); + if (__pyx_t_1) { - /* "View.MemoryView":930 - * index += view.shape[dim] - * if index < 0: - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<< + /* "View.MemoryView":1008 + * + * if memviewslice.memview == Py_None: + * return None # <<<<<<<<<<<<<< * - * if index >= shape: - */ - __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 930, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 930, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_IndexError, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 930, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 930, __pyx_L1_error) - - /* "View.MemoryView":929 - * if index < 0: - * index += view.shape[dim] - * if index < 0: # <<<<<<<<<<<<<< - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) * */ - } + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; - /* "View.MemoryView":927 - * suboffset = view.suboffsets[dim] + /* "View.MemoryView":1007 + * cdef _memoryviewslice result + * + * if memviewslice.memview == Py_None: # <<<<<<<<<<<<<< + * return None * - * if index < 0: # <<<<<<<<<<<<<< - * index += view.shape[dim] - * if index < 0: */ } - /* "View.MemoryView":932 - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) + /* "View.MemoryView":1013 * - * if index >= shape: # <<<<<<<<<<<<<< - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) * + * result = _memoryviewslice.__new__(_memoryviewslice, None, 0, dtype_is_object) # <<<<<<<<<<<<<< + * + * result.from_slice = memviewslice */ - __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0); - if (unlikely(__pyx_t_2)) { + __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1013, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 1013, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None)) __PYX_ERR(1, 1013, __pyx_L1_error); + __Pyx_INCREF(__pyx_int_0); + __Pyx_GIVEREF(__pyx_int_0); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0)) __PYX_ERR(1, 1013, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2)) __PYX_ERR(1, 1013, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_2 = ((PyObject *)__pyx_tp_new__memoryviewslice(((PyTypeObject *)__pyx_memoryviewslice_type), __pyx_t_3, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1013, __pyx_L1_error) + __Pyx_GOTREF((PyObject *)__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2); + __pyx_t_2 = 0; - /* "View.MemoryView":933 + /* "View.MemoryView":1015 + * result = _memoryviewslice.__new__(_memoryviewslice, None, 0, dtype_is_object) * - * if index >= shape: - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<< + * result.from_slice = memviewslice # <<<<<<<<<<<<<< + * __PYX_INC_MEMVIEW(&memviewslice, 1) * - * resultp = bufp + index * stride */ - __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 933, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 933, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_IndexError, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 933, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 933, __pyx_L1_error) + __pyx_v_result->from_slice = __pyx_v_memviewslice; - /* "View.MemoryView":932 - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) + /* "View.MemoryView":1016 * - * if index >= shape: # <<<<<<<<<<<<<< - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) + * result.from_slice = memviewslice + * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<< * + * result.from_object = ( memviewslice.memview)._get_base() */ - } + __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1); - /* "View.MemoryView":935 - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) + /* "View.MemoryView":1018 + * __PYX_INC_MEMVIEW(&memviewslice, 1) + * + * result.from_object = ( memviewslice.memview)._get_base() # <<<<<<<<<<<<<< + * result.typeinfo = memviewslice.memview.typeinfo * - * resultp = bufp + index * stride # <<<<<<<<<<<<<< - * if suboffset >= 0: - * resultp = ( resultp)[0] + suboffset */ - __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride)); + __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)((struct __pyx_memoryview_obj *)__pyx_v_memviewslice.memview)->__pyx_vtab)->_get_base(((struct __pyx_memoryview_obj *)__pyx_v_memviewslice.memview)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1018, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_v_result->from_object); + __Pyx_DECREF(__pyx_v_result->from_object); + __pyx_v_result->from_object = __pyx_t_2; + __pyx_t_2 = 0; - /* "View.MemoryView":936 + /* "View.MemoryView":1019 * - * resultp = bufp + index * stride - * if suboffset >= 0: # <<<<<<<<<<<<<< - * resultp = ( resultp)[0] + suboffset + * result.from_object = ( memviewslice.memview)._get_base() + * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<< * + * result.view = memviewslice.memview.view */ - __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0); - if (__pyx_t_2) { + __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo; + __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4; - /* "View.MemoryView":937 - * resultp = bufp + index * stride - * if suboffset >= 0: - * resultp = ( resultp)[0] + suboffset # <<<<<<<<<<<<<< + /* "View.MemoryView":1021 + * result.typeinfo = memviewslice.memview.typeinfo * - * return resultp + * result.view = memviewslice.memview.view # <<<<<<<<<<<<<< + * result.view.buf = memviewslice.data + * result.view.ndim = ndim */ - __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset); + __pyx_t_5 = __pyx_v_memviewslice.memview->view; + __pyx_v_result->__pyx_base.view = __pyx_t_5; - /* "View.MemoryView":936 - * - * resultp = bufp + index * stride - * if suboffset >= 0: # <<<<<<<<<<<<<< - * resultp = ( resultp)[0] + suboffset + /* "View.MemoryView":1022 * + * result.view = memviewslice.memview.view + * result.view.buf = memviewslice.data # <<<<<<<<<<<<<< + * result.view.ndim = ndim + * (<__pyx_buffer *> &result.view).obj = Py_None */ - } + __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data); - /* "View.MemoryView":939 - * resultp = ( resultp)[0] + suboffset - * - * return resultp # <<<<<<<<<<<<<< - * - * + /* "View.MemoryView":1023 + * result.view = memviewslice.memview.view + * result.view.buf = memviewslice.data + * result.view.ndim = ndim # <<<<<<<<<<<<<< + * (<__pyx_buffer *> &result.view).obj = Py_None + * Py_INCREF(Py_None) */ - __pyx_r = __pyx_v_resultp; - goto __pyx_L0; + __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim; - /* "View.MemoryView":912 + /* "View.MemoryView":1024 + * result.view.buf = memviewslice.data + * result.view.ndim = ndim + * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<< + * Py_INCREF(Py_None) * - * @cname('__pyx_pybuffer_index') - * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<< - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 */ + ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None; - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":1025 + * result.view.ndim = ndim + * (<__pyx_buffer *> &result.view).obj = Py_None + * Py_INCREF(Py_None) # <<<<<<<<<<<<<< + * + * if (memviewslice.memview).flags & PyBUF_WRITABLE: + */ + Py_INCREF(Py_None); -/* "View.MemoryView":945 + /* "View.MemoryView":1027 + * Py_INCREF(Py_None) * - * @cname('__pyx_memslice_transpose') - * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<< - * cdef int ndim = memslice.memview.view.ndim + * if (memviewslice.memview).flags & PyBUF_WRITABLE: # <<<<<<<<<<<<<< + * result.flags = PyBUF_RECORDS + * else: + */ + __pyx_t_1 = ((((struct __pyx_memoryview_obj *)__pyx_v_memviewslice.memview)->flags & PyBUF_WRITABLE) != 0); + if (__pyx_t_1) { + + /* "View.MemoryView":1028 * + * if (memviewslice.memview).flags & PyBUF_WRITABLE: + * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<< + * else: + * result.flags = PyBUF_RECORDS_RO */ + __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS; -static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) { - int __pyx_v_ndim; - Py_ssize_t *__pyx_v_shape; - Py_ssize_t *__pyx_v_strides; - int __pyx_v_i; - int __pyx_v_j; - int __pyx_r; - int __pyx_t_1; - Py_ssize_t *__pyx_t_2; - long __pyx_t_3; - long __pyx_t_4; - Py_ssize_t __pyx_t_5; - Py_ssize_t __pyx_t_6; - int __pyx_t_7; - int __pyx_t_8; - int __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; + /* "View.MemoryView":1027 + * Py_INCREF(Py_None) + * + * if (memviewslice.memview).flags & PyBUF_WRITABLE: # <<<<<<<<<<<<<< + * result.flags = PyBUF_RECORDS + * else: + */ + goto __pyx_L4; + } - /* "View.MemoryView":946 - * @cname('__pyx_memslice_transpose') - * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: - * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<< + /* "View.MemoryView":1030 + * result.flags = PyBUF_RECORDS + * else: + * result.flags = PyBUF_RECORDS_RO # <<<<<<<<<<<<<< * - * cdef Py_ssize_t *shape = memslice.shape + * result.view.shape = result.from_slice.shape */ - __pyx_t_1 = __pyx_v_memslice->memview->view.ndim; - __pyx_v_ndim = __pyx_t_1; + /*else*/ { + __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS_RO; + } + __pyx_L4:; - /* "View.MemoryView":948 - * cdef int ndim = memslice.memview.view.ndim + /* "View.MemoryView":1032 + * result.flags = PyBUF_RECORDS_RO * - * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<< - * cdef Py_ssize_t *strides = memslice.strides + * result.view.shape = result.from_slice.shape # <<<<<<<<<<<<<< + * result.view.strides = result.from_slice.strides * */ - __pyx_t_2 = __pyx_v_memslice->shape; - __pyx_v_shape = __pyx_t_2; + __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape); - /* "View.MemoryView":949 + /* "View.MemoryView":1033 * - * cdef Py_ssize_t *shape = memslice.shape - * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<< + * result.view.shape = result.from_slice.shape + * result.view.strides = result.from_slice.strides # <<<<<<<<<<<<<< * * */ - __pyx_t_2 = __pyx_v_memslice->strides; - __pyx_v_strides = __pyx_t_2; + __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides); - /* "View.MemoryView":953 + /* "View.MemoryView":1036 * - * cdef int i, j - * for i in range(ndim / 2): # <<<<<<<<<<<<<< - * j = ndim - 1 - i - * strides[i], strides[j] = strides[j], strides[i] - */ - __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2); - __pyx_t_4 = __pyx_t_3; - for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_4; __pyx_t_1+=1) { - __pyx_v_i = __pyx_t_1; - - /* "View.MemoryView":954 - * cdef int i, j - * for i in range(ndim / 2): - * j = ndim - 1 - i # <<<<<<<<<<<<<< - * strides[i], strides[j] = strides[j], strides[i] - * shape[i], shape[j] = shape[j], shape[i] + * + * result.view.suboffsets = NULL # <<<<<<<<<<<<<< + * for suboffset in result.from_slice.suboffsets[:ndim]: + * if suboffset >= 0: */ - __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i); + __pyx_v_result->__pyx_base.view.suboffsets = NULL; - /* "View.MemoryView":955 - * for i in range(ndim / 2): - * j = ndim - 1 - i - * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<< - * shape[i], shape[j] = shape[j], shape[i] + /* "View.MemoryView":1037 * + * result.view.suboffsets = NULL + * for suboffset in result.from_slice.suboffsets[:ndim]: # <<<<<<<<<<<<<< + * if suboffset >= 0: + * result.view.suboffsets = result.from_slice.suboffsets */ - __pyx_t_5 = (__pyx_v_strides[__pyx_v_j]); - __pyx_t_6 = (__pyx_v_strides[__pyx_v_i]); - (__pyx_v_strides[__pyx_v_i]) = __pyx_t_5; - (__pyx_v_strides[__pyx_v_j]) = __pyx_t_6; + __pyx_t_7 = (__pyx_v_result->from_slice.suboffsets + __pyx_v_ndim); + for (__pyx_t_8 = __pyx_v_result->from_slice.suboffsets; __pyx_t_8 < __pyx_t_7; __pyx_t_8++) { + __pyx_t_6 = __pyx_t_8; + __pyx_v_suboffset = (__pyx_t_6[0]); - /* "View.MemoryView":956 - * j = ndim - 1 - i - * strides[i], strides[j] = strides[j], strides[i] - * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<< - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: + /* "View.MemoryView":1038 + * result.view.suboffsets = NULL + * for suboffset in result.from_slice.suboffsets[:ndim]: + * if suboffset >= 0: # <<<<<<<<<<<<<< + * result.view.suboffsets = result.from_slice.suboffsets + * break */ - __pyx_t_6 = (__pyx_v_shape[__pyx_v_j]); - __pyx_t_5 = (__pyx_v_shape[__pyx_v_i]); - (__pyx_v_shape[__pyx_v_i]) = __pyx_t_6; - (__pyx_v_shape[__pyx_v_j]) = __pyx_t_5; + __pyx_t_1 = (__pyx_v_suboffset >= 0); + if (__pyx_t_1) { - /* "View.MemoryView":958 - * shape[i], shape[j] = shape[j], shape[i] - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<< - * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") + /* "View.MemoryView":1039 + * for suboffset in result.from_slice.suboffsets[:ndim]: + * if suboffset >= 0: + * result.view.suboffsets = result.from_slice.suboffsets # <<<<<<<<<<<<<< + * break * */ - __pyx_t_8 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0); - if (!__pyx_t_8) { - } else { - __pyx_t_7 = __pyx_t_8; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_8 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0); - __pyx_t_7 = __pyx_t_8; - __pyx_L6_bool_binop_done:; - if (__pyx_t_7) { + __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets); - /* "View.MemoryView":959 - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: - * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<< + /* "View.MemoryView":1040 + * if suboffset >= 0: + * result.view.suboffsets = result.from_slice.suboffsets + * break # <<<<<<<<<<<<<< * - * return 1 + * result.view.len = result.view.itemsize */ - __pyx_t_9 = __pyx_memoryview_err(__pyx_builtin_ValueError, ((char *)"Cannot transpose memoryview with indirect dimensions")); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 959, __pyx_L1_error) + goto __pyx_L6_break; - /* "View.MemoryView":958 - * shape[i], shape[j] = shape[j], shape[i] - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<< - * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") - * + /* "View.MemoryView":1038 + * result.view.suboffsets = NULL + * for suboffset in result.from_slice.suboffsets[:ndim]: + * if suboffset >= 0: # <<<<<<<<<<<<<< + * result.view.suboffsets = result.from_slice.suboffsets + * break */ } } + __pyx_L6_break:; - /* "View.MemoryView":961 - * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") - * - * return 1 # <<<<<<<<<<<<<< - * + /* "View.MemoryView":1042 + * break * + * result.view.len = result.view.itemsize # <<<<<<<<<<<<<< + * for length in result.view.shape[:ndim]: + * result.view.len *= length */ - __pyx_r = 1; - goto __pyx_L0; + __pyx_t_9 = __pyx_v_result->__pyx_base.view.itemsize; + __pyx_v_result->__pyx_base.view.len = __pyx_t_9; - /* "View.MemoryView":945 + /* "View.MemoryView":1043 * - * @cname('__pyx_memslice_transpose') - * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<< - * cdef int ndim = memslice.memview.view.ndim + * result.view.len = result.view.itemsize + * for length in result.view.shape[:ndim]: # <<<<<<<<<<<<<< + * result.view.len *= length * */ + __pyx_t_7 = (__pyx_v_result->__pyx_base.view.shape + __pyx_v_ndim); + for (__pyx_t_8 = __pyx_v_result->__pyx_base.view.shape; __pyx_t_8 < __pyx_t_7; __pyx_t_8++) { + __pyx_t_6 = __pyx_t_8; + __pyx_t_2 = PyInt_FromSsize_t((__pyx_t_6[0])); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1043, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_2); + __pyx_t_2 = 0; - /* function exit code */ - __pyx_L1_error:; - { - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif + /* "View.MemoryView":1044 + * result.view.len = result.view.itemsize + * for length in result.view.shape[:ndim]: + * result.view.len *= length # <<<<<<<<<<<<<< + * + * result.to_object_func = to_object_func + */ + __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_result->__pyx_base.view.len); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1044, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_t_2, __pyx_v_length); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 1044, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __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(1, 1044, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_result->__pyx_base.view.len = __pyx_t_9; } - __pyx_r = 0; - __pyx_L0:; - return __pyx_r; -} -/* "View.MemoryView":978 - * cdef int (*to_dtype_func)(char *, object) except 0 + /* "View.MemoryView":1046 + * result.view.len *= length * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) + * result.to_object_func = to_object_func # <<<<<<<<<<<<<< + * result.to_dtype_func = to_dtype_func * */ + __pyx_v_result->to_object_func = __pyx_v_to_object_func; -/* Python wrapper */ -static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__", 0); - - /* "View.MemoryView":979 + /* "View.MemoryView":1047 * - * def __dealloc__(self): - * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<< + * result.to_object_func = to_object_func + * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<< * - * cdef convert_item_to_object(self, char *itemp): + * return result */ - __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1); + __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func; - /* "View.MemoryView":978 - * cdef int (*to_dtype_func)(char *, object) except 0 + /* "View.MemoryView":1049 + * result.to_dtype_func = to_dtype_func * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) + * return result # <<<<<<<<<<<<<< + * + * @cname('__pyx_memoryview_get_slice_from_memoryview') + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF((PyObject *)__pyx_v_result); + __pyx_r = ((PyObject *)__pyx_v_result); + goto __pyx_L0; + + /* "View.MemoryView":999 * + * @cname('__pyx_memoryview_fromslice') + * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<< + * int ndim, + * object (*to_object_func)(char *), */ /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_result); + __Pyx_XDECREF(__pyx_v_length); + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); + return __pyx_r; } -/* "View.MemoryView":981 - * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) +/* "View.MemoryView":1052 * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * if self.to_object_func != NULL: - * return self.to_object_func(itemp) + * @cname('__pyx_memoryview_get_slice_from_memoryview') + * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<< + * __Pyx_memviewslice *mslice) except NULL: + * cdef _memoryviewslice obj */ -static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) { - PyObject *__pyx_r = NULL; +static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) { + struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0; + __Pyx_memviewslice *__pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("convert_item_to_object", 0); + __Pyx_RefNannySetupContext("get_slice_from_memview", 1); - /* "View.MemoryView":982 - * - * cdef convert_item_to_object(self, char *itemp): - * if self.to_object_func != NULL: # <<<<<<<<<<<<<< - * return self.to_object_func(itemp) - * else: + /* "View.MemoryView":1055 + * __Pyx_memviewslice *mslice) except NULL: + * cdef _memoryviewslice obj + * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< + * obj = memview + * return &obj.from_slice */ - __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0); + __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); if (__pyx_t_1) { - /* "View.MemoryView":983 - * cdef convert_item_to_object(self, char *itemp): - * if self.to_object_func != NULL: - * return self.to_object_func(itemp) # <<<<<<<<<<<<<< - * else: - * return memoryview.convert_item_to_object(self, itemp) + /* "View.MemoryView":1056 + * cdef _memoryviewslice obj + * if isinstance(memview, _memoryviewslice): + * obj = memview # <<<<<<<<<<<<<< + * return &obj.from_slice + * else: */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 983, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; + if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) __PYX_ERR(1, 1056, __pyx_L1_error) + __pyx_t_2 = ((PyObject *)__pyx_v_memview); + __Pyx_INCREF(__pyx_t_2); + __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2); __pyx_t_2 = 0; + + /* "View.MemoryView":1057 + * if isinstance(memview, _memoryviewslice): + * obj = memview + * return &obj.from_slice # <<<<<<<<<<<<<< + * else: + * slice_copy(memview, mslice) + */ + __pyx_r = (&__pyx_v_obj->from_slice); goto __pyx_L0; - /* "View.MemoryView":982 - * - * cdef convert_item_to_object(self, char *itemp): - * if self.to_object_func != NULL: # <<<<<<<<<<<<<< - * return self.to_object_func(itemp) - * else: + /* "View.MemoryView":1055 + * __Pyx_memviewslice *mslice) except NULL: + * cdef _memoryviewslice obj + * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< + * obj = memview + * return &obj.from_slice */ } - /* "View.MemoryView":985 - * return self.to_object_func(itemp) - * else: - * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<< + /* "View.MemoryView":1059 + * return &obj.from_slice + * else: + * slice_copy(memview, mslice) # <<<<<<<<<<<<<< + * return mslice * - * cdef assign_item_from_object(self, char *itemp, object value): */ /*else*/ { - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 985, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; + __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice); + + /* "View.MemoryView":1060 + * else: + * slice_copy(memview, mslice) + * return mslice # <<<<<<<<<<<<<< + * + * @cname('__pyx_memoryview_slice_copy') + */ + __pyx_r = __pyx_v_mslice; goto __pyx_L0; } - /* "View.MemoryView":981 - * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) + /* "View.MemoryView":1052 * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * if self.to_object_func != NULL: - * return self.to_object_func(itemp) + * @cname('__pyx_memoryview_get_slice_from_memoryview') + * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<< + * __Pyx_memviewslice *mslice) except NULL: + * cdef _memoryviewslice obj */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; + __Pyx_AddTraceback("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); + __Pyx_XDECREF((PyObject *)__pyx_v_obj); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":987 - * return memoryview.convert_item_to_object(self, itemp) +/* "View.MemoryView":1063 * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * if self.to_dtype_func != NULL: - * self.to_dtype_func(itemp, value) + * @cname('__pyx_memoryview_slice_copy') + * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst) noexcept: # <<<<<<<<<<<<<< + * cdef int dim + * cdef (Py_ssize_t*) shape, strides, suboffsets */ -static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; +static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) { + int __pyx_v_dim; + Py_ssize_t *__pyx_v_shape; + Py_ssize_t *__pyx_v_strides; + Py_ssize_t *__pyx_v_suboffsets; + Py_ssize_t *__pyx_t_1; int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("assign_item_from_object", 0); + int __pyx_t_3; + int __pyx_t_4; + Py_ssize_t __pyx_t_5; + int __pyx_t_6; - /* "View.MemoryView":988 + /* "View.MemoryView":1067 + * cdef (Py_ssize_t*) shape, strides, suboffsets * - * cdef assign_item_from_object(self, char *itemp, object value): - * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<< - * self.to_dtype_func(itemp, value) - * else: + * shape = memview.view.shape # <<<<<<<<<<<<<< + * strides = memview.view.strides + * suboffsets = memview.view.suboffsets */ - __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0); - if (__pyx_t_1) { + __pyx_t_1 = __pyx_v_memview->view.shape; + __pyx_v_shape = __pyx_t_1; - /* "View.MemoryView":989 - * cdef assign_item_from_object(self, char *itemp, object value): - * if self.to_dtype_func != NULL: - * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<< - * else: - * memoryview.assign_item_from_object(self, itemp, value) + /* "View.MemoryView":1068 + * + * shape = memview.view.shape + * strides = memview.view.strides # <<<<<<<<<<<<<< + * suboffsets = memview.view.suboffsets + * */ - __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 989, __pyx_L1_error) + __pyx_t_1 = __pyx_v_memview->view.strides; + __pyx_v_strides = __pyx_t_1; - /* "View.MemoryView":988 + /* "View.MemoryView":1069 + * shape = memview.view.shape + * strides = memview.view.strides + * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<< * - * cdef assign_item_from_object(self, char *itemp, object value): - * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<< - * self.to_dtype_func(itemp, value) - * else: + * dst.memview = <__pyx_memoryview *> memview */ - goto __pyx_L3; - } + __pyx_t_1 = __pyx_v_memview->view.suboffsets; + __pyx_v_suboffsets = __pyx_t_1; - /* "View.MemoryView":991 - * self.to_dtype_func(itemp, value) - * else: - * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<< + /* "View.MemoryView":1071 + * suboffsets = memview.view.suboffsets + * + * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<< + * dst.data = memview.view.buf * - * @property */ - /*else*/ { - __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 991, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_L3:; + __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview); - /* "View.MemoryView":987 - * return memoryview.convert_item_to_object(self, itemp) + /* "View.MemoryView":1072 * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * if self.to_dtype_func != NULL: - * self.to_dtype_func(itemp, value) + * dst.memview = <__pyx_memoryview *> memview + * dst.data = memview.view.buf # <<<<<<<<<<<<<< + * + * for dim in range(memview.view.ndim): */ + __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf); - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":994 + /* "View.MemoryView":1074 + * dst.data = memview.view.buf * - * @property - * def base(self): # <<<<<<<<<<<<<< - * return self.from_object + * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<< + * dst.shape[dim] = shape[dim] + * dst.strides[dim] = strides[dim] + */ + __pyx_t_2 = __pyx_v_memview->view.ndim; + __pyx_t_3 = __pyx_t_2; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_dim = __pyx_t_4; + + /* "View.MemoryView":1075 * + * for dim in range(memview.view.ndim): + * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<< + * dst.strides[dim] = strides[dim] + * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 */ + (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]); -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_16_memoryviewslice_4base_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_16_memoryviewslice_4base_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":995 - * @property - * def base(self): - * return self.from_object # <<<<<<<<<<<<<< + /* "View.MemoryView":1076 + * for dim in range(memview.view.ndim): + * dst.shape[dim] = shape[dim] + * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<< + * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 * - * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->from_object); - __pyx_r = __pyx_v_self->from_object; - goto __pyx_L0; + (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]); - /* "View.MemoryView":994 + /* "View.MemoryView":1077 + * dst.shape[dim] = shape[dim] + * dst.strides[dim] = strides[dim] + * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 # <<<<<<<<<<<<<< * - * @property - * def base(self): # <<<<<<<<<<<<<< - * return self.from_object + * @cname('__pyx_memoryview_copy_object') + */ + __pyx_t_6 = (__pyx_v_suboffsets != 0); + if (__pyx_t_6) { + __pyx_t_5 = (__pyx_v_suboffsets[__pyx_v_dim]); + } else { + __pyx_t_5 = -1L; + } + (__pyx_v_dst->suboffsets[__pyx_v_dim]) = __pyx_t_5; + } + + /* "View.MemoryView":1063 * + * @cname('__pyx_memoryview_slice_copy') + * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst) noexcept: # <<<<<<<<<<<<<< + * cdef int dim + * cdef (Py_ssize_t*) shape, strides, suboffsets */ /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; } -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): +/* "View.MemoryView":1080 + * + * @cname('__pyx_memoryview_copy_object') + * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<< + * "Create a new memoryview object" + * cdef __Pyx_memviewslice memviewslice */ -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryviewslice_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw___pyx_memoryviewslice_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_memoryviewslice___reduce_cython__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_memoryviewslice___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self) { +static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) { + __Pyx_memviewslice __pyx_v_memviewslice; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ + __Pyx_RefNannySetupContext("memoryview_copy", 1); - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + /* "View.MemoryView":1083 + * "Create a new memoryview object" + * cdef __Pyx_memviewslice memviewslice + * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<< + * return memoryview_copy_from_slice(memview, &memviewslice) + * */ + __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice)); -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryviewslice_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw___pyx_memoryviewslice_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_memoryviewslice_2__setstate_cython__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_memoryviewslice_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + /* "View.MemoryView":1084 + * cdef __Pyx_memviewslice memviewslice + * slice_copy(memview, &memviewslice) + * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<< + * + * @cname('__pyx_memoryview_copy_object_from_slice') */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 4, __pyx_L1_error) + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1084, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 4, __pyx_L1_error) + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + /* "View.MemoryView":1080 + * + * @cname('__pyx_memoryview_copy_object') + * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<< + * "Create a new memoryview object" + * cdef __Pyx_memviewslice memviewslice */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; + __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":1001 +/* "View.MemoryView":1087 * - * @cname('__pyx_memoryview_fromslice') - * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<< - * int ndim, - * object (*to_object_func)(char *), + * @cname('__pyx_memoryview_copy_object_from_slice') + * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<< + * """ + * Create a new memoryview object from a given memoryview object and slice. */ -static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) { - struct __pyx_memoryviewslice_obj *__pyx_v_result = 0; - Py_ssize_t __pyx_v_suboffset; - PyObject *__pyx_v_length = NULL; +static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) { + PyObject *(*__pyx_v_to_object_func)(char *); + int (*__pyx_v_to_dtype_func)(char *, PyObject *); PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - __Pyx_TypeInfo *__pyx_t_4; - Py_buffer __pyx_t_5; - Py_ssize_t *__pyx_t_6; - Py_ssize_t *__pyx_t_7; - Py_ssize_t *__pyx_t_8; - Py_ssize_t __pyx_t_9; + PyObject *(*__pyx_t_2)(char *); + int (*__pyx_t_3)(char *, PyObject *); + PyObject *__pyx_t_4 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_fromslice", 0); + __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 1); - /* "View.MemoryView":1009 - * cdef _memoryviewslice result - * - * if memviewslice.memview == Py_None: # <<<<<<<<<<<<<< - * return None + /* "View.MemoryView":1094 + * cdef int (*to_dtype_func)(char *, object) except 0 * + * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< + * to_object_func = (<_memoryviewslice> memview).to_object_func + * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func */ - __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0); + __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); if (__pyx_t_1) { - /* "View.MemoryView":1010 - * - * if memviewslice.memview == Py_None: - * return None # <<<<<<<<<<<<<< - * + /* "View.MemoryView":1095 * + * if isinstance(memview, _memoryviewslice): + * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<< + * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func + * else: */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; + __pyx_t_2 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func; + __pyx_v_to_object_func = __pyx_t_2; - /* "View.MemoryView":1009 - * cdef _memoryviewslice result - * - * if memviewslice.memview == Py_None: # <<<<<<<<<<<<<< - * return None + /* "View.MemoryView":1096 + * if isinstance(memview, _memoryviewslice): + * to_object_func = (<_memoryviewslice> memview).to_object_func + * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<< + * else: + * to_object_func = NULL + */ + __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func; + __pyx_v_to_dtype_func = __pyx_t_3; + + /* "View.MemoryView":1094 + * cdef int (*to_dtype_func)(char *, object) except 0 * + * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< + * to_object_func = (<_memoryviewslice> memview).to_object_func + * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func */ + goto __pyx_L3; } - /* "View.MemoryView":1015 - * - * - * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<< + /* "View.MemoryView":1098 + * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func + * else: + * to_object_func = NULL # <<<<<<<<<<<<<< + * to_dtype_func = NULL * - * result.from_slice = memviewslice */ - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1015, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1015, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2); - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryviewslice_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1015, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2); - __pyx_t_2 = 0; + /*else*/ { + __pyx_v_to_object_func = NULL; - /* "View.MemoryView":1017 - * result = _memoryviewslice(None, 0, dtype_is_object) - * - * result.from_slice = memviewslice # <<<<<<<<<<<<<< - * __PYX_INC_MEMVIEW(&memviewslice, 1) + /* "View.MemoryView":1099 + * else: + * to_object_func = NULL + * to_dtype_func = NULL # <<<<<<<<<<<<<< * + * return memoryview_fromslice(memviewslice[0], memview.view.ndim, */ - __pyx_v_result->from_slice = __pyx_v_memviewslice; + __pyx_v_to_dtype_func = NULL; + } + __pyx_L3:; - /* "View.MemoryView":1018 - * - * result.from_slice = memviewslice - * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<< + /* "View.MemoryView":1101 + * to_dtype_func = NULL * - * result.from_object = ( memviewslice.memview).base + * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<< + * to_object_func, to_dtype_func, + * memview.dtype_is_object) */ - __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1); + __Pyx_XDECREF(__pyx_r); - /* "View.MemoryView":1020 - * __PYX_INC_MEMVIEW(&memviewslice, 1) + /* "View.MemoryView":1103 + * return memoryview_fromslice(memviewslice[0], memview.view.ndim, + * to_object_func, to_dtype_func, + * memview.dtype_is_object) # <<<<<<<<<<<<<< * - * result.from_object = ( memviewslice.memview).base # <<<<<<<<<<<<<< - * result.typeinfo = memviewslice.memview.typeinfo * */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1020, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_result->from_object); - __Pyx_DECREF(__pyx_v_result->from_object); - __pyx_v_result->from_object = __pyx_t_2; - __pyx_t_2 = 0; + __pyx_t_4 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 1101, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; - /* "View.MemoryView":1021 - * - * result.from_object = ( memviewslice.memview).base - * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<< + /* "View.MemoryView":1087 * - * result.view = memviewslice.memview.view + * @cname('__pyx_memoryview_copy_object_from_slice') + * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<< + * """ + * Create a new memoryview object from a given memoryview object and slice. */ - __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo; - __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4; - /* "View.MemoryView":1023 - * result.typeinfo = memviewslice.memview.typeinfo - * - * result.view = memviewslice.memview.view # <<<<<<<<<<<<<< - * result.view.buf = memviewslice.data - * result.view.ndim = ndim - */ - __pyx_t_5 = __pyx_v_memviewslice.memview->view; - __pyx_v_result->__pyx_base.view = __pyx_t_5; + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":1024 +/* "View.MemoryView":1109 + * + * + * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) noexcept nogil: # <<<<<<<<<<<<<< + * return -arg if arg < 0 else arg * - * result.view = memviewslice.memview.view - * result.view.buf = memviewslice.data # <<<<<<<<<<<<<< - * result.view.ndim = ndim - * (<__pyx_buffer *> &result.view).obj = Py_None */ - __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data); - /* "View.MemoryView":1025 - * result.view = memviewslice.memview.view - * result.view.buf = memviewslice.data - * result.view.ndim = ndim # <<<<<<<<<<<<<< - * (<__pyx_buffer *> &result.view).obj = Py_None - * Py_INCREF(Py_None) - */ - __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim; +static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) { + Py_ssize_t __pyx_r; + Py_ssize_t __pyx_t_1; + int __pyx_t_2; - /* "View.MemoryView":1026 - * result.view.buf = memviewslice.data - * result.view.ndim = ndim - * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<< - * Py_INCREF(Py_None) + /* "View.MemoryView":1110 * + * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) noexcept nogil: + * return -arg if arg < 0 else arg # <<<<<<<<<<<<<< + * + * @cname('__pyx_get_best_slice_order') */ - ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None; + __pyx_t_2 = (__pyx_v_arg < 0); + if (__pyx_t_2) { + __pyx_t_1 = (-__pyx_v_arg); + } else { + __pyx_t_1 = __pyx_v_arg; + } + __pyx_r = __pyx_t_1; + goto __pyx_L0; - /* "View.MemoryView":1027 - * result.view.ndim = ndim - * (<__pyx_buffer *> &result.view).obj = Py_None - * Py_INCREF(Py_None) # <<<<<<<<<<<<<< + /* "View.MemoryView":1109 + * + * + * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) noexcept nogil: # <<<<<<<<<<<<<< + * return -arg if arg < 0 else arg * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: */ - Py_INCREF(Py_None); - /* "View.MemoryView":1029 - * Py_INCREF(Py_None) + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "View.MemoryView":1113 * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: # <<<<<<<<<<<<<< - * result.flags = PyBUF_RECORDS - * else: + * @cname('__pyx_get_best_slice_order') + * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) noexcept nogil: # <<<<<<<<<<<<<< + * """ + * Figure out the best memory access order for a given slice. */ - __pyx_t_1 = ((((struct __pyx_memoryview_obj *)__pyx_v_memviewslice.memview)->flags & PyBUF_WRITABLE) != 0); - if (__pyx_t_1) { - /* "View.MemoryView":1030 +static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) { + int __pyx_v_i; + Py_ssize_t __pyx_v_c_stride; + Py_ssize_t __pyx_v_f_stride; + char __pyx_r; + int __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + int __pyx_t_4; + + /* "View.MemoryView":1118 + * """ + * cdef int i + * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<< + * cdef Py_ssize_t f_stride = 0 * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: - * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<< - * else: - * result.flags = PyBUF_RECORDS_RO */ - __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS; + __pyx_v_c_stride = 0; - /* "View.MemoryView":1029 - * Py_INCREF(Py_None) + /* "View.MemoryView":1119 + * cdef int i + * cdef Py_ssize_t c_stride = 0 + * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<< * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: # <<<<<<<<<<<<<< - * result.flags = PyBUF_RECORDS - * else: + * for i in range(ndim - 1, -1, -1): */ - goto __pyx_L4; - } + __pyx_v_f_stride = 0; - /* "View.MemoryView":1032 - * result.flags = PyBUF_RECORDS - * else: - * result.flags = PyBUF_RECORDS_RO # <<<<<<<<<<<<<< + /* "View.MemoryView":1121 + * cdef Py_ssize_t f_stride = 0 * - * result.view.shape = result.from_slice.shape + * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< + * if mslice.shape[i] > 1: + * c_stride = mslice.strides[i] */ - /*else*/ { - __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS_RO; - } - __pyx_L4:; + for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) { + __pyx_v_i = __pyx_t_1; - /* "View.MemoryView":1034 - * result.flags = PyBUF_RECORDS_RO - * - * result.view.shape = result.from_slice.shape # <<<<<<<<<<<<<< - * result.view.strides = result.from_slice.strides + /* "View.MemoryView":1122 * + * for i in range(ndim - 1, -1, -1): + * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< + * c_stride = mslice.strides[i] + * break */ - __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape); + __pyx_t_2 = ((__pyx_v_mslice->shape[__pyx_v_i]) > 1); + if (__pyx_t_2) { - /* "View.MemoryView":1035 - * - * result.view.shape = result.from_slice.shape - * result.view.strides = result.from_slice.strides # <<<<<<<<<<<<<< - * + /* "View.MemoryView":1123 + * for i in range(ndim - 1, -1, -1): + * if mslice.shape[i] > 1: + * c_stride = mslice.strides[i] # <<<<<<<<<<<<<< + * break * */ - __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides); + __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]); - /* "View.MemoryView":1038 + /* "View.MemoryView":1124 + * if mslice.shape[i] > 1: + * c_stride = mslice.strides[i] + * break # <<<<<<<<<<<<<< * + * for i in range(ndim): + */ + goto __pyx_L4_break; + + /* "View.MemoryView":1122 * - * result.view.suboffsets = NULL # <<<<<<<<<<<<<< - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: + * for i in range(ndim - 1, -1, -1): + * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< + * c_stride = mslice.strides[i] + * break */ - __pyx_v_result->__pyx_base.view.suboffsets = NULL; + } + } + __pyx_L4_break:; - /* "View.MemoryView":1039 + /* "View.MemoryView":1126 + * break * - * result.view.suboffsets = NULL - * for suboffset in result.from_slice.suboffsets[:ndim]: # <<<<<<<<<<<<<< - * if suboffset >= 0: - * result.view.suboffsets = result.from_slice.suboffsets + * for i in range(ndim): # <<<<<<<<<<<<<< + * if mslice.shape[i] > 1: + * f_stride = mslice.strides[i] */ - __pyx_t_7 = (__pyx_v_result->from_slice.suboffsets + __pyx_v_ndim); - for (__pyx_t_8 = __pyx_v_result->from_slice.suboffsets; __pyx_t_8 < __pyx_t_7; __pyx_t_8++) { - __pyx_t_6 = __pyx_t_8; - __pyx_v_suboffset = (__pyx_t_6[0]); + __pyx_t_1 = __pyx_v_ndim; + __pyx_t_3 = __pyx_t_1; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_i = __pyx_t_4; - /* "View.MemoryView":1040 - * result.view.suboffsets = NULL - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * result.view.suboffsets = result.from_slice.suboffsets + /* "View.MemoryView":1127 + * + * for i in range(ndim): + * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< + * f_stride = mslice.strides[i] * break */ - __pyx_t_1 = ((__pyx_v_suboffset >= 0) != 0); - if (__pyx_t_1) { + __pyx_t_2 = ((__pyx_v_mslice->shape[__pyx_v_i]) > 1); + if (__pyx_t_2) { - /* "View.MemoryView":1041 - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: - * result.view.suboffsets = result.from_slice.suboffsets # <<<<<<<<<<<<<< + /* "View.MemoryView":1128 + * for i in range(ndim): + * if mslice.shape[i] > 1: + * f_stride = mslice.strides[i] # <<<<<<<<<<<<<< * break * */ - __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets); + __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]); - /* "View.MemoryView":1042 - * if suboffset >= 0: - * result.view.suboffsets = result.from_slice.suboffsets + /* "View.MemoryView":1129 + * if mslice.shape[i] > 1: + * f_stride = mslice.strides[i] * break # <<<<<<<<<<<<<< * - * result.view.len = result.view.itemsize + * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): */ - goto __pyx_L6_break; + goto __pyx_L7_break; - /* "View.MemoryView":1040 - * result.view.suboffsets = NULL - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * result.view.suboffsets = result.from_slice.suboffsets + /* "View.MemoryView":1127 + * + * for i in range(ndim): + * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< + * f_stride = mslice.strides[i] * break */ } } - __pyx_L6_break:; + __pyx_L7_break:; - /* "View.MemoryView":1044 + /* "View.MemoryView":1131 * break * - * result.view.len = result.view.itemsize # <<<<<<<<<<<<<< - * for length in result.view.shape[:ndim]: - * result.view.len *= length + * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<< + * return 'C' + * else: */ - __pyx_t_9 = __pyx_v_result->__pyx_base.view.itemsize; - __pyx_v_result->__pyx_base.view.len = __pyx_t_9; + __pyx_t_2 = (abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)); + if (__pyx_t_2) { - /* "View.MemoryView":1045 - * - * result.view.len = result.view.itemsize - * for length in result.view.shape[:ndim]: # <<<<<<<<<<<<<< - * result.view.len *= length + /* "View.MemoryView":1132 * + * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): + * return 'C' # <<<<<<<<<<<<<< + * else: + * return 'F' */ - __pyx_t_7 = (__pyx_v_result->__pyx_base.view.shape + __pyx_v_ndim); - for (__pyx_t_8 = __pyx_v_result->__pyx_base.view.shape; __pyx_t_8 < __pyx_t_7; __pyx_t_8++) { - __pyx_t_6 = __pyx_t_8; - __pyx_t_2 = PyInt_FromSsize_t((__pyx_t_6[0])); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1045, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_2); - __pyx_t_2 = 0; + __pyx_r = 'C'; + goto __pyx_L0; - /* "View.MemoryView":1046 - * result.view.len = result.view.itemsize - * for length in result.view.shape[:ndim]: - * result.view.len *= length # <<<<<<<<<<<<<< + /* "View.MemoryView":1131 + * break * - * result.to_object_func = to_object_func + * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<< + * return 'C' + * else: */ - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_result->__pyx_base.view.len); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1046, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_t_2, __pyx_v_length); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1046, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __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(2, 1046, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result->__pyx_base.view.len = __pyx_t_9; } - /* "View.MemoryView":1048 - * result.view.len *= length - * - * result.to_object_func = to_object_func # <<<<<<<<<<<<<< - * result.to_dtype_func = to_dtype_func - * - */ - __pyx_v_result->to_object_func = __pyx_v_to_object_func; - - /* "View.MemoryView":1049 - * - * result.to_object_func = to_object_func - * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<< - * - * return result - */ - __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func; - - /* "View.MemoryView":1051 - * result.to_dtype_func = to_dtype_func - * - * return result # <<<<<<<<<<<<<< + /* "View.MemoryView":1134 + * return 'C' + * else: + * return 'F' # <<<<<<<<<<<<<< * - * @cname('__pyx_memoryview_get_slice_from_memoryview') + * @cython.cdivision(True) */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_result)); - __pyx_r = ((PyObject *)__pyx_v_result); - goto __pyx_L0; + /*else*/ { + __pyx_r = 'F'; + goto __pyx_L0; + } - /* "View.MemoryView":1001 + /* "View.MemoryView":1113 * - * @cname('__pyx_memoryview_fromslice') - * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<< - * int ndim, - * object (*to_object_func)(char *), + * @cname('__pyx_get_best_slice_order') + * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) noexcept nogil: # <<<<<<<<<<<<<< + * """ + * Figure out the best memory access order for a given slice. */ /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XDECREF(__pyx_v_length); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":1054 +/* "View.MemoryView":1137 * - * @cname('__pyx_memoryview_get_slice_from_memoryview') - * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj + * @cython.cdivision(True) + * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<< + * char *dst_data, Py_ssize_t *dst_strides, + * Py_ssize_t *src_shape, Py_ssize_t *dst_shape, */ -static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) { - struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0; - __Pyx_memviewslice *__pyx_r; - __Pyx_RefNannyDeclarations +static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) { + CYTHON_UNUSED Py_ssize_t __pyx_v_i; + CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent; + Py_ssize_t __pyx_v_dst_extent; + Py_ssize_t __pyx_v_src_stride; + Py_ssize_t __pyx_v_dst_stride; int __pyx_t_1; int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_slice_from_memview", 0); - - /* "View.MemoryView":1057 - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * obj = memview - * return &obj.from_slice - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { + Py_ssize_t __pyx_t_3; + Py_ssize_t __pyx_t_4; + Py_ssize_t __pyx_t_5; - /* "View.MemoryView":1058 - * cdef _memoryviewslice obj - * if isinstance(memview, _memoryviewslice): - * obj = memview # <<<<<<<<<<<<<< - * return &obj.from_slice - * else: + /* "View.MemoryView":1144 + * + * cdef Py_ssize_t i + * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<< + * cdef Py_ssize_t dst_extent = dst_shape[0] + * cdef Py_ssize_t src_stride = src_strides[0] */ - if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) __PYX_ERR(2, 1058, __pyx_L1_error) - __pyx_t_3 = ((PyObject *)__pyx_v_memview); - __Pyx_INCREF(__pyx_t_3); - __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3); - __pyx_t_3 = 0; + __pyx_v_src_extent = (__pyx_v_src_shape[0]); - /* "View.MemoryView":1059 - * if isinstance(memview, _memoryviewslice): - * obj = memview - * return &obj.from_slice # <<<<<<<<<<<<<< - * else: - * slice_copy(memview, mslice) + /* "View.MemoryView":1145 + * cdef Py_ssize_t i + * cdef Py_ssize_t src_extent = src_shape[0] + * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<< + * cdef Py_ssize_t src_stride = src_strides[0] + * cdef Py_ssize_t dst_stride = dst_strides[0] */ - __pyx_r = (&__pyx_v_obj->from_slice); - goto __pyx_L0; + __pyx_v_dst_extent = (__pyx_v_dst_shape[0]); - /* "View.MemoryView":1057 - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * obj = memview - * return &obj.from_slice + /* "View.MemoryView":1146 + * cdef Py_ssize_t src_extent = src_shape[0] + * cdef Py_ssize_t dst_extent = dst_shape[0] + * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<< + * cdef Py_ssize_t dst_stride = dst_strides[0] + * */ - } + __pyx_v_src_stride = (__pyx_v_src_strides[0]); - /* "View.MemoryView":1061 - * return &obj.from_slice - * else: - * slice_copy(memview, mslice) # <<<<<<<<<<<<<< - * return mslice + /* "View.MemoryView":1147 + * cdef Py_ssize_t dst_extent = dst_shape[0] + * cdef Py_ssize_t src_stride = src_strides[0] + * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<< * + * if ndim == 1: */ - /*else*/ { - __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice); + __pyx_v_dst_stride = (__pyx_v_dst_strides[0]); - /* "View.MemoryView":1062 - * else: - * slice_copy(memview, mslice) - * return mslice # <<<<<<<<<<<<<< + /* "View.MemoryView":1149 + * cdef Py_ssize_t dst_stride = dst_strides[0] * - * @cname('__pyx_memoryview_slice_copy') + * if ndim == 1: # <<<<<<<<<<<<<< + * if (src_stride > 0 and dst_stride > 0 and + * src_stride == itemsize == dst_stride): */ - __pyx_r = __pyx_v_mslice; - goto __pyx_L0; - } + __pyx_t_1 = (__pyx_v_ndim == 1); + if (__pyx_t_1) { - /* "View.MemoryView":1054 + /* "View.MemoryView":1150 * - * @cname('__pyx_memoryview_get_slice_from_memoryview') - * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj + * if ndim == 1: + * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< + * src_stride == itemsize == dst_stride): + * memcpy(dst_data, src_data, itemsize * dst_extent) */ + __pyx_t_2 = (__pyx_v_src_stride > 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L5_bool_binop_done; + } + __pyx_t_2 = (__pyx_v_dst_stride > 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L5_bool_binop_done; + } - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_obj); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "View.MemoryView":1151 + * if ndim == 1: + * if (src_stride > 0 and dst_stride > 0 and + * src_stride == itemsize == dst_stride): # <<<<<<<<<<<<<< + * memcpy(dst_data, src_data, itemsize * dst_extent) + * else: + */ + __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize); + if (__pyx_t_2) { + __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride)); + } + __pyx_t_1 = __pyx_t_2; + __pyx_L5_bool_binop_done:; -/* "View.MemoryView":1065 + /* "View.MemoryView":1150 * - * @cname('__pyx_memoryview_slice_copy') - * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<< - * cdef int dim - * cdef (Py_ssize_t*) shape, strides, suboffsets + * if ndim == 1: + * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< + * src_stride == itemsize == dst_stride): + * memcpy(dst_data, src_data, itemsize * dst_extent) */ + if (__pyx_t_1) { -static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) { - int __pyx_v_dim; - Py_ssize_t *__pyx_v_shape; - Py_ssize_t *__pyx_v_strides; - Py_ssize_t *__pyx_v_suboffsets; - __Pyx_RefNannyDeclarations - Py_ssize_t *__pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - Py_ssize_t __pyx_t_5; - __Pyx_RefNannySetupContext("slice_copy", 0); - - /* "View.MemoryView":1069 - * cdef (Py_ssize_t*) shape, strides, suboffsets - * - * shape = memview.view.shape # <<<<<<<<<<<<<< - * strides = memview.view.strides - * suboffsets = memview.view.suboffsets + /* "View.MemoryView":1152 + * if (src_stride > 0 and dst_stride > 0 and + * src_stride == itemsize == dst_stride): + * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<< + * else: + * for i in range(dst_extent): */ - __pyx_t_1 = __pyx_v_memview->view.shape; - __pyx_v_shape = __pyx_t_1; + (void)(memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent))); - /* "View.MemoryView":1070 - * - * shape = memview.view.shape - * strides = memview.view.strides # <<<<<<<<<<<<<< - * suboffsets = memview.view.suboffsets + /* "View.MemoryView":1150 * + * if ndim == 1: + * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< + * src_stride == itemsize == dst_stride): + * memcpy(dst_data, src_data, itemsize * dst_extent) */ - __pyx_t_1 = __pyx_v_memview->view.strides; - __pyx_v_strides = __pyx_t_1; + goto __pyx_L4; + } - /* "View.MemoryView":1071 - * shape = memview.view.shape - * strides = memview.view.strides - * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<< - * - * dst.memview = <__pyx_memoryview *> memview + /* "View.MemoryView":1154 + * memcpy(dst_data, src_data, itemsize * dst_extent) + * else: + * for i in range(dst_extent): # <<<<<<<<<<<<<< + * memcpy(dst_data, src_data, itemsize) + * src_data += src_stride */ - __pyx_t_1 = __pyx_v_memview->view.suboffsets; - __pyx_v_suboffsets = __pyx_t_1; + /*else*/ { + __pyx_t_3 = __pyx_v_dst_extent; + __pyx_t_4 = __pyx_t_3; + for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_i = __pyx_t_5; - /* "View.MemoryView":1073 - * suboffsets = memview.view.suboffsets - * - * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<< - * dst.data = memview.view.buf - * + /* "View.MemoryView":1155 + * else: + * for i in range(dst_extent): + * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<< + * src_data += src_stride + * dst_data += dst_stride */ - __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview); + (void)(memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize)); - /* "View.MemoryView":1074 - * - * dst.memview = <__pyx_memoryview *> memview - * dst.data = memview.view.buf # <<<<<<<<<<<<<< - * - * for dim in range(memview.view.ndim): + /* "View.MemoryView":1156 + * for i in range(dst_extent): + * memcpy(dst_data, src_data, itemsize) + * src_data += src_stride # <<<<<<<<<<<<<< + * dst_data += dst_stride + * else: */ - __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf); + __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride); - /* "View.MemoryView":1076 - * dst.data = memview.view.buf - * - * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<< - * dst.shape[dim] = shape[dim] - * dst.strides[dim] = strides[dim] + /* "View.MemoryView":1157 + * memcpy(dst_data, src_data, itemsize) + * src_data += src_stride + * dst_data += dst_stride # <<<<<<<<<<<<<< + * else: + * for i in range(dst_extent): */ - __pyx_t_2 = __pyx_v_memview->view.ndim; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_dim = __pyx_t_4; + __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride); + } + } + __pyx_L4:; - /* "View.MemoryView":1077 + /* "View.MemoryView":1149 + * cdef Py_ssize_t dst_stride = dst_strides[0] * - * for dim in range(memview.view.ndim): - * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<< - * dst.strides[dim] = strides[dim] - * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 + * if ndim == 1: # <<<<<<<<<<<<<< + * if (src_stride > 0 and dst_stride > 0 and + * src_stride == itemsize == dst_stride): */ - (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]); + goto __pyx_L3; + } - /* "View.MemoryView":1078 - * for dim in range(memview.view.ndim): - * dst.shape[dim] = shape[dim] - * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<< - * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 + /* "View.MemoryView":1159 + * dst_data += dst_stride + * else: + * for i in range(dst_extent): # <<<<<<<<<<<<<< + * _copy_strided_to_strided(src_data, src_strides + 1, + * dst_data, dst_strides + 1, + */ + /*else*/ { + __pyx_t_3 = __pyx_v_dst_extent; + __pyx_t_4 = __pyx_t_3; + for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_i = __pyx_t_5; + + /* "View.MemoryView":1160 + * else: + * for i in range(dst_extent): + * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<< + * dst_data, dst_strides + 1, + * src_shape + 1, dst_shape + 1, + */ + _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize); + + /* "View.MemoryView":1164 + * src_shape + 1, dst_shape + 1, + * ndim - 1, itemsize) + * src_data += src_stride # <<<<<<<<<<<<<< + * dst_data += dst_stride * */ - (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]); + __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride); - /* "View.MemoryView":1079 - * dst.shape[dim] = shape[dim] - * dst.strides[dim] = strides[dim] - * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 # <<<<<<<<<<<<<< + /* "View.MemoryView":1165 + * ndim - 1, itemsize) + * src_data += src_stride + * dst_data += dst_stride # <<<<<<<<<<<<<< * - * @cname('__pyx_memoryview_copy_object') + * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, */ - if ((__pyx_v_suboffsets != 0)) { - __pyx_t_5 = (__pyx_v_suboffsets[__pyx_v_dim]); - } else { - __pyx_t_5 = -1L; + __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride); } - (__pyx_v_dst->suboffsets[__pyx_v_dim]) = __pyx_t_5; } + __pyx_L3:; - /* "View.MemoryView":1065 + /* "View.MemoryView":1137 * - * @cname('__pyx_memoryview_slice_copy') - * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<< - * cdef int dim - * cdef (Py_ssize_t*) shape, strides, suboffsets + * @cython.cdivision(True) + * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<< + * char *dst_data, Py_ssize_t *dst_strides, + * Py_ssize_t *src_shape, Py_ssize_t *dst_shape, */ /* function exit code */ - __Pyx_RefNannyFinishContext(); } -/* "View.MemoryView":1082 +/* "View.MemoryView":1167 + * dst_data += dst_stride * - * @cname('__pyx_memoryview_copy_object') - * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<< - * "Create a new memoryview object" - * cdef __Pyx_memviewslice memviewslice + * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< + * __Pyx_memviewslice *dst, + * int ndim, size_t itemsize) noexcept nogil: */ -static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) { - __Pyx_memviewslice __pyx_v_memviewslice; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_copy", 0); - - /* "View.MemoryView":1085 - * "Create a new memoryview object" - * cdef __Pyx_memviewslice memviewslice - * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<< - * return memoryview_copy_from_slice(memview, &memviewslice) - * - */ - __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice)); +static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) { - /* "View.MemoryView":1086 - * cdef __Pyx_memviewslice memviewslice - * slice_copy(memview, &memviewslice) - * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<< + /* "View.MemoryView":1170 + * __Pyx_memviewslice *dst, + * int ndim, size_t itemsize) noexcept nogil: + * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<< + * src.shape, dst.shape, ndim, itemsize) * - * @cname('__pyx_memoryview_copy_object_from_slice') */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1086, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; + _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize); - /* "View.MemoryView":1082 + /* "View.MemoryView":1167 + * dst_data += dst_stride * - * @cname('__pyx_memoryview_copy_object') - * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<< - * "Create a new memoryview object" - * cdef __Pyx_memviewslice memviewslice + * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< + * __Pyx_memviewslice *dst, + * int ndim, size_t itemsize) noexcept nogil: */ /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; } -/* "View.MemoryView":1089 +/* "View.MemoryView":1174 * - * @cname('__pyx_memoryview_copy_object_from_slice') - * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<< - * """ - * Create a new memoryview object from a given memoryview object and slice. + * @cname('__pyx_memoryview_slice_get_size') + * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) noexcept nogil: # <<<<<<<<<<<<<< + * "Return the size of the memory occupied by the slice in number of bytes" + * cdef Py_ssize_t shape, size = src.memview.view.itemsize */ -static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) { - PyObject *(*__pyx_v_to_object_func)(char *); - int (*__pyx_v_to_dtype_func)(char *, PyObject *); - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *(*__pyx_t_3)(char *); - int (*__pyx_t_4)(char *, PyObject *); - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0); +static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) { + Py_ssize_t __pyx_v_shape; + Py_ssize_t __pyx_v_size; + Py_ssize_t __pyx_r; + Py_ssize_t __pyx_t_1; + Py_ssize_t *__pyx_t_2; + Py_ssize_t *__pyx_t_3; + Py_ssize_t *__pyx_t_4; - /* "View.MemoryView":1096 - * cdef int (*to_dtype_func)(char *, object) except 0 + /* "View.MemoryView":1176 + * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) noexcept nogil: + * "Return the size of the memory occupied by the slice in number of bytes" + * cdef Py_ssize_t shape, size = src.memview.view.itemsize # <<<<<<<<<<<<<< * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * to_object_func = (<_memoryviewslice> memview).to_object_func - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func + * for shape in src.shape[:ndim]: */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { + __pyx_t_1 = __pyx_v_src->memview->view.itemsize; + __pyx_v_size = __pyx_t_1; - /* "View.MemoryView":1097 + /* "View.MemoryView":1178 + * cdef Py_ssize_t shape, size = src.memview.view.itemsize * - * if isinstance(memview, _memoryviewslice): - * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<< - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func - * else: - */ - __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func; - __pyx_v_to_object_func = __pyx_t_3; - - /* "View.MemoryView":1098 - * if isinstance(memview, _memoryviewslice): - * to_object_func = (<_memoryviewslice> memview).to_object_func - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<< - * else: - * to_object_func = NULL - */ - __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func; - __pyx_v_to_dtype_func = __pyx_t_4; - - /* "View.MemoryView":1096 - * cdef int (*to_dtype_func)(char *, object) except 0 + * for shape in src.shape[:ndim]: # <<<<<<<<<<<<<< + * size *= shape * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * to_object_func = (<_memoryviewslice> memview).to_object_func - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func */ - goto __pyx_L3; - } + __pyx_t_3 = (__pyx_v_src->shape + __pyx_v_ndim); + for (__pyx_t_4 = __pyx_v_src->shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { + __pyx_t_2 = __pyx_t_4; + __pyx_v_shape = (__pyx_t_2[0]); - /* "View.MemoryView":1100 - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func - * else: - * to_object_func = NULL # <<<<<<<<<<<<<< - * to_dtype_func = NULL + /* "View.MemoryView":1179 * - */ - /*else*/ { - __pyx_v_to_object_func = NULL; - - /* "View.MemoryView":1101 - * else: - * to_object_func = NULL - * to_dtype_func = NULL # <<<<<<<<<<<<<< + * for shape in src.shape[:ndim]: + * size *= shape # <<<<<<<<<<<<<< * - * return memoryview_fromslice(memviewslice[0], memview.view.ndim, + * return size */ - __pyx_v_to_dtype_func = NULL; + __pyx_v_size = (__pyx_v_size * __pyx_v_shape); } - __pyx_L3:; - - /* "View.MemoryView":1103 - * to_dtype_func = NULL - * - * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<< - * to_object_func, to_dtype_func, - * memview.dtype_is_object) - */ - __Pyx_XDECREF(__pyx_r); - /* "View.MemoryView":1105 - * return memoryview_fromslice(memviewslice[0], memview.view.ndim, - * to_object_func, to_dtype_func, - * memview.dtype_is_object) # <<<<<<<<<<<<<< + /* "View.MemoryView":1181 + * size *= shape * + * return size # <<<<<<<<<<<<<< * + * @cname('__pyx_fill_contig_strides_array') */ - __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 1103, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; + __pyx_r = __pyx_v_size; goto __pyx_L0; - /* "View.MemoryView":1089 + /* "View.MemoryView":1174 * - * @cname('__pyx_memoryview_copy_object_from_slice') - * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<< - * """ - * Create a new memoryview object from a given memoryview object and slice. + * @cname('__pyx_memoryview_slice_get_size') + * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) noexcept nogil: # <<<<<<<<<<<<<< + * "Return the size of the memory occupied by the slice in number of bytes" + * cdef Py_ssize_t shape, size = src.memview.view.itemsize */ /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":1111 - * +/* "View.MemoryView":1184 * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<< - * if arg < 0: - * return -arg + * @cname('__pyx_fill_contig_strides_array') + * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<< + * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, + * int ndim, char order) noexcept nogil: */ -static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) { +static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) { + int __pyx_v_idx; Py_ssize_t __pyx_r; int __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + int __pyx_t_4; - /* "View.MemoryView":1112 + /* "View.MemoryView":1193 + * cdef int idx * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: - * if arg < 0: # <<<<<<<<<<<<<< - * return -arg - * else: - */ - __pyx_t_1 = ((__pyx_v_arg < 0) != 0); + * if order == 'F': # <<<<<<<<<<<<<< + * for idx in range(ndim): + * strides[idx] = stride + */ + __pyx_t_1 = (__pyx_v_order == 'F'); if (__pyx_t_1) { - /* "View.MemoryView":1113 - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: - * if arg < 0: - * return -arg # <<<<<<<<<<<<<< + /* "View.MemoryView":1194 + * + * if order == 'F': + * for idx in range(ndim): # <<<<<<<<<<<<<< + * strides[idx] = stride + * stride *= shape[idx] + */ + __pyx_t_2 = __pyx_v_ndim; + __pyx_t_3 = __pyx_t_2; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_idx = __pyx_t_4; + + /* "View.MemoryView":1195 + * if order == 'F': + * for idx in range(ndim): + * strides[idx] = stride # <<<<<<<<<<<<<< + * stride *= shape[idx] + * else: + */ + (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride; + + /* "View.MemoryView":1196 + * for idx in range(ndim): + * strides[idx] = stride + * stride *= shape[idx] # <<<<<<<<<<<<<< * else: - * return arg + * for idx in range(ndim - 1, -1, -1): */ - __pyx_r = (-__pyx_v_arg); - goto __pyx_L0; + __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx])); + } - /* "View.MemoryView":1112 + /* "View.MemoryView":1193 + * cdef int idx * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: - * if arg < 0: # <<<<<<<<<<<<<< - * return -arg - * else: + * if order == 'F': # <<<<<<<<<<<<<< + * for idx in range(ndim): + * strides[idx] = stride */ + goto __pyx_L3; } - /* "View.MemoryView":1115 - * return -arg + /* "View.MemoryView":1198 + * stride *= shape[idx] * else: - * return arg # <<<<<<<<<<<<<< - * - * @cname('__pyx_get_best_slice_order') + * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< + * strides[idx] = stride + * stride *= shape[idx] */ /*else*/ { - __pyx_r = __pyx_v_arg; - goto __pyx_L0; + for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) { + __pyx_v_idx = __pyx_t_2; + + /* "View.MemoryView":1199 + * else: + * for idx in range(ndim - 1, -1, -1): + * strides[idx] = stride # <<<<<<<<<<<<<< + * stride *= shape[idx] + * + */ + (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride; + + /* "View.MemoryView":1200 + * for idx in range(ndim - 1, -1, -1): + * strides[idx] = stride + * stride *= shape[idx] # <<<<<<<<<<<<<< + * + * return stride + */ + __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx])); + } } + __pyx_L3:; - /* "View.MemoryView":1111 + /* "View.MemoryView":1202 + * stride *= shape[idx] + * + * return stride # <<<<<<<<<<<<<< * + * @cname('__pyx_memoryview_copy_data_to_temp') + */ + __pyx_r = __pyx_v_stride; + goto __pyx_L0; + + /* "View.MemoryView":1184 * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<< - * if arg < 0: - * return -arg + * @cname('__pyx_fill_contig_strides_array') + * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<< + * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, + * int ndim, char order) noexcept nogil: */ /* function exit code */ @@ -14702,4626 +16035,6984 @@ static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) { return __pyx_r; } -/* "View.MemoryView":1118 +/* "View.MemoryView":1205 * - * @cname('__pyx_get_best_slice_order') - * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<< - * """ - * Figure out the best memory access order for a given slice. + * @cname('__pyx_memoryview_copy_data_to_temp') + * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< + * __Pyx_memviewslice *tmpslice, + * char order, */ -static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) { +static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) { int __pyx_v_i; - Py_ssize_t __pyx_v_c_stride; - Py_ssize_t __pyx_v_f_stride; - char __pyx_r; - int __pyx_t_1; + void *__pyx_v_result; + size_t __pyx_v_itemsize; + size_t __pyx_v_size; + void *__pyx_r; + Py_ssize_t __pyx_t_1; int __pyx_t_2; int __pyx_t_3; - int __pyx_t_4; + struct __pyx_memoryview_obj *__pyx_t_4; + int __pyx_t_5; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save; + #endif - /* "View.MemoryView":1123 - * """ - * cdef int i - * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<< - * cdef Py_ssize_t f_stride = 0 + /* "View.MemoryView":1216 + * cdef void *result * - */ - __pyx_v_c_stride = 0; - - /* "View.MemoryView":1124 - * cdef int i - * cdef Py_ssize_t c_stride = 0 - * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<< + * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<< + * cdef size_t size = slice_get_size(src, ndim) * - * for i in range(ndim - 1, -1, -1): */ - __pyx_v_f_stride = 0; + __pyx_t_1 = __pyx_v_src->memview->view.itemsize; + __pyx_v_itemsize = __pyx_t_1; - /* "View.MemoryView":1126 - * cdef Py_ssize_t f_stride = 0 + /* "View.MemoryView":1217 * - * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< - * if mslice.shape[i] > 1: - * c_stride = mslice.strides[i] + * cdef size_t itemsize = src.memview.view.itemsize + * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<< + * + * result = malloc(size) */ - for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) { - __pyx_v_i = __pyx_t_1; + __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim); - /* "View.MemoryView":1127 + /* "View.MemoryView":1219 + * cdef size_t size = slice_get_size(src, ndim) * - * for i in range(ndim - 1, -1, -1): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * c_stride = mslice.strides[i] - * break + * result = malloc(size) # <<<<<<<<<<<<<< + * if not result: + * _err_no_memory() */ - __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0); - if (__pyx_t_2) { + __pyx_v_result = malloc(__pyx_v_size); - /* "View.MemoryView":1128 - * for i in range(ndim - 1, -1, -1): - * if mslice.shape[i] > 1: - * c_stride = mslice.strides[i] # <<<<<<<<<<<<<< - * break + /* "View.MemoryView":1220 + * + * result = malloc(size) + * if not result: # <<<<<<<<<<<<<< + * _err_no_memory() * */ - __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]); + __pyx_t_2 = (!(__pyx_v_result != 0)); + if (__pyx_t_2) { - /* "View.MemoryView":1129 - * if mslice.shape[i] > 1: - * c_stride = mslice.strides[i] - * break # <<<<<<<<<<<<<< + /* "View.MemoryView":1221 + * result = malloc(size) + * if not result: + * _err_no_memory() # <<<<<<<<<<<<<< + * * - * for i in range(ndim): */ - goto __pyx_L4_break; + __pyx_t_3 = __pyx_memoryview_err_no_memory(); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(1, 1221, __pyx_L1_error) - /* "View.MemoryView":1127 + /* "View.MemoryView":1220 + * + * result = malloc(size) + * if not result: # <<<<<<<<<<<<<< + * _err_no_memory() * - * for i in range(ndim - 1, -1, -1): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * c_stride = mslice.strides[i] - * break */ - } } - __pyx_L4_break:; - /* "View.MemoryView":1131 - * break + /* "View.MemoryView":1224 * - * for i in range(ndim): # <<<<<<<<<<<<<< - * if mslice.shape[i] > 1: - * f_stride = mslice.strides[i] + * + * tmpslice.data = result # <<<<<<<<<<<<<< + * tmpslice.memview = src.memview + * for i in range(ndim): */ - __pyx_t_1 = __pyx_v_ndim; - __pyx_t_3 = __pyx_t_1; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; + __pyx_v_tmpslice->data = ((char *)__pyx_v_result); - /* "View.MemoryView":1132 + /* "View.MemoryView":1225 * + * tmpslice.data = result + * tmpslice.memview = src.memview # <<<<<<<<<<<<<< * for i in range(ndim): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * f_stride = mslice.strides[i] - * break + * tmpslice.shape[i] = src.shape[i] */ - __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0); - if (__pyx_t_2) { + __pyx_t_4 = __pyx_v_src->memview; + __pyx_v_tmpslice->memview = __pyx_t_4; - /* "View.MemoryView":1133 - * for i in range(ndim): - * if mslice.shape[i] > 1: - * f_stride = mslice.strides[i] # <<<<<<<<<<<<<< - * break - * + /* "View.MemoryView":1226 + * tmpslice.data = result + * tmpslice.memview = src.memview + * for i in range(ndim): # <<<<<<<<<<<<<< + * tmpslice.shape[i] = src.shape[i] + * tmpslice.suboffsets[i] = -1 */ - __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]); + __pyx_t_3 = __pyx_v_ndim; + __pyx_t_5 = __pyx_t_3; + for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { + __pyx_v_i = __pyx_t_6; - /* "View.MemoryView":1134 - * if mslice.shape[i] > 1: - * f_stride = mslice.strides[i] - * break # <<<<<<<<<<<<<< + /* "View.MemoryView":1227 + * tmpslice.memview = src.memview + * for i in range(ndim): + * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<< + * tmpslice.suboffsets[i] = -1 * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): */ - goto __pyx_L7_break; + (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]); - /* "View.MemoryView":1132 - * + /* "View.MemoryView":1228 * for i in range(ndim): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * f_stride = mslice.strides[i] - * break + * tmpslice.shape[i] = src.shape[i] + * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<< + * + * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, ndim, order) */ - } + (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1L; } - __pyx_L7_break:; - /* "View.MemoryView":1136 - * break + /* "View.MemoryView":1230 + * tmpslice.suboffsets[i] = -1 + * + * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, ndim, order) # <<<<<<<<<<<<<< + * * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<< - * return 'C' - * else: */ - __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0); - if (__pyx_t_2) { + (void)(__pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order)); - /* "View.MemoryView":1137 + /* "View.MemoryView":1233 * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): - * return 'C' # <<<<<<<<<<<<<< - * else: - * return 'F' + * + * for i in range(ndim): # <<<<<<<<<<<<<< + * if tmpslice.shape[i] == 1: + * tmpslice.strides[i] = 0 */ - __pyx_r = 'C'; - goto __pyx_L0; + __pyx_t_3 = __pyx_v_ndim; + __pyx_t_5 = __pyx_t_3; + for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { + __pyx_v_i = __pyx_t_6; - /* "View.MemoryView":1136 - * break + /* "View.MemoryView":1234 * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<< - * return 'C' + * for i in range(ndim): + * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<< + * tmpslice.strides[i] = 0 + * + */ + __pyx_t_2 = ((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1); + if (__pyx_t_2) { + + /* "View.MemoryView":1235 + * for i in range(ndim): + * if tmpslice.shape[i] == 1: + * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<< + * + * if slice_is_contig(src[0], order, ndim): + */ + (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0; + + /* "View.MemoryView":1234 + * + * for i in range(ndim): + * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<< + * tmpslice.strides[i] = 0 + * + */ + } + } + + /* "View.MemoryView":1237 + * tmpslice.strides[i] = 0 + * + * if slice_is_contig(src[0], order, ndim): # <<<<<<<<<<<<<< + * memcpy(result, src.data, size) + * else: + */ + __pyx_t_2 = __pyx_memviewslice_is_contig((__pyx_v_src[0]), __pyx_v_order, __pyx_v_ndim); + if (__pyx_t_2) { + + /* "View.MemoryView":1238 + * + * if slice_is_contig(src[0], order, ndim): + * memcpy(result, src.data, size) # <<<<<<<<<<<<<< + * else: + * copy_strided_to_strided(src, tmpslice, ndim, itemsize) + */ + (void)(memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size)); + + /* "View.MemoryView":1237 + * tmpslice.strides[i] = 0 + * + * if slice_is_contig(src[0], order, ndim): # <<<<<<<<<<<<<< + * memcpy(result, src.data, size) * else: */ + goto __pyx_L9; } - /* "View.MemoryView":1139 - * return 'C' + /* "View.MemoryView":1240 + * memcpy(result, src.data, size) * else: - * return 'F' # <<<<<<<<<<<<<< + * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<< * - * @cython.cdivision(True) + * return result */ /*else*/ { - __pyx_r = 'F'; - goto __pyx_L0; + copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize); } + __pyx_L9:; - /* "View.MemoryView":1118 + /* "View.MemoryView":1242 + * copy_strided_to_strided(src, tmpslice, ndim, itemsize) * - * @cname('__pyx_get_best_slice_order') - * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<< - * """ - * Figure out the best memory access order for a given slice. + * return result # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_result; + goto __pyx_L0; + + /* "View.MemoryView":1205 + * + * @cname('__pyx_memoryview_copy_data_to_temp') + * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< + * __Pyx_memviewslice *tmpslice, + * char order, */ /* function exit code */ + __pyx_L1_error:; + #ifdef WITH_THREAD + __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif __pyx_L0:; return __pyx_r; } -/* "View.MemoryView":1142 +/* "View.MemoryView":1247 * - * @cython.cdivision(True) - * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<< - * char *dst_data, Py_ssize_t *dst_strides, - * Py_ssize_t *src_shape, Py_ssize_t *dst_shape, + * @cname('__pyx_memoryview_err_extents') + * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<< + * Py_ssize_t extent2) except -1 with gil: + * raise ValueError, f"got differing extents in dimension {i} (got {extent1} and {extent2})" */ -static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) { - CYTHON_UNUSED Py_ssize_t __pyx_v_i; - CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent; - Py_ssize_t __pyx_v_dst_extent; - Py_ssize_t __pyx_v_src_stride; - Py_ssize_t __pyx_v_dst_stride; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - Py_ssize_t __pyx_t_4; - Py_ssize_t __pyx_t_5; - Py_ssize_t __pyx_t_6; +static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + Py_UCS4 __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_RefNannySetupContext("_err_extents", 0); - /* "View.MemoryView":1149 + /* "View.MemoryView":1249 + * cdef int _err_extents(int i, Py_ssize_t extent1, + * Py_ssize_t extent2) except -1 with gil: + * raise ValueError, f"got differing extents in dimension {i} (got {extent1} and {extent2})" # <<<<<<<<<<<<<< * - * cdef Py_ssize_t i - * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t dst_extent = dst_shape[0] - * cdef Py_ssize_t src_stride = src_strides[0] - */ - __pyx_v_src_extent = (__pyx_v_src_shape[0]); - - /* "View.MemoryView":1150 - * cdef Py_ssize_t i - * cdef Py_ssize_t src_extent = src_shape[0] - * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t src_stride = src_strides[0] - * cdef Py_ssize_t dst_stride = dst_strides[0] + * @cname('__pyx_memoryview_err_dim') */ - __pyx_v_dst_extent = (__pyx_v_dst_shape[0]); + __pyx_t_1 = PyTuple_New(7); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = 127; + __Pyx_INCREF(__pyx_kp_u_got_differing_extents_in_dimensi); + __pyx_t_2 += 35; + __Pyx_GIVEREF(__pyx_kp_u_got_differing_extents_in_dimensi); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_got_differing_extents_in_dimensi); + __pyx_t_4 = __Pyx_PyUnicode_From_int(__pyx_v_i, 0, ' ', 'd'); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4); + __pyx_t_4 = 0; + __Pyx_INCREF(__pyx_kp_u_got); + __pyx_t_2 += 6; + __Pyx_GIVEREF(__pyx_kp_u_got); + PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_got); + __pyx_t_4 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_extent1, 0, ' ', 'd'); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_4); + __pyx_t_4 = 0; + __Pyx_INCREF(__pyx_kp_u_and); + __pyx_t_2 += 5; + __Pyx_GIVEREF(__pyx_kp_u_and); + PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u_and); + __pyx_t_4 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_extent2, 0, ' ', 'd'); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_t_4); + __pyx_t_4 = 0; + __Pyx_INCREF(__pyx_kp_u__7); + __pyx_t_2 += 1; + __Pyx_GIVEREF(__pyx_kp_u__7); + PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_kp_u__7); + __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_1, 7, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_Raise(__pyx_builtin_ValueError, __pyx_t_4, 0, 0); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __PYX_ERR(1, 1249, __pyx_L1_error) - /* "View.MemoryView":1151 - * cdef Py_ssize_t src_extent = src_shape[0] - * cdef Py_ssize_t dst_extent = dst_shape[0] - * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t dst_stride = dst_strides[0] + /* "View.MemoryView":1247 * + * @cname('__pyx_memoryview_err_extents') + * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<< + * Py_ssize_t extent2) except -1 with gil: + * raise ValueError, f"got differing extents in dimension {i} (got {extent1} and {extent2})" */ - __pyx_v_src_stride = (__pyx_v_src_strides[0]); - /* "View.MemoryView":1152 - * cdef Py_ssize_t dst_extent = dst_shape[0] - * cdef Py_ssize_t src_stride = src_strides[0] - * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<< + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __Pyx_RefNannyFinishContext(); + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + return __pyx_r; +} + +/* "View.MemoryView":1252 + * + * @cname('__pyx_memoryview_err_dim') + * cdef int _err_dim(PyObject *error, str msg, int dim) except -1 with gil: # <<<<<<<<<<<<<< + * raise error, msg % dim * - * if ndim == 1: */ - __pyx_v_dst_stride = (__pyx_v_dst_strides[0]); - /* "View.MemoryView":1154 - * cdef Py_ssize_t dst_stride = dst_strides[0] +static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, PyObject *__pyx_v_msg, int __pyx_v_dim) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_RefNannySetupContext("_err_dim", 0); + __Pyx_INCREF(__pyx_v_msg); + + /* "View.MemoryView":1253 + * @cname('__pyx_memoryview_err_dim') + * cdef int _err_dim(PyObject *error, str msg, int dim) except -1 with gil: + * raise error, msg % dim # <<<<<<<<<<<<<< * - * if ndim == 1: # <<<<<<<<<<<<<< - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): + * @cname('__pyx_memoryview_err') */ - __pyx_t_1 = ((__pyx_v_ndim == 1) != 0); - if (__pyx_t_1) { + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1253, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyString_FormatSafe(__pyx_v_msg, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1253, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_Raise(((PyObject *)__pyx_v_error), __pyx_t_2, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(1, 1253, __pyx_L1_error) - /* "View.MemoryView":1155 + /* "View.MemoryView":1252 + * + * @cname('__pyx_memoryview_err_dim') + * cdef int _err_dim(PyObject *error, str msg, int dim) except -1 with gil: # <<<<<<<<<<<<<< + * raise error, msg % dim * - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) */ - __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L5_bool_binop_done; - } - __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L5_bool_binop_done; - } - /* "View.MemoryView":1156 - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): # <<<<<<<<<<<<<< - * memcpy(dst_data, src_data, itemsize * dst_extent) - * else: - */ - __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize); - if (__pyx_t_2) { - __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride)); - } - __pyx_t_3 = (__pyx_t_2 != 0); - __pyx_t_1 = __pyx_t_3; - __pyx_L5_bool_binop_done:; + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __Pyx_XDECREF(__pyx_v_msg); + __Pyx_RefNannyFinishContext(); + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + return __pyx_r; +} - /* "View.MemoryView":1155 +/* "View.MemoryView":1256 + * + * @cname('__pyx_memoryview_err') + * cdef int _err(PyObject *error, str msg) except -1 with gil: # <<<<<<<<<<<<<< + * raise error, msg * - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) */ - if (__pyx_t_1) { - /* "View.MemoryView":1157 - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<< - * else: - * for i in range(dst_extent): - */ - (void)(memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent))); +static int __pyx_memoryview_err(PyObject *__pyx_v_error, PyObject *__pyx_v_msg) { + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_RefNannySetupContext("_err", 0); + __Pyx_INCREF(__pyx_v_msg); - /* "View.MemoryView":1155 + /* "View.MemoryView":1257 + * @cname('__pyx_memoryview_err') + * cdef int _err(PyObject *error, str msg) except -1 with gil: + * raise error, msg # <<<<<<<<<<<<<< * - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) + * @cname('__pyx_memoryview_err_no_memory') */ - goto __pyx_L4; - } + __Pyx_Raise(((PyObject *)__pyx_v_error), __pyx_v_msg, 0, 0); + __PYX_ERR(1, 1257, __pyx_L1_error) - /* "View.MemoryView":1159 - * memcpy(dst_data, src_data, itemsize * dst_extent) - * else: - * for i in range(dst_extent): # <<<<<<<<<<<<<< - * memcpy(dst_data, src_data, itemsize) - * src_data += src_stride - */ - /*else*/ { - __pyx_t_4 = __pyx_v_dst_extent; - __pyx_t_5 = __pyx_t_4; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "View.MemoryView":1160 - * else: - * for i in range(dst_extent): - * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<< - * src_data += src_stride - * dst_data += dst_stride + /* "View.MemoryView":1256 + * + * @cname('__pyx_memoryview_err') + * cdef int _err(PyObject *error, str msg) except -1 with gil: # <<<<<<<<<<<<<< + * raise error, msg + * */ - (void)(memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize)); - /* "View.MemoryView":1161 - * for i in range(dst_extent): - * memcpy(dst_data, src_data, itemsize) - * src_data += src_stride # <<<<<<<<<<<<<< - * dst_data += dst_stride - * else: - */ - __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride); - - /* "View.MemoryView":1162 - * memcpy(dst_data, src_data, itemsize) - * src_data += src_stride - * dst_data += dst_stride # <<<<<<<<<<<<<< - * else: - * for i in range(dst_extent): - */ - __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride); - } - } - __pyx_L4:; + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __Pyx_XDECREF(__pyx_v_msg); + __Pyx_RefNannyFinishContext(); + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + return __pyx_r; +} - /* "View.MemoryView":1154 - * cdef Py_ssize_t dst_stride = dst_strides[0] +/* "View.MemoryView":1260 + * + * @cname('__pyx_memoryview_err_no_memory') + * cdef int _err_no_memory() except -1 with gil: # <<<<<<<<<<<<<< + * raise MemoryError * - * if ndim == 1: # <<<<<<<<<<<<<< - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1164 - * dst_data += dst_stride - * else: - * for i in range(dst_extent): # <<<<<<<<<<<<<< - * _copy_strided_to_strided(src_data, src_strides + 1, - * dst_data, dst_strides + 1, */ - /*else*/ { - __pyx_t_4 = __pyx_v_dst_extent; - __pyx_t_5 = __pyx_t_4; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - /* "View.MemoryView":1165 - * else: - * for i in range(dst_extent): - * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<< - * dst_data, dst_strides + 1, - * src_shape + 1, dst_shape + 1, - */ - _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize); +static int __pyx_memoryview_err_no_memory(void) { + int __pyx_r; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif - /* "View.MemoryView":1169 - * src_shape + 1, dst_shape + 1, - * ndim - 1, itemsize) - * src_data += src_stride # <<<<<<<<<<<<<< - * dst_data += dst_stride + /* "View.MemoryView":1261 + * @cname('__pyx_memoryview_err_no_memory') + * cdef int _err_no_memory() except -1 with gil: + * raise MemoryError # <<<<<<<<<<<<<< * - */ - __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride); - - /* "View.MemoryView":1170 - * ndim - 1, itemsize) - * src_data += src_stride - * dst_data += dst_stride # <<<<<<<<<<<<<< * - * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, */ - __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride); - } - } - __pyx_L3:; + PyErr_NoMemory(); __PYX_ERR(1, 1261, __pyx_L1_error) - /* "View.MemoryView":1142 + /* "View.MemoryView":1260 + * + * @cname('__pyx_memoryview_err_no_memory') + * cdef int _err_no_memory() except -1 with gil: # <<<<<<<<<<<<<< + * raise MemoryError * - * @cython.cdivision(True) - * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<< - * char *dst_data, Py_ssize_t *dst_strides, - * Py_ssize_t *src_shape, Py_ssize_t *dst_shape, */ /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("View.MemoryView._err_no_memory", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif + return __pyx_r; } -/* "View.MemoryView":1172 - * dst_data += dst_stride +/* "View.MemoryView":1265 * - * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * int ndim, size_t itemsize) nogil: + * @cname('__pyx_memoryview_copy_contents') + * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<< + * __Pyx_memviewslice dst, + * int src_ndim, int dst_ndim, */ -static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) { +static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) { + void *__pyx_v_tmpdata; + size_t __pyx_v_itemsize; + int __pyx_v_i; + char __pyx_v_order; + int __pyx_v_broadcasting; + int __pyx_v_direct_copy; + __Pyx_memviewslice __pyx_v_tmp; + int __pyx_v_ndim; + int __pyx_r; + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + int __pyx_t_6; + void *__pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save; + #endif - /* "View.MemoryView":1175 - * __Pyx_memviewslice *dst, - * int ndim, size_t itemsize) nogil: - * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<< - * src.shape, dst.shape, ndim, itemsize) - * + /* "View.MemoryView":1273 + * Check for overlapping memory and verify the shapes. + * """ + * cdef void *tmpdata = NULL # <<<<<<<<<<<<<< + * cdef size_t itemsize = src.memview.view.itemsize + * cdef int i */ - _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize); + __pyx_v_tmpdata = NULL; - /* "View.MemoryView":1172 - * dst_data += dst_stride - * - * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * int ndim, size_t itemsize) nogil: + /* "View.MemoryView":1274 + * """ + * cdef void *tmpdata = NULL + * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<< + * cdef int i + * cdef char order = get_best_order(&src, src_ndim) */ + __pyx_t_1 = __pyx_v_src.memview->view.itemsize; + __pyx_v_itemsize = __pyx_t_1; - /* function exit code */ -} - -/* "View.MemoryView":1179 - * - * @cname('__pyx_memoryview_slice_get_size') - * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<< - * "Return the size of the memory occupied by the slice in number of bytes" - * cdef Py_ssize_t shape, size = src.memview.view.itemsize + /* "View.MemoryView":1276 + * cdef size_t itemsize = src.memview.view.itemsize + * cdef int i + * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<< + * cdef bint broadcasting = False + * cdef bint direct_copy = False */ + __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim); -static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) { - Py_ssize_t __pyx_v_shape; - Py_ssize_t __pyx_v_size; - Py_ssize_t __pyx_r; - Py_ssize_t __pyx_t_1; - Py_ssize_t *__pyx_t_2; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; + /* "View.MemoryView":1277 + * cdef int i + * cdef char order = get_best_order(&src, src_ndim) + * cdef bint broadcasting = False # <<<<<<<<<<<<<< + * cdef bint direct_copy = False + * cdef __Pyx_memviewslice tmp + */ + __pyx_v_broadcasting = 0; - /* "View.MemoryView":1181 - * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: - * "Return the size of the memory occupied by the slice in number of bytes" - * cdef Py_ssize_t shape, size = src.memview.view.itemsize # <<<<<<<<<<<<<< + /* "View.MemoryView":1278 + * cdef char order = get_best_order(&src, src_ndim) + * cdef bint broadcasting = False + * cdef bint direct_copy = False # <<<<<<<<<<<<<< + * cdef __Pyx_memviewslice tmp * - * for shape in src.shape[:ndim]: */ - __pyx_t_1 = __pyx_v_src->memview->view.itemsize; - __pyx_v_size = __pyx_t_1; + __pyx_v_direct_copy = 0; - /* "View.MemoryView":1183 - * cdef Py_ssize_t shape, size = src.memview.view.itemsize - * - * for shape in src.shape[:ndim]: # <<<<<<<<<<<<<< - * size *= shape + /* "View.MemoryView":1281 + * cdef __Pyx_memviewslice tmp * + * if src_ndim < dst_ndim: # <<<<<<<<<<<<<< + * broadcast_leading(&src, src_ndim, dst_ndim) + * elif dst_ndim < src_ndim: */ - __pyx_t_3 = (__pyx_v_src->shape + __pyx_v_ndim); - for (__pyx_t_4 = __pyx_v_src->shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { - __pyx_t_2 = __pyx_t_4; - __pyx_v_shape = (__pyx_t_2[0]); + __pyx_t_2 = (__pyx_v_src_ndim < __pyx_v_dst_ndim); + if (__pyx_t_2) { - /* "View.MemoryView":1184 - * - * for shape in src.shape[:ndim]: - * size *= shape # <<<<<<<<<<<<<< + /* "View.MemoryView":1282 * - * return size + * if src_ndim < dst_ndim: + * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<< + * elif dst_ndim < src_ndim: + * broadcast_leading(&dst, dst_ndim, src_ndim) */ - __pyx_v_size = (__pyx_v_size * __pyx_v_shape); - } + __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim); - /* "View.MemoryView":1186 - * size *= shape - * - * return size # <<<<<<<<<<<<<< + /* "View.MemoryView":1281 + * cdef __Pyx_memviewslice tmp * - * @cname('__pyx_fill_contig_strides_array') + * if src_ndim < dst_ndim: # <<<<<<<<<<<<<< + * broadcast_leading(&src, src_ndim, dst_ndim) + * elif dst_ndim < src_ndim: */ - __pyx_r = __pyx_v_size; - goto __pyx_L0; + goto __pyx_L3; + } - /* "View.MemoryView":1179 + /* "View.MemoryView":1283 + * if src_ndim < dst_ndim: + * broadcast_leading(&src, src_ndim, dst_ndim) + * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<< + * broadcast_leading(&dst, dst_ndim, src_ndim) * - * @cname('__pyx_memoryview_slice_get_size') - * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<< - * "Return the size of the memory occupied by the slice in number of bytes" - * cdef Py_ssize_t shape, size = src.memview.view.itemsize */ + __pyx_t_2 = (__pyx_v_dst_ndim < __pyx_v_src_ndim); + if (__pyx_t_2) { - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1189 + /* "View.MemoryView":1284 + * broadcast_leading(&src, src_ndim, dst_ndim) + * elif dst_ndim < src_ndim: + * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<< * - * @cname('__pyx_fill_contig_strides_array') - * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<< - * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, - * int ndim, char order) nogil: + * cdef int ndim = max(src_ndim, dst_ndim) */ + __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim); -static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) { - int __pyx_v_idx; - Py_ssize_t __pyx_r; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - - /* "View.MemoryView":1198 - * cdef int idx + /* "View.MemoryView":1283 + * if src_ndim < dst_ndim: + * broadcast_leading(&src, src_ndim, dst_ndim) + * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<< + * broadcast_leading(&dst, dst_ndim, src_ndim) * - * if order == 'F': # <<<<<<<<<<<<<< - * for idx in range(ndim): - * strides[idx] = stride */ - __pyx_t_1 = ((__pyx_v_order == 'F') != 0); - if (__pyx_t_1) { + } + __pyx_L3:; - /* "View.MemoryView":1199 + /* "View.MemoryView":1286 + * broadcast_leading(&dst, dst_ndim, src_ndim) * - * if order == 'F': - * for idx in range(ndim): # <<<<<<<<<<<<<< - * strides[idx] = stride - * stride *= shape[idx] + * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<< + * + * for i in range(ndim): */ - __pyx_t_2 = __pyx_v_ndim; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_idx = __pyx_t_4; - - /* "View.MemoryView":1200 - * if order == 'F': - * for idx in range(ndim): - * strides[idx] = stride # <<<<<<<<<<<<<< - * stride *= shape[idx] - * else: - */ - (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride; + __pyx_t_3 = __pyx_v_dst_ndim; + __pyx_t_4 = __pyx_v_src_ndim; + __pyx_t_2 = (__pyx_t_3 > __pyx_t_4); + if (__pyx_t_2) { + __pyx_t_5 = __pyx_t_3; + } else { + __pyx_t_5 = __pyx_t_4; + } + __pyx_v_ndim = __pyx_t_5; - /* "View.MemoryView":1201 - * for idx in range(ndim): - * strides[idx] = stride - * stride *= shape[idx] # <<<<<<<<<<<<<< - * else: - * for idx in range(ndim - 1, -1, -1): + /* "View.MemoryView":1288 + * cdef int ndim = max(src_ndim, dst_ndim) + * + * for i in range(ndim): # <<<<<<<<<<<<<< + * if src.shape[i] != dst.shape[i]: + * if src.shape[i] == 1: */ - __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx])); - } + __pyx_t_5 = __pyx_v_ndim; + __pyx_t_3 = __pyx_t_5; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_i = __pyx_t_4; - /* "View.MemoryView":1198 - * cdef int idx + /* "View.MemoryView":1289 * - * if order == 'F': # <<<<<<<<<<<<<< - * for idx in range(ndim): - * strides[idx] = stride + * for i in range(ndim): + * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<< + * if src.shape[i] == 1: + * broadcasting = True */ - goto __pyx_L3; - } + __pyx_t_2 = ((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])); + if (__pyx_t_2) { - /* "View.MemoryView":1203 - * stride *= shape[idx] - * else: - * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< - * strides[idx] = stride - * stride *= shape[idx] + /* "View.MemoryView":1290 + * for i in range(ndim): + * if src.shape[i] != dst.shape[i]: + * if src.shape[i] == 1: # <<<<<<<<<<<<<< + * broadcasting = True + * src.strides[i] = 0 */ - /*else*/ { - for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) { - __pyx_v_idx = __pyx_t_2; + __pyx_t_2 = ((__pyx_v_src.shape[__pyx_v_i]) == 1); + if (__pyx_t_2) { - /* "View.MemoryView":1204 - * else: - * for idx in range(ndim - 1, -1, -1): - * strides[idx] = stride # <<<<<<<<<<<<<< - * stride *= shape[idx] - * + /* "View.MemoryView":1291 + * if src.shape[i] != dst.shape[i]: + * if src.shape[i] == 1: + * broadcasting = True # <<<<<<<<<<<<<< + * src.strides[i] = 0 + * else: */ - (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride; + __pyx_v_broadcasting = 1; - /* "View.MemoryView":1205 - * for idx in range(ndim - 1, -1, -1): - * strides[idx] = stride - * stride *= shape[idx] # <<<<<<<<<<<<<< - * - * return stride + /* "View.MemoryView":1292 + * if src.shape[i] == 1: + * broadcasting = True + * src.strides[i] = 0 # <<<<<<<<<<<<<< + * else: + * _err_extents(i, dst.shape[i], src.shape[i]) */ - __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx])); - } - } - __pyx_L3:; + (__pyx_v_src.strides[__pyx_v_i]) = 0; - /* "View.MemoryView":1207 - * stride *= shape[idx] - * - * return stride # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_copy_data_to_temp') + /* "View.MemoryView":1290 + * for i in range(ndim): + * if src.shape[i] != dst.shape[i]: + * if src.shape[i] == 1: # <<<<<<<<<<<<<< + * broadcasting = True + * src.strides[i] = 0 */ - __pyx_r = __pyx_v_stride; - goto __pyx_L0; + goto __pyx_L7; + } - /* "View.MemoryView":1189 + /* "View.MemoryView":1294 + * src.strides[i] = 0 + * else: + * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<< * - * @cname('__pyx_fill_contig_strides_array') - * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<< - * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, - * int ndim, char order) nogil: + * if src.suboffsets[i] >= 0: */ + /*else*/ { + __pyx_t_6 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(1, 1294, __pyx_L1_error) + } + __pyx_L7:; - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1210 + /* "View.MemoryView":1289 * - * @cname('__pyx_memoryview_copy_data_to_temp') - * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *tmpslice, - * char order, + * for i in range(ndim): + * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<< + * if src.shape[i] == 1: + * broadcasting = True */ + } -static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) { - int __pyx_v_i; - void *__pyx_v_result; - size_t __pyx_v_itemsize; - size_t __pyx_v_size; - void *__pyx_r; - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - struct __pyx_memoryview_obj *__pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - - /* "View.MemoryView":1221 - * cdef void *result + /* "View.MemoryView":1296 + * _err_extents(i, dst.shape[i], src.shape[i]) * - * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<< - * cdef size_t size = slice_get_size(src, ndim) + * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<< + * _err_dim(PyExc_ValueError, "Dimension %d is not direct", i) * */ - __pyx_t_1 = __pyx_v_src->memview->view.itemsize; - __pyx_v_itemsize = __pyx_t_1; + __pyx_t_2 = ((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0); + if (__pyx_t_2) { - /* "View.MemoryView":1222 + /* "View.MemoryView":1297 * - * cdef size_t itemsize = src.memview.view.itemsize - * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<< + * if src.suboffsets[i] >= 0: + * _err_dim(PyExc_ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<< * - * result = malloc(size) + * if slices_overlap(&src, &dst, ndim, itemsize): */ - __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim); + __pyx_t_6 = __pyx_memoryview_err_dim(PyExc_ValueError, __pyx_kp_s_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(1, 1297, __pyx_L1_error) - /* "View.MemoryView":1224 - * cdef size_t size = slice_get_size(src, ndim) + /* "View.MemoryView":1296 + * _err_extents(i, dst.shape[i], src.shape[i]) + * + * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<< + * _err_dim(PyExc_ValueError, "Dimension %d is not direct", i) * - * result = malloc(size) # <<<<<<<<<<<<<< - * if not result: - * _err(MemoryError, NULL) */ - __pyx_v_result = malloc(__pyx_v_size); + } + } - /* "View.MemoryView":1225 + /* "View.MemoryView":1299 + * _err_dim(PyExc_ValueError, "Dimension %d is not direct", i) * - * result = malloc(size) - * if not result: # <<<<<<<<<<<<<< - * _err(MemoryError, NULL) + * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<< * + * if not slice_is_contig(src, order, ndim): */ - __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0); + __pyx_t_2 = __pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize); if (__pyx_t_2) { - /* "View.MemoryView":1226 - * result = malloc(size) - * if not result: - * _err(MemoryError, NULL) # <<<<<<<<<<<<<< + /* "View.MemoryView":1301 + * if slices_overlap(&src, &dst, ndim, itemsize): * + * if not slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<< + * order = get_best_order(&dst, ndim) * */ - __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(2, 1226, __pyx_L1_error) + __pyx_t_2 = (!__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim)); + if (__pyx_t_2) { - /* "View.MemoryView":1225 + /* "View.MemoryView":1302 * - * result = malloc(size) - * if not result: # <<<<<<<<<<<<<< - * _err(MemoryError, NULL) + * if not slice_is_contig(src, order, ndim): + * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<< * + * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) */ - } + __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim); - /* "View.MemoryView":1229 + /* "View.MemoryView":1301 + * if slices_overlap(&src, &dst, ndim, itemsize): * + * if not slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<< + * order = get_best_order(&dst, ndim) * - * tmpslice.data = result # <<<<<<<<<<<<<< - * tmpslice.memview = src.memview - * for i in range(ndim): */ - __pyx_v_tmpslice->data = ((char *)__pyx_v_result); + } - /* "View.MemoryView":1230 + /* "View.MemoryView":1304 + * order = get_best_order(&dst, ndim) + * + * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<< + * src = tmp * - * tmpslice.data = result - * tmpslice.memview = src.memview # <<<<<<<<<<<<<< - * for i in range(ndim): - * tmpslice.shape[i] = src.shape[i] - */ - __pyx_t_4 = __pyx_v_src->memview; - __pyx_v_tmpslice->memview = __pyx_t_4; - - /* "View.MemoryView":1231 - * tmpslice.data = result - * tmpslice.memview = src.memview - * for i in range(ndim): # <<<<<<<<<<<<<< - * tmpslice.shape[i] = src.shape[i] - * tmpslice.suboffsets[i] = -1 */ - __pyx_t_3 = __pyx_v_ndim; - __pyx_t_5 = __pyx_t_3; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; + __pyx_t_7 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_7 == ((void *)NULL))) __PYX_ERR(1, 1304, __pyx_L1_error) + __pyx_v_tmpdata = __pyx_t_7; - /* "View.MemoryView":1232 - * tmpslice.memview = src.memview - * for i in range(ndim): - * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<< - * tmpslice.suboffsets[i] = -1 + /* "View.MemoryView":1305 + * + * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) + * src = tmp # <<<<<<<<<<<<<< * + * if not broadcasting: */ - (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]); + __pyx_v_src = __pyx_v_tmp; - /* "View.MemoryView":1233 - * for i in range(ndim): - * tmpslice.shape[i] = src.shape[i] - * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<< + /* "View.MemoryView":1299 + * _err_dim(PyExc_ValueError, "Dimension %d is not direct", i) + * + * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<< * - * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, + * if not slice_is_contig(src, order, ndim): */ - (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1L; } - /* "View.MemoryView":1235 - * tmpslice.suboffsets[i] = -1 + /* "View.MemoryView":1307 + * src = tmp + * + * if not broadcasting: # <<<<<<<<<<<<<< * - * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<< - * ndim, order) * */ - (void)(__pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order)); + __pyx_t_2 = (!__pyx_v_broadcasting); + if (__pyx_t_2) { - /* "View.MemoryView":1239 + /* "View.MemoryView":1310 * * - * for i in range(ndim): # <<<<<<<<<<<<<< - * if tmpslice.shape[i] == 1: - * tmpslice.strides[i] = 0 + * if slice_is_contig(src, 'C', ndim): # <<<<<<<<<<<<<< + * direct_copy = slice_is_contig(dst, 'C', ndim) + * elif slice_is_contig(src, 'F', ndim): */ - __pyx_t_3 = __pyx_v_ndim; - __pyx_t_5 = __pyx_t_3; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; + __pyx_t_2 = __pyx_memviewslice_is_contig(__pyx_v_src, 'C', __pyx_v_ndim); + if (__pyx_t_2) { - /* "View.MemoryView":1240 + /* "View.MemoryView":1311 + * + * if slice_is_contig(src, 'C', ndim): + * direct_copy = slice_is_contig(dst, 'C', ndim) # <<<<<<<<<<<<<< + * elif slice_is_contig(src, 'F', ndim): + * direct_copy = slice_is_contig(dst, 'F', ndim) + */ + __pyx_v_direct_copy = __pyx_memviewslice_is_contig(__pyx_v_dst, 'C', __pyx_v_ndim); + + /* "View.MemoryView":1310 * - * for i in range(ndim): - * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<< - * tmpslice.strides[i] = 0 * + * if slice_is_contig(src, 'C', ndim): # <<<<<<<<<<<<<< + * direct_copy = slice_is_contig(dst, 'C', ndim) + * elif slice_is_contig(src, 'F', ndim): */ - __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0); - if (__pyx_t_2) { + goto __pyx_L12; + } - /* "View.MemoryView":1241 - * for i in range(ndim): - * if tmpslice.shape[i] == 1: - * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<< + /* "View.MemoryView":1312 + * if slice_is_contig(src, 'C', ndim): + * direct_copy = slice_is_contig(dst, 'C', ndim) + * elif slice_is_contig(src, 'F', ndim): # <<<<<<<<<<<<<< + * direct_copy = slice_is_contig(dst, 'F', ndim) * - * if slice_is_contig(src[0], order, ndim): */ - (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0; + __pyx_t_2 = __pyx_memviewslice_is_contig(__pyx_v_src, 'F', __pyx_v_ndim); + if (__pyx_t_2) { - /* "View.MemoryView":1240 + /* "View.MemoryView":1313 + * direct_copy = slice_is_contig(dst, 'C', ndim) + * elif slice_is_contig(src, 'F', ndim): + * direct_copy = slice_is_contig(dst, 'F', ndim) # <<<<<<<<<<<<<< * - * for i in range(ndim): - * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<< - * tmpslice.strides[i] = 0 + * if direct_copy: + */ + __pyx_v_direct_copy = __pyx_memviewslice_is_contig(__pyx_v_dst, 'F', __pyx_v_ndim); + + /* "View.MemoryView":1312 + * if slice_is_contig(src, 'C', ndim): + * direct_copy = slice_is_contig(dst, 'C', ndim) + * elif slice_is_contig(src, 'F', ndim): # <<<<<<<<<<<<<< + * direct_copy = slice_is_contig(dst, 'F', ndim) * */ } - } + __pyx_L12:; - /* "View.MemoryView":1243 - * tmpslice.strides[i] = 0 + /* "View.MemoryView":1315 + * direct_copy = slice_is_contig(dst, 'F', ndim) * - * if slice_is_contig(src[0], order, ndim): # <<<<<<<<<<<<<< - * memcpy(result, src.data, size) - * else: + * if direct_copy: # <<<<<<<<<<<<<< + * + * refcount_copying(&dst, dtype_is_object, ndim, inc=False) */ - __pyx_t_2 = (__pyx_memviewslice_is_contig((__pyx_v_src[0]), __pyx_v_order, __pyx_v_ndim) != 0); - if (__pyx_t_2) { + if (__pyx_v_direct_copy) { - /* "View.MemoryView":1244 + /* "View.MemoryView":1317 + * if direct_copy: * - * if slice_is_contig(src[0], order, ndim): - * memcpy(result, src.data, size) # <<<<<<<<<<<<<< - * else: - * copy_strided_to_strided(src, tmpslice, ndim, itemsize) + * refcount_copying(&dst, dtype_is_object, ndim, inc=False) # <<<<<<<<<<<<<< + * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) + * refcount_copying(&dst, dtype_is_object, ndim, inc=True) */ - (void)(memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size)); + __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0); - /* "View.MemoryView":1243 - * tmpslice.strides[i] = 0 + /* "View.MemoryView":1318 + * + * refcount_copying(&dst, dtype_is_object, ndim, inc=False) + * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<< + * refcount_copying(&dst, dtype_is_object, ndim, inc=True) + * free(tmpdata) + */ + (void)(memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim))); + + /* "View.MemoryView":1319 + * refcount_copying(&dst, dtype_is_object, ndim, inc=False) + * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) + * refcount_copying(&dst, dtype_is_object, ndim, inc=True) # <<<<<<<<<<<<<< + * free(tmpdata) + * return 0 + */ + __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1); + + /* "View.MemoryView":1320 + * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) + * refcount_copying(&dst, dtype_is_object, ndim, inc=True) + * free(tmpdata) # <<<<<<<<<<<<<< + * return 0 + * + */ + free(__pyx_v_tmpdata); + + /* "View.MemoryView":1321 + * refcount_copying(&dst, dtype_is_object, ndim, inc=True) + * free(tmpdata) + * return 0 # <<<<<<<<<<<<<< + * + * if order == 'F' == get_best_order(&dst, ndim): + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "View.MemoryView":1315 + * direct_copy = slice_is_contig(dst, 'F', ndim) + * + * if direct_copy: # <<<<<<<<<<<<<< + * + * refcount_copying(&dst, dtype_is_object, ndim, inc=False) + */ + } + + /* "View.MemoryView":1307 + * src = tmp + * + * if not broadcasting: # <<<<<<<<<<<<<< + * * - * if slice_is_contig(src[0], order, ndim): # <<<<<<<<<<<<<< - * memcpy(result, src.data, size) - * else: */ - goto __pyx_L9; } - /* "View.MemoryView":1246 - * memcpy(result, src.data, size) - * else: - * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<< + /* "View.MemoryView":1323 + * return 0 + * + * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<< + * * - * return result */ - /*else*/ { - copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize); + __pyx_t_2 = (__pyx_v_order == 'F'); + if (__pyx_t_2) { + __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim)); } - __pyx_L9:; + if (__pyx_t_2) { - /* "View.MemoryView":1248 - * copy_strided_to_strided(src, tmpslice, ndim, itemsize) + /* "View.MemoryView":1326 * - * return result # <<<<<<<<<<<<<< * + * transpose_memslice(&src) # <<<<<<<<<<<<<< + * transpose_memslice(&dst) * */ - __pyx_r = __pyx_v_result; - goto __pyx_L0; + __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(1, 1326, __pyx_L1_error) - /* "View.MemoryView":1210 + /* "View.MemoryView":1327 * - * @cname('__pyx_memoryview_copy_data_to_temp') - * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *tmpslice, - * char order, + * transpose_memslice(&src) + * transpose_memslice(&dst) # <<<<<<<<<<<<<< + * + * refcount_copying(&dst, dtype_is_object, ndim, inc=False) */ + __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(1, 1327, __pyx_L1_error) - /* function exit code */ - __pyx_L1_error:; - { - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif + /* "View.MemoryView":1323 + * return 0 + * + * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<< + * + * + */ } - __pyx_r = NULL; - __pyx_L0:; - return __pyx_r; -} -/* "View.MemoryView":1253 + /* "View.MemoryView":1329 + * transpose_memslice(&dst) * - * @cname('__pyx_memoryview_err_extents') - * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<< - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError("got differing extents in dimension %d (got %d and %d)" % + * refcount_copying(&dst, dtype_is_object, ndim, inc=False) # <<<<<<<<<<<<<< + * copy_strided_to_strided(&src, &dst, ndim, itemsize) + * refcount_copying(&dst, dtype_is_object, ndim, inc=True) */ + __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0); -static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("_err_extents", 0); + /* "View.MemoryView":1330 + * + * refcount_copying(&dst, dtype_is_object, ndim, inc=False) + * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<< + * refcount_copying(&dst, dtype_is_object, ndim, inc=True) + * + */ + copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize); - /* "View.MemoryView":1256 - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError("got differing extents in dimension %d (got %d and %d)" % - * (i, extent1, extent2)) # <<<<<<<<<<<<<< + /* "View.MemoryView":1331 + * refcount_copying(&dst, dtype_is_object, ndim, inc=False) + * copy_strided_to_strided(&src, &dst, ndim, itemsize) + * refcount_copying(&dst, dtype_is_object, ndim, inc=True) # <<<<<<<<<<<<<< * - * @cname('__pyx_memoryview_err_dim') + * free(tmpdata) */ - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1256, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1256, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1256, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 1256, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_3 = 0; + __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1); - /* "View.MemoryView":1255 - * cdef int _err_extents(int i, Py_ssize_t extent1, - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<< - * (i, extent1, extent2)) + /* "View.MemoryView":1333 + * refcount_copying(&dst, dtype_is_object, ndim, inc=True) + * + * free(tmpdata) # <<<<<<<<<<<<<< + * return 0 * */ - __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1255, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 1255, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_4, 0, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(2, 1255, __pyx_L1_error) + free(__pyx_v_tmpdata); - /* "View.MemoryView":1253 + /* "View.MemoryView":1334 * - * @cname('__pyx_memoryview_err_extents') - * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<< - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError("got differing extents in dimension %d (got %d and %d)" % + * free(tmpdata) + * return 0 # <<<<<<<<<<<<<< + * + * @cname('__pyx_memoryview_broadcast_leading') + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "View.MemoryView":1265 + * + * @cname('__pyx_memoryview_copy_contents') + * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<< + * __Pyx_memviewslice dst, + * int src_ndim, int dst_ndim, */ /* 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("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename); + #ifdef WITH_THREAD + __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; - __Pyx_RefNannyFinishContext(); #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif + __pyx_L0:; return __pyx_r; } -/* "View.MemoryView":1259 - * - * @cname('__pyx_memoryview_err_dim') - * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<< - * raise error(msg.decode('ascii') % dim) +/* "View.MemoryView":1337 * + * @cname('__pyx_memoryview_broadcast_leading') + * cdef void broadcast_leading(__Pyx_memviewslice *mslice, # <<<<<<<<<<<<<< + * int ndim, + * int ndim_other) noexcept nogil: */ -static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("_err_dim", 0); - __Pyx_INCREF(__pyx_v_error); +static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim, int __pyx_v_ndim_other) { + int __pyx_v_i; + int __pyx_v_offset; + int __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; - /* "View.MemoryView":1260 - * @cname('__pyx_memoryview_err_dim') - * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: - * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<< + /* "View.MemoryView":1341 + * int ndim_other) noexcept nogil: + * cdef int i + * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<< * - * @cname('__pyx_memoryview_err') + * for i in range(ndim - 1, -1, -1): */ - __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1260, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1260, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 1260, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_INCREF(__pyx_v_error); - __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_2)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_2); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - } - } - __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_2, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1260, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 1260, __pyx_L1_error) + __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim); - /* "View.MemoryView":1259 - * - * @cname('__pyx_memoryview_err_dim') - * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<< - * raise error(msg.decode('ascii') % dim) + /* "View.MemoryView":1343 + * cdef int offset = ndim_other - ndim * + * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< + * mslice.shape[i + offset] = mslice.shape[i] + * mslice.strides[i + offset] = mslice.strides[i] */ + for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) { + __pyx_v_i = __pyx_t_1; - /* 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("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __Pyx_XDECREF(__pyx_v_error); - __Pyx_RefNannyFinishContext(); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - return __pyx_r; -} + /* "View.MemoryView":1344 + * + * for i in range(ndim - 1, -1, -1): + * mslice.shape[i + offset] = mslice.shape[i] # <<<<<<<<<<<<<< + * mslice.strides[i + offset] = mslice.strides[i] + * mslice.suboffsets[i + offset] = mslice.suboffsets[i] + */ + (__pyx_v_mslice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->shape[__pyx_v_i]); -/* "View.MemoryView":1263 + /* "View.MemoryView":1345 + * for i in range(ndim - 1, -1, -1): + * mslice.shape[i + offset] = mslice.shape[i] + * mslice.strides[i + offset] = mslice.strides[i] # <<<<<<<<<<<<<< + * mslice.suboffsets[i + offset] = mslice.suboffsets[i] * - * @cname('__pyx_memoryview_err') - * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<< - * if msg != NULL: - * raise error(msg.decode('ascii')) */ + (__pyx_v_mslice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->strides[__pyx_v_i]); -static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("_err", 0); - __Pyx_INCREF(__pyx_v_error); + /* "View.MemoryView":1346 + * mslice.shape[i + offset] = mslice.shape[i] + * mslice.strides[i + offset] = mslice.strides[i] + * mslice.suboffsets[i + offset] = mslice.suboffsets[i] # <<<<<<<<<<<<<< + * + * for i in range(offset): + */ + (__pyx_v_mslice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->suboffsets[__pyx_v_i]); + } - /* "View.MemoryView":1264 - * @cname('__pyx_memoryview_err') - * cdef int _err(object error, char *msg) except -1 with gil: - * if msg != NULL: # <<<<<<<<<<<<<< - * raise error(msg.decode('ascii')) - * else: + /* "View.MemoryView":1348 + * mslice.suboffsets[i + offset] = mslice.suboffsets[i] + * + * for i in range(offset): # <<<<<<<<<<<<<< + * mslice.shape[i] = 1 + * mslice.strides[i] = mslice.strides[0] */ - __pyx_t_1 = ((__pyx_v_msg != NULL) != 0); - if (unlikely(__pyx_t_1)) { + __pyx_t_1 = __pyx_v_offset; + __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; - /* "View.MemoryView":1265 - * cdef int _err(object error, char *msg) except -1 with gil: - * if msg != NULL: - * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<< - * else: - * raise error + /* "View.MemoryView":1349 + * + * for i in range(offset): + * mslice.shape[i] = 1 # <<<<<<<<<<<<<< + * mslice.strides[i] = mslice.strides[0] + * mslice.suboffsets[i] = -1 */ - __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1265, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_error); - __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1265, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(2, 1265, __pyx_L1_error) + (__pyx_v_mslice->shape[__pyx_v_i]) = 1; - /* "View.MemoryView":1264 - * @cname('__pyx_memoryview_err') - * cdef int _err(object error, char *msg) except -1 with gil: - * if msg != NULL: # <<<<<<<<<<<<<< - * raise error(msg.decode('ascii')) - * else: + /* "View.MemoryView":1350 + * for i in range(offset): + * mslice.shape[i] = 1 + * mslice.strides[i] = mslice.strides[0] # <<<<<<<<<<<<<< + * mslice.suboffsets[i] = -1 + * */ - } + (__pyx_v_mslice->strides[__pyx_v_i]) = (__pyx_v_mslice->strides[0]); - /* "View.MemoryView":1267 - * raise error(msg.decode('ascii')) - * else: - * raise error # <<<<<<<<<<<<<< + /* "View.MemoryView":1351 + * mslice.shape[i] = 1 + * mslice.strides[i] = mslice.strides[0] + * mslice.suboffsets[i] = -1 # <<<<<<<<<<<<<< + * * - * @cname('__pyx_memoryview_copy_contents') */ - /*else*/ { - __Pyx_Raise(__pyx_v_error, 0, 0, 0); - __PYX_ERR(2, 1267, __pyx_L1_error) + (__pyx_v_mslice->suboffsets[__pyx_v_i]) = -1L; } - /* "View.MemoryView":1263 + /* "View.MemoryView":1337 * - * @cname('__pyx_memoryview_err') - * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<< - * if msg != NULL: - * raise error(msg.decode('ascii')) + * @cname('__pyx_memoryview_broadcast_leading') + * cdef void broadcast_leading(__Pyx_memviewslice *mslice, # <<<<<<<<<<<<<< + * int ndim, + * int ndim_other) noexcept nogil: */ /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __Pyx_XDECREF(__pyx_v_error); - __Pyx_RefNannyFinishContext(); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - return __pyx_r; } -/* "View.MemoryView":1270 +/* "View.MemoryView":1359 * - * @cname('__pyx_memoryview_copy_contents') - * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice dst, - * int src_ndim, int dst_ndim, + * @cname('__pyx_memoryview_refcount_copying') + * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, int ndim, bint inc) noexcept nogil: # <<<<<<<<<<<<<< + * + * if dtype_is_object: */ -static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) { - void *__pyx_v_tmpdata; - size_t __pyx_v_itemsize; - int __pyx_v_i; - char __pyx_v_order; - int __pyx_v_broadcasting; - int __pyx_v_direct_copy; - __Pyx_memviewslice __pyx_v_tmp; - int __pyx_v_ndim; - int __pyx_r; - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - void *__pyx_t_7; - int __pyx_t_8; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - - /* "View.MemoryView":1278 - * Check for overlapping memory and verify the shapes. - * """ - * cdef void *tmpdata = NULL # <<<<<<<<<<<<<< - * cdef size_t itemsize = src.memview.view.itemsize - * cdef int i - */ - __pyx_v_tmpdata = NULL; +static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) { - /* "View.MemoryView":1279 - * """ - * cdef void *tmpdata = NULL - * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<< - * cdef int i - * cdef char order = get_best_order(&src, src_ndim) + /* "View.MemoryView":1361 + * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, int ndim, bint inc) noexcept nogil: + * + * if dtype_is_object: # <<<<<<<<<<<<<< + * refcount_objects_in_slice_with_gil(dst.data, dst.shape, dst.strides, ndim, inc) + * */ - __pyx_t_1 = __pyx_v_src.memview->view.itemsize; - __pyx_v_itemsize = __pyx_t_1; + if (__pyx_v_dtype_is_object) { - /* "View.MemoryView":1281 - * cdef size_t itemsize = src.memview.view.itemsize - * cdef int i - * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<< - * cdef bint broadcasting = False - * cdef bint direct_copy = False + /* "View.MemoryView":1362 + * + * if dtype_is_object: + * refcount_objects_in_slice_with_gil(dst.data, dst.shape, dst.strides, ndim, inc) # <<<<<<<<<<<<<< + * + * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') */ - __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim); + __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc); - /* "View.MemoryView":1282 - * cdef int i - * cdef char order = get_best_order(&src, src_ndim) - * cdef bint broadcasting = False # <<<<<<<<<<<<<< - * cdef bint direct_copy = False - * cdef __Pyx_memviewslice tmp + /* "View.MemoryView":1361 + * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, int ndim, bint inc) noexcept nogil: + * + * if dtype_is_object: # <<<<<<<<<<<<<< + * refcount_objects_in_slice_with_gil(dst.data, dst.shape, dst.strides, ndim, inc) + * */ - __pyx_v_broadcasting = 0; + } - /* "View.MemoryView":1283 - * cdef char order = get_best_order(&src, src_ndim) - * cdef bint broadcasting = False - * cdef bint direct_copy = False # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice tmp + /* "View.MemoryView":1359 * + * @cname('__pyx_memoryview_refcount_copying') + * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, int ndim, bint inc) noexcept nogil: # <<<<<<<<<<<<<< + * + * if dtype_is_object: */ - __pyx_v_direct_copy = 0; - /* "View.MemoryView":1286 - * cdef __Pyx_memviewslice tmp + /* function exit code */ +} + +/* "View.MemoryView":1365 * - * if src_ndim < dst_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: + * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') + * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< + * Py_ssize_t *strides, int ndim, + * bint inc) noexcept with gil: */ - __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0); - if (__pyx_t_2) { - /* "View.MemoryView":1287 +static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); + #endif + + /* "View.MemoryView":1368 + * Py_ssize_t *strides, int ndim, + * bint inc) noexcept with gil: + * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<< * - * if src_ndim < dst_ndim: - * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<< - * elif dst_ndim < src_ndim: - * broadcast_leading(&dst, dst_ndim, src_ndim) + * @cname('__pyx_memoryview_refcount_objects_in_slice') */ - __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim); + __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc); - /* "View.MemoryView":1286 - * cdef __Pyx_memviewslice tmp + /* "View.MemoryView":1365 * - * if src_ndim < dst_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: + * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') + * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< + * Py_ssize_t *strides, int ndim, + * bint inc) noexcept with gil: */ - goto __pyx_L3; - } - /* "View.MemoryView":1288 - * if src_ndim < dst_ndim: - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&dst, dst_ndim, src_ndim) - * - */ - __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0); - if (__pyx_t_2) { + /* function exit code */ + #ifdef WITH_THREAD + __Pyx_PyGILState_Release(__pyx_gilstate_save); + #endif +} - /* "View.MemoryView":1289 - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: - * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<< +/* "View.MemoryView":1371 * - * cdef int ndim = max(src_ndim, dst_ndim) + * @cname('__pyx_memoryview_refcount_objects_in_slice') + * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< + * Py_ssize_t *strides, int ndim, bint inc) noexcept: + * cdef Py_ssize_t i */ - __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim); - /* "View.MemoryView":1288 - * if src_ndim < dst_ndim: - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&dst, dst_ndim, src_ndim) - * - */ - } - __pyx_L3:; +static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) { + CYTHON_UNUSED Py_ssize_t __pyx_v_i; + Py_ssize_t __pyx_v_stride; + Py_ssize_t __pyx_t_1; + Py_ssize_t __pyx_t_2; + Py_ssize_t __pyx_t_3; + int __pyx_t_4; - /* "View.MemoryView":1291 - * broadcast_leading(&dst, dst_ndim, src_ndim) - * - * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<< + /* "View.MemoryView":1374 + * Py_ssize_t *strides, int ndim, bint inc) noexcept: + * cdef Py_ssize_t i + * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<< * - * for i in range(ndim): + * for i in range(shape[0]): */ - __pyx_t_3 = __pyx_v_dst_ndim; - __pyx_t_4 = __pyx_v_src_ndim; - if (((__pyx_t_3 > __pyx_t_4) != 0)) { - __pyx_t_5 = __pyx_t_3; - } else { - __pyx_t_5 = __pyx_t_4; - } - __pyx_v_ndim = __pyx_t_5; + __pyx_v_stride = (__pyx_v_strides[0]); - /* "View.MemoryView":1293 - * cdef int ndim = max(src_ndim, dst_ndim) + /* "View.MemoryView":1376 + * cdef Py_ssize_t stride = strides[0] * - * for i in range(ndim): # <<<<<<<<<<<<<< - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: + * for i in range(shape[0]): # <<<<<<<<<<<<<< + * if ndim == 1: + * if inc: */ - __pyx_t_5 = __pyx_v_ndim; - __pyx_t_3 = __pyx_t_5; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; + __pyx_t_1 = (__pyx_v_shape[0]); + __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; - /* "View.MemoryView":1294 + /* "View.MemoryView":1377 * - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<< - * if src.shape[i] == 1: - * broadcasting = True - */ - __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1295 - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: # <<<<<<<<<<<<<< - * broadcasting = True - * src.strides[i] = 0 + * for i in range(shape[0]): + * if ndim == 1: # <<<<<<<<<<<<<< + * if inc: + * Py_INCREF(( data)[0]) */ - __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0); - if (__pyx_t_2) { + __pyx_t_4 = (__pyx_v_ndim == 1); + if (__pyx_t_4) { - /* "View.MemoryView":1296 - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: - * broadcasting = True # <<<<<<<<<<<<<< - * src.strides[i] = 0 + /* "View.MemoryView":1378 + * for i in range(shape[0]): + * if ndim == 1: + * if inc: # <<<<<<<<<<<<<< + * Py_INCREF(( data)[0]) * else: */ - __pyx_v_broadcasting = 1; + if (__pyx_v_inc) { - /* "View.MemoryView":1297 - * if src.shape[i] == 1: - * broadcasting = True - * src.strides[i] = 0 # <<<<<<<<<<<<<< + /* "View.MemoryView":1379 + * if ndim == 1: + * if inc: + * Py_INCREF(( data)[0]) # <<<<<<<<<<<<<< * else: - * _err_extents(i, dst.shape[i], src.shape[i]) + * Py_DECREF(( data)[0]) */ - (__pyx_v_src.strides[__pyx_v_i]) = 0; + Py_INCREF((((PyObject **)__pyx_v_data)[0])); - /* "View.MemoryView":1295 - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: # <<<<<<<<<<<<<< - * broadcasting = True - * src.strides[i] = 0 + /* "View.MemoryView":1378 + * for i in range(shape[0]): + * if ndim == 1: + * if inc: # <<<<<<<<<<<<<< + * Py_INCREF(( data)[0]) + * else: */ - goto __pyx_L7; + goto __pyx_L6; } - /* "View.MemoryView":1299 - * src.strides[i] = 0 + /* "View.MemoryView":1381 + * Py_INCREF(( data)[0]) * else: - * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<< - * - * if src.suboffsets[i] >= 0: + * Py_DECREF(( data)[0]) # <<<<<<<<<<<<<< + * else: + * refcount_objects_in_slice(data, shape + 1, strides + 1, ndim - 1, inc) */ /*else*/ { - __pyx_t_6 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(2, 1299, __pyx_L1_error) + Py_DECREF((((PyObject **)__pyx_v_data)[0])); } - __pyx_L7:; + __pyx_L6:; - /* "View.MemoryView":1294 + /* "View.MemoryView":1377 * - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<< - * if src.shape[i] == 1: - * broadcasting = True + * for i in range(shape[0]): + * if ndim == 1: # <<<<<<<<<<<<<< + * if inc: + * Py_INCREF(( data)[0]) */ + goto __pyx_L5; } - /* "View.MemoryView":1301 - * _err_extents(i, dst.shape[i], src.shape[i]) - * - * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<< - * _err_dim(ValueError, "Dimension %d is not direct", i) + /* "View.MemoryView":1383 + * Py_DECREF(( data)[0]) + * else: + * refcount_objects_in_slice(data, shape + 1, strides + 1, ndim - 1, inc) # <<<<<<<<<<<<<< * + * data += stride */ - __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0); - if (__pyx_t_2) { + /*else*/ { + __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc); + } + __pyx_L5:; - /* "View.MemoryView":1302 - * - * if src.suboffsets[i] >= 0: - * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<< + /* "View.MemoryView":1385 + * refcount_objects_in_slice(data, shape + 1, strides + 1, ndim - 1, inc) * - * if slices_overlap(&src, &dst, ndim, itemsize): - */ - __pyx_t_6 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, ((char *)"Dimension %d is not direct"), __pyx_v_i); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(2, 1302, __pyx_L1_error) - - /* "View.MemoryView":1301 - * _err_extents(i, dst.shape[i], src.shape[i]) + * data += stride # <<<<<<<<<<<<<< * - * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<< - * _err_dim(ValueError, "Dimension %d is not direct", i) * */ - } + __pyx_v_data = (__pyx_v_data + __pyx_v_stride); } - /* "View.MemoryView":1304 - * _err_dim(ValueError, "Dimension %d is not direct", i) - * - * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<< + /* "View.MemoryView":1371 * - * if not slice_is_contig(src, order, ndim): + * @cname('__pyx_memoryview_refcount_objects_in_slice') + * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< + * Py_ssize_t *strides, int ndim, bint inc) noexcept: + * cdef Py_ssize_t i */ - __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0); - if (__pyx_t_2) { - /* "View.MemoryView":1306 - * if slices_overlap(&src, &dst, ndim, itemsize): - * - * if not slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<< - * order = get_best_order(&dst, ndim) - * - */ - __pyx_t_2 = ((!(__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0)) != 0); - if (__pyx_t_2) { + /* function exit code */ +} - /* "View.MemoryView":1307 - * - * if not slice_is_contig(src, order, ndim): - * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<< +/* "View.MemoryView":1391 * - * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) + * @cname('__pyx_memoryview_slice_assign_scalar') + * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<< + * size_t itemsize, void *item, + * bint dtype_is_object) noexcept nogil: */ - __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim); - /* "View.MemoryView":1306 - * if slices_overlap(&src, &dst, ndim, itemsize): - * - * if not slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<< - * order = get_best_order(&dst, ndim) - * +static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) { + + /* "View.MemoryView":1394 + * size_t itemsize, void *item, + * bint dtype_is_object) noexcept nogil: + * refcount_copying(dst, dtype_is_object, ndim, inc=False) # <<<<<<<<<<<<<< + * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, itemsize, item) + * refcount_copying(dst, dtype_is_object, ndim, inc=True) */ - } + __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0); - /* "View.MemoryView":1309 - * order = get_best_order(&dst, ndim) - * - * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<< - * src = tmp + /* "View.MemoryView":1395 + * bint dtype_is_object) noexcept nogil: + * refcount_copying(dst, dtype_is_object, ndim, inc=False) + * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, itemsize, item) # <<<<<<<<<<<<<< + * refcount_copying(dst, dtype_is_object, ndim, inc=True) * */ - __pyx_t_7 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_7 == ((void *)NULL))) __PYX_ERR(2, 1309, __pyx_L1_error) - __pyx_v_tmpdata = __pyx_t_7; + __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item); - /* "View.MemoryView":1310 + /* "View.MemoryView":1396 + * refcount_copying(dst, dtype_is_object, ndim, inc=False) + * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, itemsize, item) + * refcount_copying(dst, dtype_is_object, ndim, inc=True) # <<<<<<<<<<<<<< * - * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) - * src = tmp # <<<<<<<<<<<<<< * - * if not broadcasting: */ - __pyx_v_src = __pyx_v_tmp; + __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1); - /* "View.MemoryView":1304 - * _err_dim(ValueError, "Dimension %d is not direct", i) - * - * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<< + /* "View.MemoryView":1391 * - * if not slice_is_contig(src, order, ndim): + * @cname('__pyx_memoryview_slice_assign_scalar') + * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<< + * size_t itemsize, void *item, + * bint dtype_is_object) noexcept nogil: */ - } - /* "View.MemoryView":1312 - * src = tmp - * - * if not broadcasting: # <<<<<<<<<<<<<< - * + /* function exit code */ +} + +/* "View.MemoryView":1400 * + * @cname('__pyx_memoryview__slice_assign_scalar') + * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< + * Py_ssize_t *strides, int ndim, + * size_t itemsize, void *item) noexcept nogil: */ - __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0); - if (__pyx_t_2) { - /* "View.MemoryView":1315 - * +static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) { + CYTHON_UNUSED Py_ssize_t __pyx_v_i; + Py_ssize_t __pyx_v_stride; + Py_ssize_t __pyx_v_extent; + int __pyx_t_1; + Py_ssize_t __pyx_t_2; + Py_ssize_t __pyx_t_3; + Py_ssize_t __pyx_t_4; + + /* "View.MemoryView":1404 + * size_t itemsize, void *item) noexcept nogil: + * cdef Py_ssize_t i + * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<< + * cdef Py_ssize_t extent = shape[0] * - * if slice_is_contig(src, 'C', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): */ - __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, 'C', __pyx_v_ndim) != 0); - if (__pyx_t_2) { + __pyx_v_stride = (__pyx_v_strides[0]); - /* "View.MemoryView":1316 + /* "View.MemoryView":1405 + * cdef Py_ssize_t i + * cdef Py_ssize_t stride = strides[0] + * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<< * - * if slice_is_contig(src, 'C', ndim): - * direct_copy = slice_is_contig(dst, 'C', ndim) # <<<<<<<<<<<<<< - * elif slice_is_contig(src, 'F', ndim): - * direct_copy = slice_is_contig(dst, 'F', ndim) + * if ndim == 1: */ - __pyx_v_direct_copy = __pyx_memviewslice_is_contig(__pyx_v_dst, 'C', __pyx_v_ndim); + __pyx_v_extent = (__pyx_v_shape[0]); - /* "View.MemoryView":1315 + /* "View.MemoryView":1407 + * cdef Py_ssize_t extent = shape[0] * - * - * if slice_is_contig(src, 'C', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): + * if ndim == 1: # <<<<<<<<<<<<<< + * for i in range(extent): + * memcpy(data, item, itemsize) */ - goto __pyx_L12; - } + __pyx_t_1 = (__pyx_v_ndim == 1); + if (__pyx_t_1) { - /* "View.MemoryView":1317 - * if slice_is_contig(src, 'C', ndim): - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'F', ndim) + /* "View.MemoryView":1408 * + * if ndim == 1: + * for i in range(extent): # <<<<<<<<<<<<<< + * memcpy(data, item, itemsize) + * data += stride */ - __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, 'F', __pyx_v_ndim) != 0); - if (__pyx_t_2) { + __pyx_t_2 = __pyx_v_extent; + __pyx_t_3 = __pyx_t_2; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_i = __pyx_t_4; - /* "View.MemoryView":1318 - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): - * direct_copy = slice_is_contig(dst, 'F', ndim) # <<<<<<<<<<<<<< - * - * if direct_copy: + /* "View.MemoryView":1409 + * if ndim == 1: + * for i in range(extent): + * memcpy(data, item, itemsize) # <<<<<<<<<<<<<< + * data += stride + * else: */ - __pyx_v_direct_copy = __pyx_memviewslice_is_contig(__pyx_v_dst, 'F', __pyx_v_ndim); + (void)(memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize)); - /* "View.MemoryView":1317 - * if slice_is_contig(src, 'C', ndim): - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'F', ndim) - * + /* "View.MemoryView":1410 + * for i in range(extent): + * memcpy(data, item, itemsize) + * data += stride # <<<<<<<<<<<<<< + * else: + * for i in range(extent): */ + __pyx_v_data = (__pyx_v_data + __pyx_v_stride); } - __pyx_L12:; - /* "View.MemoryView":1320 - * direct_copy = slice_is_contig(dst, 'F', ndim) - * - * if direct_copy: # <<<<<<<<<<<<<< + /* "View.MemoryView":1407 + * cdef Py_ssize_t extent = shape[0] * - * refcount_copying(&dst, dtype_is_object, ndim, False) + * if ndim == 1: # <<<<<<<<<<<<<< + * for i in range(extent): + * memcpy(data, item, itemsize) */ - __pyx_t_2 = (__pyx_v_direct_copy != 0); - if (__pyx_t_2) { + goto __pyx_L3; + } - /* "View.MemoryView":1322 - * if direct_copy: - * - * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<< - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) - * refcount_copying(&dst, dtype_is_object, ndim, True) + /* "View.MemoryView":1412 + * data += stride + * else: + * for i in range(extent): # <<<<<<<<<<<<<< + * _slice_assign_scalar(data, shape + 1, strides + 1, ndim - 1, itemsize, item) + * data += stride */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0); + /*else*/ { + __pyx_t_2 = __pyx_v_extent; + __pyx_t_3 = __pyx_t_2; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_i = __pyx_t_4; - /* "View.MemoryView":1323 + /* "View.MemoryView":1413 + * else: + * for i in range(extent): + * _slice_assign_scalar(data, shape + 1, strides + 1, ndim - 1, itemsize, item) # <<<<<<<<<<<<<< + * data += stride * - * refcount_copying(&dst, dtype_is_object, ndim, False) - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<< - * refcount_copying(&dst, dtype_is_object, ndim, True) - * free(tmpdata) - */ - (void)(memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim))); - - /* "View.MemoryView":1324 - * refcount_copying(&dst, dtype_is_object, ndim, False) - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) - * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<< - * free(tmpdata) - * return 0 */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1); + __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item); - /* "View.MemoryView":1325 - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) - * refcount_copying(&dst, dtype_is_object, ndim, True) - * free(tmpdata) # <<<<<<<<<<<<<< - * return 0 + /* "View.MemoryView":1414 + * for i in range(extent): + * _slice_assign_scalar(data, shape + 1, strides + 1, ndim - 1, itemsize, item) + * data += stride # <<<<<<<<<<<<<< + * * */ - free(__pyx_v_tmpdata); + __pyx_v_data = (__pyx_v_data + __pyx_v_stride); + } + } + __pyx_L3:; - /* "View.MemoryView":1326 - * refcount_copying(&dst, dtype_is_object, ndim, True) - * free(tmpdata) - * return 0 # <<<<<<<<<<<<<< + /* "View.MemoryView":1400 * - * if order == 'F' == get_best_order(&dst, ndim): + * @cname('__pyx_memoryview__slice_assign_scalar') + * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< + * Py_ssize_t *strides, int ndim, + * size_t itemsize, void *item) noexcept nogil: */ - __pyx_r = 0; - goto __pyx_L0; - /* "View.MemoryView":1320 - * direct_copy = slice_is_contig(dst, 'F', ndim) - * - * if direct_copy: # <<<<<<<<<<<<<< - * - * refcount_copying(&dst, dtype_is_object, ndim, False) + /* function exit code */ +} + +/* "(tree fragment)":1 + * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result */ + +/* Python wrapper */ +static PyObject *__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum(PyObject *__pyx_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*/ +static PyMethodDef __pyx_mdef_15View_dot_MemoryView_1__pyx_unpickle_Enum = {"__pyx_unpickle_Enum", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum(PyObject *__pyx_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___pyx_type = 0; + long __pyx_v___pyx_checksum; + PyObject *__pyx_v___pyx_state = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__pyx_unpickle_Enum (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_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + 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_pyx_type)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 1, __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_pyx_checksum)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, 1); __PYX_ERR(1, 1, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pyx_state)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, 2); __PYX_ERR(1, 1, __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, "__pyx_unpickle_Enum") < 0)) __PYX_ERR(1, 1, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + } + __pyx_v___pyx_type = values[0]; + __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) + __pyx_v___pyx_state = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, __pyx_nargs); __PYX_ERR(1, 1, __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("View.MemoryView.__pyx_unpickle_Enum", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_15View_dot_MemoryView___pyx_unpickle_Enum(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); - /* "View.MemoryView":1312 - * src = tmp - * - * if not broadcasting: # <<<<<<<<<<<<<< - * - * - */ + /* 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; +} - /* "View.MemoryView":1328 - * return 0 - * - * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<< - * - * +static PyObject *__pyx_pf_15View_dot_MemoryView___pyx_unpickle_Enum(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_v___pyx_PickleError = 0; + PyObject *__pyx_v___pyx_result = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_unpickle_Enum", 1); + + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum not in (0x82a3537, 0x6ae9995, 0xb068931): # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum */ - __pyx_t_2 = (__pyx_v_order == 'F'); + __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_t_1, __pyx_tuple__8, Py_NE)); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(1, 4, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_2) { - __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim)); - } - __pyx_t_8 = (__pyx_t_2 != 0); - if (__pyx_t_8) { - /* "View.MemoryView":1331 - * - * - * transpose_memslice(&src) # <<<<<<<<<<<<<< - * transpose_memslice(&dst) - * + /* "(tree fragment)":5 + * cdef object __pyx_result + * if __pyx_checksum not in (0x82a3537, 0x6ae9995, 0xb068931): + * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< + * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum + * __pyx_result = Enum.__new__(__pyx_type) */ - __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(2, 1331, __pyx_L1_error) + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_s_PickleError); + __Pyx_GIVEREF(__pyx_n_s_PickleError); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_PickleError)) __PYX_ERR(1, 5, __pyx_L1_error); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_1); + __pyx_v___pyx_PickleError = __pyx_t_1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "View.MemoryView":1332 - * - * transpose_memslice(&src) - * transpose_memslice(&dst) # <<<<<<<<<<<<<< - * - * refcount_copying(&dst, dtype_is_object, ndim, False) + /* "(tree fragment)":6 + * if __pyx_checksum not in (0x82a3537, 0x6ae9995, 0xb068931): + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum # <<<<<<<<<<<<<< + * __pyx_result = Enum.__new__(__pyx_type) + * if __pyx_state is not None: */ - __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(2, 1332, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_0x_x_vs_0, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_v___pyx_PickleError, __pyx_t_1, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(1, 6, __pyx_L1_error) - /* "View.MemoryView":1328 - * return 0 - * - * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<< - * - * + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum not in (0x82a3537, 0x6ae9995, 0xb068931): # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum */ } - /* "View.MemoryView":1334 - * transpose_memslice(&dst) - * - * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<< - * copy_strided_to_strided(&src, &dst, ndim, itemsize) - * refcount_copying(&dst, dtype_is_object, ndim, True) + /* "(tree fragment)":7 + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum + * __pyx_result = Enum.__new__(__pyx_type) # <<<<<<<<<<<<<< + * if __pyx_state is not None: + * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_MemviewEnum_type), __pyx_n_s_new); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = NULL; + __pyx_t_5 = 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_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v___pyx_type}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v___pyx_result = __pyx_t_1; + __pyx_t_1 = 0; - /* "View.MemoryView":1335 - * - * refcount_copying(&dst, dtype_is_object, ndim, False) - * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<< - * refcount_copying(&dst, dtype_is_object, ndim, True) - * + /* "(tree fragment)":8 + * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum + * __pyx_result = Enum.__new__(__pyx_type) + * if __pyx_state is not None: # <<<<<<<<<<<<<< + * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) + * return __pyx_result */ - copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize); + __pyx_t_2 = (__pyx_v___pyx_state != Py_None); + if (__pyx_t_2) { - /* "View.MemoryView":1336 - * refcount_copying(&dst, dtype_is_object, ndim, False) - * copy_strided_to_strided(&src, &dst, ndim, itemsize) - * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<< - * - * free(tmpdata) + /* "(tree fragment)":9 + * __pyx_result = Enum.__new__(__pyx_type) + * if __pyx_state is not None: + * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< + * return __pyx_result + * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1); + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None) || __Pyx_RaiseUnexpectedTypeError("tuple", __pyx_v___pyx_state))) __PYX_ERR(1, 9, __pyx_L1_error) + __pyx_t_1 = __pyx_unpickle_Enum__set_state(((struct __pyx_MemviewEnum_obj *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "View.MemoryView":1338 - * refcount_copying(&dst, dtype_is_object, ndim, True) - * - * free(tmpdata) # <<<<<<<<<<<<<< - * return 0 - * + /* "(tree fragment)":8 + * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum + * __pyx_result = Enum.__new__(__pyx_type) + * if __pyx_state is not None: # <<<<<<<<<<<<<< + * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) + * return __pyx_result */ - free(__pyx_v_tmpdata); + } - /* "View.MemoryView":1339 - * - * free(tmpdata) - * return 0 # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_broadcast_leading') + /* "(tree fragment)":10 + * if __pyx_state is not None: + * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) + * return __pyx_result # <<<<<<<<<<<<<< + * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): + * __pyx_result.name = __pyx_state[0] */ - __pyx_r = 0; + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v___pyx_result); + __pyx_r = __pyx_v___pyx_result; goto __pyx_L0; - /* "View.MemoryView":1270 - * - * @cname('__pyx_memoryview_copy_contents') - * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice dst, - * int src_ndim, int dst_ndim, + /* "(tree fragment)":1 + * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result */ /* function exit code */ __pyx_L1_error:; - { - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("View.MemoryView.__pyx_unpickle_Enum", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v___pyx_PickleError); + __Pyx_XDECREF(__pyx_v___pyx_result); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":11 + * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result.name = __pyx_state[0] + * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): + */ + +static PyObject *__pyx_unpickle_Enum__set_state(struct __pyx_MemviewEnum_obj *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + Py_ssize_t __pyx_t_3; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_unpickle_Enum__set_state", 1); + + /* "(tree fragment)":12 + * return __pyx_result + * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): + * __pyx_result.name = __pyx_state[0] # <<<<<<<<<<<<<< + * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): + * __pyx_result.__dict__.update(__pyx_state[1]) + */ + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->name); + __Pyx_DECREF(__pyx_v___pyx_result->name); + __pyx_v___pyx_result->name = __pyx_t_1; + __pyx_t_1 = 0; + + /* "(tree fragment)":13 + * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): + * __pyx_result.name = __pyx_state[0] + * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< + * __pyx_result.__dict__.update(__pyx_state[1]) + */ + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(1, 13, __pyx_L1_error) + } + __pyx_t_3 = __Pyx_PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_4 = (__pyx_t_3 > 1); + if (__pyx_t_4) { + } else { + __pyx_t_2 = __pyx_t_4; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_2 = __pyx_t_4; + __pyx_L4_bool_binop_done:; + if (__pyx_t_2) { + + /* "(tree fragment)":14 + * __pyx_result.name = __pyx_state[0] + * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): + * __pyx_result.__dict__.update(__pyx_state[1]) # <<<<<<<<<<<<<< + */ + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_update); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 14, __pyx_L1_error) + } + __pyx_t_5 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = NULL; + __pyx_t_8 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_7)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + __pyx_t_8 = 1; + } + } #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_7, __pyx_t_5}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_8, 1+__pyx_t_8); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":13 + * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): + * __pyx_result.name = __pyx_state[0] + * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< + * __pyx_result.__dict__.update(__pyx_state[1]) + */ } - __pyx_r = -1; + + /* "(tree fragment)":11 + * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result.name = __pyx_state[0] + * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("View.MemoryView.__pyx_unpickle_Enum__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "View.MemoryView":1342 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":245 * - * @cname('__pyx_memoryview_broadcast_leading') - * cdef void broadcast_leading(__Pyx_memviewslice *mslice, # <<<<<<<<<<<<<< - * int ndim, - * int ndim_other) nogil: + * @property + * cdef inline PyObject* base(self) nogil: # <<<<<<<<<<<<<< + * """Returns a borrowed reference to the object owning the data/memory. + * """ */ -static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim, int __pyx_v_ndim_other) { - int __pyx_v_i; - int __pyx_v_offset; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; +static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject *__pyx_v_self) { + PyObject *__pyx_r; - /* "View.MemoryView":1346 - * int ndim_other) nogil: - * cdef int i - * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<< + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":248 + * """Returns a borrowed reference to the object owning the data/memory. + * """ + * return PyArray_BASE(self) # <<<<<<<<<<<<<< * - * for i in range(ndim - 1, -1, -1): + * @property */ - __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim); + __pyx_r = PyArray_BASE(__pyx_v_self); + goto __pyx_L0; - /* "View.MemoryView":1348 - * cdef int offset = ndim_other - ndim + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":245 * - * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< - * mslice.shape[i + offset] = mslice.shape[i] - * mslice.strides[i + offset] = mslice.strides[i] + * @property + * cdef inline PyObject* base(self) nogil: # <<<<<<<<<<<<<< + * """Returns a borrowed reference to the object owning the data/memory. + * """ */ - for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) { - __pyx_v_i = __pyx_t_1; - /* "View.MemoryView":1349 + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":251 * - * for i in range(ndim - 1, -1, -1): - * mslice.shape[i + offset] = mslice.shape[i] # <<<<<<<<<<<<<< - * mslice.strides[i + offset] = mslice.strides[i] - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] + * @property + * cdef inline dtype descr(self): # <<<<<<<<<<<<<< + * """Returns an owned reference to the dtype of the array. + * """ */ - (__pyx_v_mslice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->shape[__pyx_v_i]); - /* "View.MemoryView":1350 - * for i in range(ndim - 1, -1, -1): - * mslice.shape[i + offset] = mslice.shape[i] - * mslice.strides[i + offset] = mslice.strides[i] # <<<<<<<<<<<<<< - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] +static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArrayObject *__pyx_v_self) { + PyArray_Descr *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyArray_Descr *__pyx_t_1; + __Pyx_RefNannySetupContext("descr", 1); + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":254 + * """Returns an owned reference to the dtype of the array. + * """ + * return PyArray_DESCR(self) # <<<<<<<<<<<<<< * + * @property */ - (__pyx_v_mslice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->strides[__pyx_v_i]); + __Pyx_XDECREF((PyObject *)__pyx_r); + __pyx_t_1 = PyArray_DESCR(__pyx_v_self); + __Pyx_INCREF((PyObject *)((PyArray_Descr *)__pyx_t_1)); + __pyx_r = ((PyArray_Descr *)__pyx_t_1); + goto __pyx_L0; - /* "View.MemoryView":1351 - * mslice.shape[i + offset] = mslice.shape[i] - * mslice.strides[i + offset] = mslice.strides[i] - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] # <<<<<<<<<<<<<< + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":251 * - * for i in range(offset): + * @property + * cdef inline dtype descr(self): # <<<<<<<<<<<<<< + * """Returns an owned reference to the dtype of the array. + * """ */ - (__pyx_v_mslice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->suboffsets[__pyx_v_i]); - } - /* "View.MemoryView":1353 - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] - * - * for i in range(offset): # <<<<<<<<<<<<<< - * mslice.shape[i] = 1 - * mslice.strides[i] = mslice.strides[0] - */ - __pyx_t_1 = __pyx_v_offset; - __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; + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF((PyObject *)__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} - /* "View.MemoryView":1354 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":257 * - * for i in range(offset): - * mslice.shape[i] = 1 # <<<<<<<<<<<<<< - * mslice.strides[i] = mslice.strides[0] - * mslice.suboffsets[i] = -1 + * @property + * cdef inline int ndim(self) nogil: # <<<<<<<<<<<<<< + * """Returns the number of dimensions in the array. + * """ */ - (__pyx_v_mslice->shape[__pyx_v_i]) = 1; - /* "View.MemoryView":1355 - * for i in range(offset): - * mslice.shape[i] = 1 - * mslice.strides[i] = mslice.strides[0] # <<<<<<<<<<<<<< - * mslice.suboffsets[i] = -1 - * - */ - (__pyx_v_mslice->strides[__pyx_v_i]) = (__pyx_v_mslice->strides[0]); +static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx_v_self) { + int __pyx_r; - /* "View.MemoryView":1356 - * mslice.shape[i] = 1 - * mslice.strides[i] = mslice.strides[0] - * mslice.suboffsets[i] = -1 # <<<<<<<<<<<<<< - * + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":260 + * """Returns the number of dimensions in the array. + * """ + * return PyArray_NDIM(self) # <<<<<<<<<<<<<< * + * @property */ - (__pyx_v_mslice->suboffsets[__pyx_v_i]) = -1L; - } + __pyx_r = PyArray_NDIM(__pyx_v_self); + goto __pyx_L0; - /* "View.MemoryView":1342 + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":257 * - * @cname('__pyx_memoryview_broadcast_leading') - * cdef void broadcast_leading(__Pyx_memviewslice *mslice, # <<<<<<<<<<<<<< - * int ndim, - * int ndim_other) nogil: + * @property + * cdef inline int ndim(self) nogil: # <<<<<<<<<<<<<< + * """Returns the number of dimensions in the array. + * """ */ /* function exit code */ + __pyx_L0:; + return __pyx_r; } -/* "View.MemoryView":1364 - * - * @cname('__pyx_memoryview_refcount_copying') - * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<< - * int ndim, bint inc) nogil: - * - */ - -static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) { - int __pyx_t_1; - - /* "View.MemoryView":1368 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":263 * - * - * if dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice_with_gil(dst.data, dst.shape, - * dst.strides, ndim, inc) + * @property + * cdef inline npy_intp *shape(self) nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the dimensions/shape of the array. + * The number of elements matches the number of dimensions of the array (ndim). */ - __pyx_t_1 = (__pyx_v_dtype_is_object != 0); - if (__pyx_t_1) { - /* "View.MemoryView":1369 - * - * if dtype_is_object: - * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<< - * dst.strides, ndim, inc) - * - */ - __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc); +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObject *__pyx_v_self) { + npy_intp *__pyx_r; - /* "View.MemoryView":1368 + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":268 + * Can return NULL for 0-dimensional arrays. + * """ + * return PyArray_DIMS(self) # <<<<<<<<<<<<<< * - * - * if dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice_with_gil(dst.data, dst.shape, - * dst.strides, ndim, inc) + * @property */ - } + __pyx_r = PyArray_DIMS(__pyx_v_self); + goto __pyx_L0; - /* "View.MemoryView":1364 - * - * @cname('__pyx_memoryview_refcount_copying') - * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<< - * int ndim, bint inc) nogil: + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":263 * + * @property + * cdef inline npy_intp *shape(self) nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the dimensions/shape of the array. + * The number of elements matches the number of dimensions of the array (ndim). */ /* function exit code */ + __pyx_L0:; + return __pyx_r; } -/* "View.MemoryView":1373 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":271 * - * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') - * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * bint inc) with gil: + * @property + * cdef inline npy_intp *strides(self) nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the strides of the array. + * The number of elements matches the number of dimensions of the array (ndim). */ -static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) { - __Pyx_RefNannyDeclarations - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0); +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayObject *__pyx_v_self) { + npy_intp *__pyx_r; - /* "View.MemoryView":1376 - * Py_ssize_t *strides, int ndim, - * bint inc) with gil: - * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<< + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":275 + * The number of elements matches the number of dimensions of the array (ndim). + * """ + * return PyArray_STRIDES(self) # <<<<<<<<<<<<<< * - * @cname('__pyx_memoryview_refcount_objects_in_slice') + * @property */ - __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc); + __pyx_r = PyArray_STRIDES(__pyx_v_self); + goto __pyx_L0; - /* "View.MemoryView":1373 + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":271 * - * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') - * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * bint inc) with gil: + * @property + * cdef inline npy_intp *strides(self) nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the strides of the array. + * The number of elements matches the number of dimensions of the array (ndim). */ /* function exit code */ - __Pyx_RefNannyFinishContext(); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif + __pyx_L0:; + return __pyx_r; } -/* "View.MemoryView":1379 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":278 * - * @cname('__pyx_memoryview_refcount_objects_in_slice') - * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, bint inc): - * cdef Py_ssize_t i + * @property + * cdef inline npy_intp size(self) nogil: # <<<<<<<<<<<<<< + * """Returns the total size (in number of elements) of the array. + * """ */ -static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) { - CYTHON_UNUSED Py_ssize_t __pyx_v_i; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - Py_ssize_t __pyx_t_2; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0); +static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject *__pyx_v_self) { + npy_intp __pyx_r; - /* "View.MemoryView":1383 - * cdef Py_ssize_t i + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":281 + * """Returns the total size (in number of elements) of the array. + * """ + * return PyArray_SIZE(self) # <<<<<<<<<<<<<< * - * for i in range(shape[0]): # <<<<<<<<<<<<<< - * if ndim == 1: - * if inc: + * @property */ - __pyx_t_1 = (__pyx_v_shape[0]); - __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; + __pyx_r = PyArray_SIZE(__pyx_v_self); + goto __pyx_L0; - /* "View.MemoryView":1384 + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":278 * - * for i in range(shape[0]): - * if ndim == 1: # <<<<<<<<<<<<<< - * if inc: - * Py_INCREF(( data)[0]) + * @property + * cdef inline npy_intp size(self) nogil: # <<<<<<<<<<<<<< + * """Returns the total size (in number of elements) of the array. + * """ */ - __pyx_t_4 = ((__pyx_v_ndim == 1) != 0); - if (__pyx_t_4) { - - /* "View.MemoryView":1385 - * for i in range(shape[0]): - * if ndim == 1: - * if inc: # <<<<<<<<<<<<<< - * Py_INCREF(( data)[0]) - * else: - */ - __pyx_t_4 = (__pyx_v_inc != 0); - if (__pyx_t_4) { - /* "View.MemoryView":1386 - * if ndim == 1: - * if inc: - * Py_INCREF(( data)[0]) # <<<<<<<<<<<<<< - * else: - * Py_DECREF(( data)[0]) - */ - Py_INCREF((((PyObject **)__pyx_v_data)[0])); + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} - /* "View.MemoryView":1385 - * for i in range(shape[0]): - * if ndim == 1: - * if inc: # <<<<<<<<<<<<<< - * Py_INCREF(( data)[0]) - * else: +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":284 + * + * @property + * cdef inline char* data(self) nogil: # <<<<<<<<<<<<<< + * """The pointer to the data buffer as a char*. + * This is provided for legacy reasons to avoid direct struct field access. */ - goto __pyx_L6; - } - /* "View.MemoryView":1388 - * Py_INCREF(( data)[0]) - * else: - * Py_DECREF(( data)[0]) # <<<<<<<<<<<<<< - * else: - * refcount_objects_in_slice(data, shape + 1, strides + 1, - */ - /*else*/ { - Py_DECREF((((PyObject **)__pyx_v_data)[0])); - } - __pyx_L6:; +static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__pyx_v_self) { + char *__pyx_r; - /* "View.MemoryView":1384 + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":290 + * of `PyArray_DATA()` instead, which returns a 'void*'. + * """ + * return PyArray_BYTES(self) # <<<<<<<<<<<<<< * - * for i in range(shape[0]): - * if ndim == 1: # <<<<<<<<<<<<<< - * if inc: - * Py_INCREF(( data)[0]) + * ctypedef unsigned char npy_bool */ - goto __pyx_L5; - } + __pyx_r = PyArray_BYTES(__pyx_v_self); + goto __pyx_L0; - /* "View.MemoryView":1390 - * Py_DECREF(( data)[0]) - * else: - * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<< - * ndim - 1, inc) + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":284 * + * @property + * cdef inline char* data(self) nogil: # <<<<<<<<<<<<<< + * """The pointer to the data buffer as a char*. + * This is provided for legacy reasons to avoid direct struct field access. */ - /*else*/ { - /* "View.MemoryView":1391 - * else: - * refcount_objects_in_slice(data, shape + 1, strides + 1, - * ndim - 1, inc) # <<<<<<<<<<<<<< + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":773 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) * - * data += strides[0] */ - __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc); - } - __pyx_L5:; - /* "View.MemoryView":1393 - * ndim - 1, inc) - * - * data += strides[0] # <<<<<<<<<<<<<< +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 1); + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":774 * + * cdef inline object PyArray_MultiIterNew1(a): + * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< * + * cdef inline object PyArray_MultiIterNew2(a, b): */ - __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0])); - } + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 774, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; - /* "View.MemoryView":1379 + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":773 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) * - * @cname('__pyx_memoryview_refcount_objects_in_slice') - * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, bint inc): - * cdef Py_ssize_t i */ /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); + return __pyx_r; } -/* "View.MemoryView":1399 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":776 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) * - * @cname('__pyx_memoryview_slice_assign_scalar') - * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<< - * size_t itemsize, void *item, - * bint dtype_is_object) nogil: - */ - -static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) { - - /* "View.MemoryView":1402 - * size_t itemsize, void *item, - * bint dtype_is_object) nogil: - * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<< - * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, - * itemsize, item) */ - __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0); - /* "View.MemoryView":1403 - * bint dtype_is_object) nogil: - * refcount_copying(dst, dtype_is_object, ndim, False) - * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<< - * itemsize, item) - * refcount_copying(dst, dtype_is_object, ndim, True) - */ - __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item); +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 1); - /* "View.MemoryView":1405 - * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, - * itemsize, item) - * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<< + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":777 * + * cdef inline object PyArray_MultiIterNew2(a, b): + * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< * + * cdef inline object PyArray_MultiIterNew3(a, b, c): */ - __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 777, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; - /* "View.MemoryView":1399 + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":776 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) * - * @cname('__pyx_memoryview_slice_assign_scalar') - * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<< - * size_t itemsize, void *item, - * bint dtype_is_object) nogil: */ /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; } -/* "View.MemoryView":1409 +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":779 + * return PyArray_MultiIterNew(2, a, b) * - * @cname('__pyx_memoryview__slice_assign_scalar') - * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * size_t itemsize, void *item) nogil: - */ + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ -static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) { - CYTHON_UNUSED Py_ssize_t __pyx_v_i; - Py_ssize_t __pyx_v_stride; - Py_ssize_t __pyx_v_extent; - int __pyx_t_1; - Py_ssize_t __pyx_t_2; - Py_ssize_t __pyx_t_3; - Py_ssize_t __pyx_t_4; +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 1); - /* "View.MemoryView":1413 - * size_t itemsize, void *item) nogil: - * cdef Py_ssize_t i - * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t extent = shape[0] + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":780 + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): */ - __pyx_v_stride = (__pyx_v_strides[0]); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 780, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; - /* "View.MemoryView":1414 - * cdef Py_ssize_t i - * cdef Py_ssize_t stride = strides[0] - * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<< + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":779 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) * - * if ndim == 1: */ - __pyx_v_extent = (__pyx_v_shape[0]); - /* "View.MemoryView":1416 - * cdef Py_ssize_t extent = shape[0] + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":782 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) * - * if ndim == 1: # <<<<<<<<<<<<<< - * for i in range(extent): - * memcpy(data, item, itemsize) */ - __pyx_t_1 = ((__pyx_v_ndim == 1) != 0); - if (__pyx_t_1) { - /* "View.MemoryView":1417 +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 1); + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":783 * - * if ndim == 1: - * for i in range(extent): # <<<<<<<<<<<<<< - * memcpy(data, item, itemsize) - * data += stride + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): */ - __pyx_t_2 = __pyx_v_extent; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 783, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; - /* "View.MemoryView":1418 - * if ndim == 1: - * for i in range(extent): - * memcpy(data, item, itemsize) # <<<<<<<<<<<<<< - * data += stride - * else: + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":782 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * */ - (void)(memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize)); - /* "View.MemoryView":1419 - * for i in range(extent): - * memcpy(data, item, itemsize) - * data += stride # <<<<<<<<<<<<<< - * else: - * for i in range(extent): + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":785 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * */ - __pyx_v_data = (__pyx_v_data + __pyx_v_stride); - } - /* "View.MemoryView":1416 - * cdef Py_ssize_t extent = shape[0] +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 1); + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":786 * - * if ndim == 1: # <<<<<<<<<<<<<< - * for i in range(extent): - * memcpy(data, item, itemsize) + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< + * + * cdef inline tuple PyDataType_SHAPE(dtype d): */ - goto __pyx_L3; - } + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 786, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; - /* "View.MemoryView":1421 - * data += stride + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":785 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":788 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__pyx_v_d) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("PyDataType_SHAPE", 1); + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":789 + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< + * return d.subarray.shape * else: - * for i in range(extent): # <<<<<<<<<<<<<< - * _slice_assign_scalar(data, shape + 1, strides + 1, - * ndim - 1, itemsize, item) */ - /*else*/ { - __pyx_t_2 = __pyx_v_extent; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; + __pyx_t_1 = PyDataType_HASSUBARRAY(__pyx_v_d); + if (__pyx_t_1) { - /* "View.MemoryView":1422 + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":790 + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape # <<<<<<<<<<<<<< * else: - * for i in range(extent): - * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<< - * ndim - 1, itemsize, item) - * data += stride + * return () */ - __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject*)__pyx_v_d->subarray->shape)); + __pyx_r = ((PyObject*)__pyx_v_d->subarray->shape); + goto __pyx_L0; - /* "View.MemoryView":1424 - * _slice_assign_scalar(data, shape + 1, strides + 1, - * ndim - 1, itemsize, item) - * data += stride # <<<<<<<<<<<<<< + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":789 + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< + * return d.subarray.shape + * else: + */ + } + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":792 + * return d.subarray.shape + * else: + * return () # <<<<<<<<<<<<<< * * */ - __pyx_v_data = (__pyx_v_data + __pyx_v_stride); - } + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_empty_tuple); + __pyx_r = __pyx_empty_tuple; + goto __pyx_L0; } - __pyx_L3:; - /* "View.MemoryView":1409 + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":788 + * return PyArray_MultiIterNew(5, a, b, c, d, e) * - * @cname('__pyx_memoryview__slice_assign_scalar') - * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * size_t itemsize, void *item) nogil: + * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape */ /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; } -/* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":968 + * int _import_umath() except -1 + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * Py_INCREF(base) # important to do this before stealing the reference below! + * PyArray_SetBaseObject(arr, base) */ -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_15View_dot_MemoryView_1__pyx_unpickle_Enum = {"__pyx_unpickle_Enum", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum, METH_VARARGS|METH_KEYWORDS, 0}; -static PyObject *__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v___pyx_type = 0; - long __pyx_v___pyx_checksum; - PyObject *__pyx_v___pyx_state = 0; +static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { + int __pyx_t_1; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__pyx_unpickle_Enum (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; - PyObject* values[3] = {0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_type)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_checksum)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, 1); __PYX_ERR(2, 1, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_state)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, 2); __PYX_ERR(2, 1, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_unpickle_Enum") < 0)) __PYX_ERR(2, 1, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - } - __pyx_v___pyx_type = values[0]; - __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(2, 1, __pyx_L3_error) - __pyx_v___pyx_state = values[2]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 1, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("View.MemoryView.__pyx_unpickle_Enum", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_15View_dot_MemoryView___pyx_unpickle_Enum(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView___pyx_unpickle_Enum(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = 0; - PyObject *__pyx_v___pyx_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_Enum", 0); - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum not in (0xb068931, 0x82a3537, 0x6ae9995): # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (0x%x vs (0xb068931, 0x82a3537, 0x6ae9995) = (name))" % __pyx_checksum) + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":969 + * + * cdef inline void set_array_base(ndarray arr, object base): + * Py_INCREF(base) # important to do this before stealing the reference below! # <<<<<<<<<<<<<< + * PyArray_SetBaseObject(arr, base) + * */ - __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_t_1, __pyx_tuple__21, Py_NE)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_3 = (__pyx_t_2 != 0); - if (__pyx_t_3) { + Py_INCREF(__pyx_v_base); - /* "(tree fragment)":5 - * cdef object __pyx_result - * if __pyx_checksum not in (0xb068931, 0x82a3537, 0x6ae9995): - * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< - * raise __pyx_PickleError("Incompatible checksums (0x%x vs (0xb068931, 0x82a3537, 0x6ae9995) = (name))" % __pyx_checksum) - * __pyx_result = Enum.__new__(__pyx_type) + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":970 + * cdef inline void set_array_base(ndarray arr, object base): + * Py_INCREF(base) # important to do this before stealing the reference below! + * PyArray_SetBaseObject(arr, base) # <<<<<<<<<<<<<< + * + * cdef inline object get_array_base(ndarray arr): */ - __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_s_PickleError); - __Pyx_GIVEREF(__pyx_n_s_PickleError); - PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_PickleError); - __pyx_t_4 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_1, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_4, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_t_1); - __pyx_v___pyx_PickleError = __pyx_t_1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_1 = PyArray_SetBaseObject(__pyx_v_arr, __pyx_v_base); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(2, 970, __pyx_L1_error) - /* "(tree fragment)":6 - * if __pyx_checksum not in (0xb068931, 0x82a3537, 0x6ae9995): - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (0x%x vs (0xb068931, 0x82a3537, 0x6ae9995) = (name))" % __pyx_checksum) # <<<<<<<<<<<<<< - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":968 + * int _import_umath() except -1 + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * Py_INCREF(base) # important to do this before stealing the reference below! + * PyArray_SetBaseObject(arr, base) */ - __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_0x_x_vs_0, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_INCREF(__pyx_v___pyx_PickleError); - __pyx_t_1 = __pyx_v___pyx_PickleError; __pyx_t_6 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_1); - if (likely(__pyx_t_6)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); - __Pyx_INCREF(__pyx_t_6); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_1, function); - } - } - __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_Raise(__pyx_t_4, 0, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(2, 6, __pyx_L1_error) - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum not in (0xb068931, 0x82a3537, 0x6ae9995): # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (0x%x vs (0xb068931, 0x82a3537, 0x6ae9995) = (name))" % __pyx_checksum) + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_AddTraceback("numpy.set_array_base", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; +} + +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":972 + * PyArray_SetBaseObject(arr, base) + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * base = PyArray_BASE(arr) + * if base is NULL: */ - } - /* "(tree fragment)":7 - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (0x%x vs (0xb068931, 0x82a3537, 0x6ae9995) = (name))" % __pyx_checksum) - * __pyx_result = Enum.__new__(__pyx_type) # <<<<<<<<<<<<<< - * if __pyx_state is not None: - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) +static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { + PyObject *__pyx_v_base; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("get_array_base", 1); + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":973 + * + * cdef inline object get_array_base(ndarray arr): + * base = PyArray_BASE(arr) # <<<<<<<<<<<<<< + * if base is NULL: + * return None */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_MemviewEnum_type), __pyx_n_s_new); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_1, function); - } - } - __pyx_t_4 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_5, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v___pyx_type); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v___pyx_result = __pyx_t_4; - __pyx_t_4 = 0; + __pyx_v_base = PyArray_BASE(__pyx_v_arr); - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (0x%x vs (0xb068931, 0x82a3537, 0x6ae9995) = (name))" % __pyx_checksum) - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":974 + * cdef inline object get_array_base(ndarray arr): + * base = PyArray_BASE(arr) + * if base is NULL: # <<<<<<<<<<<<<< + * return None + * return base */ - __pyx_t_3 = (__pyx_v___pyx_state != Py_None); - __pyx_t_2 = (__pyx_t_3 != 0); - if (__pyx_t_2) { + __pyx_t_1 = (__pyx_v_base == NULL); + if (__pyx_t_1) { - /* "(tree fragment)":9 - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":975 + * base = PyArray_BASE(arr) + * if base is NULL: + * return None # <<<<<<<<<<<<<< + * return base + * */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||((void)PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(2, 9, __pyx_L1_error) - __pyx_t_4 = __pyx_unpickle_Enum__set_state(((struct __pyx_MemviewEnum_obj *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (0x%x vs (0xb068931, 0x82a3537, 0x6ae9995) = (name))" % __pyx_checksum) - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":974 + * cdef inline object get_array_base(ndarray arr): + * base = PyArray_BASE(arr) + * if base is NULL: # <<<<<<<<<<<<<< + * return None + * return base */ } - /* "(tree fragment)":10 - * if __pyx_state is not None: - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result # <<<<<<<<<<<<<< - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":976 + * if base is NULL: + * return None + * return base # <<<<<<<<<<<<<< + * + * # Versions of the import_* functions which are more suitable for */ __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v___pyx_result); - __pyx_r = __pyx_v___pyx_result; + __Pyx_INCREF(((PyObject *)__pyx_v_base)); + __pyx_r = ((PyObject *)__pyx_v_base); goto __pyx_L0; - /* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":972 + * PyArray_SetBaseObject(arr, base) + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * base = PyArray_BASE(arr) + * if base is NULL: */ /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("View.MemoryView.__pyx_unpickle_Enum", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; __pyx_L0:; - __Pyx_XDECREF(__pyx_v___pyx_PickleError); - __Pyx_XDECREF(__pyx_v___pyx_result); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "(tree fragment)":11 - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":980 + * # Versions of the import_* functions which are more suitable for + * # Cython code. + * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< + * try: + * __pyx_import_array() */ -static PyObject *__pyx_unpickle_Enum__set_state(struct __pyx_MemviewEnum_obj *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; +static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { + int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - Py_ssize_t __pyx_t_3; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; int __pyx_t_4; - int __pyx_t_5; + PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; PyObject *__pyx_t_8 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_Enum__set_state", 0); + __Pyx_RefNannySetupContext("import_array", 1); - /* "(tree fragment)":12 - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] # <<<<<<<<<<<<<< - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[1]) + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":981 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * __pyx_import_array() + * except Exception: */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(2, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->name); - __Pyx_DECREF(__pyx_v___pyx_result->name); - __pyx_v___pyx_result->name = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[1]) + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":982 + * cdef inline int import_array() except -1: + * try: + * __pyx_import_array() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(2, 13, __pyx_L1_error) - } - __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(2, 13, __pyx_L1_error) - __pyx_t_4 = ((__pyx_t_3 > 1) != 0); - if (__pyx_t_4) { - } else { - __pyx_t_2 = __pyx_t_4; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 13, __pyx_L1_error) - __pyx_t_5 = (__pyx_t_4 != 0); - __pyx_t_2 = __pyx_t_5; - __pyx_L4_bool_binop_done:; - if (__pyx_t_2) { + __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 982, __pyx_L3_error) - /* "(tree fragment)":14 - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[1]) # <<<<<<<<<<<<<< + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":981 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * __pyx_import_array() + * except Exception: */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(2, 14, __pyx_L1_error) } - __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_8 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_8)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_8); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":983 + * try: + * __pyx_import_array() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.multiarray failed to import") + * + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 983, __pyx_L5_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":984 + * __pyx_import_array() + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_umath() except -1: + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 984, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(2, 984, __pyx_L5_except_error) } - __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L5_except_error; - /* "(tree fragment)":13 - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[1]) + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":981 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * __pyx_import_array() + * except Exception: */ + __pyx_L5_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; } - /* "(tree fragment)":11 - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":980 + * # Versions of the import_* functions which are more suitable for + * # Cython code. + * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< + * try: + * __pyx_import_array() */ /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); + __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("View.MemoryView.__pyx_unpickle_Enum__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; + __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } -static struct __pyx_vtabstruct_array __pyx_vtable_array; -static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_array_obj *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_array_obj *)o); - p->__pyx_vtab = __pyx_vtabptr_array; - p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None); - if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":986 + * raise ImportError("numpy.core.multiarray failed to import") + * + * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ -static void __pyx_tp_dealloc_array(PyObject *o) { - struct __pyx_array_obj *p = (struct __pyx_array_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif +static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("import_umath", 1); + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":987 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_array___dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - Py_CLEAR(p->mode); - Py_CLEAR(p->_format); - (*Py_TYPE(o)->tp_free)(o); -} -static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) { - PyObject *r; - PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; - r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); - Py_DECREF(x); - return r; -} + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { -static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) { - if (v) { - return __pyx_array___setitem__(o, i, v); - } - else { - PyErr_Format(PyExc_NotImplementedError, - "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name); - return -1; - } -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":988 + * cdef inline int import_umath() except -1: + * try: + * _import_umath() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.umath failed to import") + */ + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 988, __pyx_L3_error) -static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) { - PyObject *v = __Pyx_PyObject_GenericGetAttr(o, n); - if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - v = __pyx_array___getattr__(o, n); - } - return v; -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":987 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; -static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(o); -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":989 + * try: + * _import_umath() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.umath failed to import") + * + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 989, __pyx_L5_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); -static PyMethodDef __pyx_methods_array[] = { - {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0}, - {"__reduce_cython__", (PyCFunction)__pyx_pw___pyx_array_1__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw___pyx_array_3__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":990 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_ufunc() except -1: + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 990, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(2, 990, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; -static struct PyGetSetDef __pyx_getsets_array[] = { - {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":987 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + __pyx_L5_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } -static PySequenceMethods __pyx_tp_as_sequence_array = { - __pyx_array___len__, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - __pyx_sq_item_array, /*sq_item*/ - 0, /*sq_slice*/ - 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - 0, /*sq_contains*/ - 0, /*sq_inplace_concat*/ - 0, /*sq_inplace_repeat*/ -}; + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":986 + * raise ImportError("numpy.core.multiarray failed to import") + * + * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ -static PyMappingMethods __pyx_tp_as_mapping_array = { - __pyx_array___len__, /*mp_length*/ - __pyx_array___getitem__, /*mp_subscript*/ - __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/ -}; + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} -static PyBufferProcs __pyx_tp_as_buffer_array = { - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getreadbuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getwritebuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getsegcount*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getcharbuffer*/ - #endif - __pyx_array_getbuffer, /*bf_getbuffer*/ - 0, /*bf_releasebuffer*/ -}; +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":992 + * raise ImportError("numpy.core.umath failed to import") + * + * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ -static PyTypeObject __pyx_type___pyx_array = { - PyVarObject_HEAD_INIT(0, 0) - "pygom.model._tau_leap.array", /*tp_name*/ - sizeof(struct __pyx_array_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_array, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - &__pyx_tp_as_sequence_array, /*tp_as_sequence*/ - &__pyx_tp_as_mapping_array, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - __pyx_tp_getattro_array, /*tp_getattro*/ - 0, /*tp_setattro*/ - &__pyx_tp_as_buffer_array, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_array, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_array, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_array, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 - 0, /*tp_pypy_flags*/ - #endif -}; +static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("import_ufunc", 1); -static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - struct __pyx_MemviewEnum_obj *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_MemviewEnum_obj *)o); - p->name = Py_None; Py_INCREF(Py_None); - return o; -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":993 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { -static void __pyx_tp_dealloc_Enum(PyObject *o) { - struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - Py_CLEAR(p->name); - (*Py_TYPE(o)->tp_free)(o); -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":994 + * cdef inline int import_ufunc() except -1: + * try: + * _import_umath() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.umath failed to import") + */ + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 994, __pyx_L3_error) -static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; - if (p->name) { - e = (*v)(p->name, a); if (e) return e; - } - return 0; -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":993 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; -static int __pyx_tp_clear_Enum(PyObject *o) { - PyObject* tmp; - struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; - tmp = ((PyObject*)p->name); - p->name = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":995 + * try: + * _import_umath() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.umath failed to import") + * + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 995, __pyx_L5_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); -static PyMethodDef __pyx_methods_Enum[] = { - {"__reduce_cython__", (PyCFunction)__pyx_pw___pyx_MemviewEnum_1__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw___pyx_MemviewEnum_3__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":996 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 996, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(2, 996, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; -static PyTypeObject __pyx_type___pyx_MemviewEnum = { - PyVarObject_HEAD_INIT(0, 0) - "pygom.model._tau_leap.Enum", /*tp_name*/ - sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_Enum, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - __pyx_MemviewEnum___repr__, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_Enum, /*tp_traverse*/ - __pyx_tp_clear_Enum, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_Enum, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - __pyx_MemviewEnum___init__, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_Enum, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 - 0, /*tp_pypy_flags*/ - #endif -}; -static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview; - -static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_memoryview_obj *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_memoryview_obj *)o); - p->__pyx_vtab = __pyx_vtabptr_memoryview; - p->obj = Py_None; Py_INCREF(Py_None); - p->_size = Py_None; Py_INCREF(Py_None); - p->_array_interface = Py_None; Py_INCREF(Py_None); - p->view.obj = NULL; - if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_memoryview(PyObject *o) { - struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_memoryview___dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":993 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + __pyx_L5_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; } - Py_CLEAR(p->obj); - Py_CLEAR(p->_size); - Py_CLEAR(p->_array_interface); - (*Py_TYPE(o)->tp_free)(o); -} -static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; - if (p->obj) { - e = (*v)(p->obj, a); if (e) return e; - } - if (p->_size) { - e = (*v)(p->_size, a); if (e) return e; - } - if (p->_array_interface) { - e = (*v)(p->_array_interface, a); if (e) return e; - } - if (p->view.obj) { - e = (*v)(p->view.obj, a); if (e) return e; - } - return 0; -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":992 + * raise ImportError("numpy.core.umath failed to import") + * + * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ -static int __pyx_tp_clear_memoryview(PyObject *o) { - PyObject* tmp; - struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; - tmp = ((PyObject*)p->obj); - p->obj = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_size); - p->_size = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_array_interface); - p->_array_interface = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - Py_CLEAR(p->view.obj); - return 0; -} -static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) { - PyObject *r; - PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; - r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); - Py_DECREF(x); - return r; + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; } -static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) { - if (v) { - return __pyx_memoryview___setitem__(o, i, v); - } - else { - PyErr_Format(PyExc_NotImplementedError, - "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name); - return -1; - } -} +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":999 + * + * + * cdef inline bint is_timedelta64_object(object obj): # <<<<<<<<<<<<<< + * """ + * Cython equivalent of `isinstance(obj, np.timedelta64)` + */ -static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(o); -} +static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_obj) { + int __pyx_r; -static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(o); -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1011 + * bool + * """ + * return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type) # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyTimedeltaArrType_Type)); + goto __pyx_L0; -static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(o); -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":999 + * + * + * cdef inline bint is_timedelta64_object(object obj): # <<<<<<<<<<<<<< + * """ + * Cython equivalent of `isinstance(obj, np.timedelta64)` + */ -static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(o); + /* function exit code */ + __pyx_L0:; + return __pyx_r; } -static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(o); -} +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1014 + * + * + * cdef inline bint is_datetime64_object(object obj): # <<<<<<<<<<<<<< + * """ + * Cython equivalent of `isinstance(obj, np.datetime64)` + */ -static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(o); -} +static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_obj) { + int __pyx_r; -static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(o); -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1026 + * bool + * """ + * return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type) # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyDatetimeArrType_Type)); + goto __pyx_L0; -static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(o); -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1014 + * + * + * cdef inline bint is_datetime64_object(object obj): # <<<<<<<<<<<<<< + * """ + * Cython equivalent of `isinstance(obj, np.datetime64)` + */ -static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(o); + /* function exit code */ + __pyx_L0:; + return __pyx_r; } -static PyMethodDef __pyx_methods_memoryview[] = { - {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0}, - {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0}, - {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0}, - {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0}, - {"__reduce_cython__", (PyCFunction)__pyx_pw___pyx_memoryview_1__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw___pyx_memoryview_3__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1029 + * + * + * cdef inline npy_datetime get_datetime64_value(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the int64 value underlying scalar numpy datetime64 object + */ -static struct PyGetSetDef __pyx_getsets_memoryview[] = { - {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, (char *)0, 0}, - {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, (char *)0, 0}, - {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, (char *)0, 0}, - {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, (char *)0, 0}, - {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, (char *)0, 0}, - {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, (char *)0, 0}, - {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, (char *)0, 0}, - {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, (char *)0, 0}, - {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; +static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject *__pyx_v_obj) { + npy_datetime __pyx_r; -static PySequenceMethods __pyx_tp_as_sequence_memoryview = { - __pyx_memoryview___len__, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - __pyx_sq_item_memoryview, /*sq_item*/ - 0, /*sq_slice*/ - 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - 0, /*sq_contains*/ - 0, /*sq_inplace_concat*/ - 0, /*sq_inplace_repeat*/ -}; + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1036 + * also needed. That can be found using `get_datetime64_unit`. + * """ + * return (obj).obval # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = ((PyDatetimeScalarObject *)__pyx_v_obj)->obval; + goto __pyx_L0; -static PyMappingMethods __pyx_tp_as_mapping_memoryview = { - __pyx_memoryview___len__, /*mp_length*/ - __pyx_memoryview___getitem__, /*mp_subscript*/ - __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/ -}; + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1029 + * + * + * cdef inline npy_datetime get_datetime64_value(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the int64 value underlying scalar numpy datetime64 object + */ -static PyBufferProcs __pyx_tp_as_buffer_memoryview = { - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getreadbuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getwritebuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getsegcount*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getcharbuffer*/ - #endif - __pyx_memoryview_getbuffer, /*bf_getbuffer*/ - 0, /*bf_releasebuffer*/ -}; + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} -static PyTypeObject __pyx_type___pyx_memoryview = { - PyVarObject_HEAD_INIT(0, 0) - "pygom.model._tau_leap.memoryview", /*tp_name*/ - sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_memoryview, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - __pyx_memoryview___repr__, /*tp_repr*/ - 0, /*tp_as_number*/ - &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/ - &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - __pyx_memoryview___str__, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_memoryview, /*tp_traverse*/ - __pyx_tp_clear_memoryview, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_memoryview, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_memoryview, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_memoryview, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 - 0, /*tp_pypy_flags*/ - #endif -}; -static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice; +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1039 + * + * + * cdef inline npy_timedelta get_timedelta64_value(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the int64 value underlying scalar numpy timedelta64 object + */ -static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_memoryviewslice_obj *p; - PyObject *o = __pyx_tp_new_memoryview(t, a, k); - if (unlikely(!o)) return 0; - p = ((struct __pyx_memoryviewslice_obj *)o); - p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice; - p->from_object = Py_None; Py_INCREF(Py_None); - p->from_slice.memview = NULL; - return o; -} +static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject *__pyx_v_obj) { + npy_timedelta __pyx_r; -static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) { - struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_memoryviewslice___dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - Py_CLEAR(p->from_object); - PyObject_GC_Track(o); - __pyx_tp_dealloc_memoryview(o); -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1043 + * returns the int64 value underlying scalar numpy timedelta64 object + * """ + * return (obj).obval # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = ((PyTimedeltaScalarObject *)__pyx_v_obj)->obval; + goto __pyx_L0; -static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; - e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e; - if (p->from_object) { - e = (*v)(p->from_object, a); if (e) return e; - } - return 0; -} + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1039 + * + * + * cdef inline npy_timedelta get_timedelta64_value(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the int64 value underlying scalar numpy timedelta64 object + */ -static int __pyx_tp_clear__memoryviewslice(PyObject *o) { - PyObject* tmp; - struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; - __pyx_tp_clear_memoryview(o); - tmp = ((PyObject*)p->from_object); - p->from_object = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - __PYX_XDEC_MEMVIEW(&p->from_slice, 1); - return 0; + /* function exit code */ + __pyx_L0:; + return __pyx_r; } -static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_16_memoryviewslice_4base_1__get__(o); -} +/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1046 + * + * + * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the unit part of the dtype for a numpy datetime64 object. + */ -static PyMethodDef __pyx_methods__memoryviewslice[] = { - {"__reduce_cython__", (PyCFunction)__pyx_pw___pyx_memoryviewslice_1__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw___pyx_memoryviewslice_3__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; +static CYTHON_INLINE NPY_DATETIMEUNIT __pyx_f_5numpy_get_datetime64_unit(PyObject *__pyx_v_obj) { + NPY_DATETIMEUNIT __pyx_r; -static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = { - {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1050 + * returns the unit part of the dtype for a numpy datetime64 object. + * """ + * return (obj).obmeta.base # <<<<<<<<<<<<<< + */ + __pyx_r = ((NPY_DATETIMEUNIT)((PyDatetimeScalarObject *)__pyx_v_obj)->obmeta.base); + goto __pyx_L0; -static PyTypeObject __pyx_type___pyx_memoryviewslice = { - PyVarObject_HEAD_INIT(0, 0) - "pygom.model._tau_leap._memoryviewslice", /*tp_name*/ - sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - #if CYTHON_COMPILING_IN_PYPY - __pyx_memoryview___repr__, /*tp_repr*/ - #else - 0, /*tp_repr*/ - #endif - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - #if CYTHON_COMPILING_IN_PYPY - __pyx_memoryview___str__, /*tp_str*/ - #else - 0, /*tp_str*/ - #endif - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - "Internal class for passing memoryview slices to Python", /*tp_doc*/ - __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/ - __pyx_tp_clear__memoryviewslice, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods__memoryviewslice, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets__memoryviewslice, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new__memoryviewslice, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 - 0, /*tp_pypy_flags*/ - #endif -}; + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1046 + * + * + * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil: # <<<<<<<<<<<<<< + * """ + * returns the unit part of the dtype for a numpy datetime64 object. + */ -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec__tau_leap(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec__tau_leap}, - {0, NULL} -}; -#endif +/* "pygom/model/_tau_leap.pyx":8 + * cimport cython + * + * @cython.boundscheck(False) # Deactivate bounds checking # <<<<<<<<<<<<<< + * @cython.wraparound(False) # Deactivate negative indexing. + * @cython.cdivision(True) # Deactivate the div 0 error checking + */ -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "_tau_leap", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ +/* Python wrapper */ +static PyObject *__pyx_pw_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety(PyObject *__pyx_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_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety, "\n Additional safety test on :math:`\\tau`-leap, decrease the step size if\n the original is not small enough. Decrease a couple of times and then\n bail out because we don't want to spend too long decreasing the\n step size until we find a suitable one.\n "); +static PyMethodDef __pyx_mdef_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety = {"_cy_test_tau_leap_safety", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety}; +static PyObject *__pyx_pw_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety(PyObject *__pyx_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 +) { + PyArrayObject *__pyx_v_x = 0; + PyArrayObject *__pyx_v_reactant_mat = 0; + PyArrayObject *__pyx_v_rates = 0; + double __pyx_v_tau_scale; + double __pyx_v_epsilon; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_cy_test_tau_leap_safety (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); #else - NULL, /* m_reload */ + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_reactant_mat,&__pyx_n_s_rates,&__pyx_n_s_tau_scale,&__pyx_n_s_epsilon,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + 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, 8, __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_reactant_mat)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 8, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 1); __PYX_ERR(0, 8, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_rates)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 8, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 2); __PYX_ERR(0, 8, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tau_scale)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 8, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 3); __PYX_ERR(0, 8, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_epsilon)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 8, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 4); __PYX_ERR(0, 8, __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, "_cy_test_tau_leap_safety") < 0)) __PYX_ERR(0, 8, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + } + __pyx_v_x = ((PyArrayObject *)values[0]); + __pyx_v_reactant_mat = ((PyArrayObject *)values[1]); + __pyx_v_rates = ((PyArrayObject *)values[2]); + __pyx_v_tau_scale = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_tau_scale == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error) + __pyx_v_epsilon = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_epsilon == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 15, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 8, __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("pygom.model._tau_leap._cy_test_tau_leap_safety", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_x), __pyx_ptype_5numpy_ndarray, 1, "x", 0))) __PYX_ERR(0, 11, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_reactant_mat), __pyx_ptype_5numpy_ndarray, 1, "reactant_mat", 0))) __PYX_ERR(0, 12, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rates), __pyx_ptype_5numpy_ndarray, 1, "rates", 0))) __PYX_ERR(0, 13, __pyx_L1_error) + __pyx_r = __pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(__pyx_self, __pyx_v_x, __pyx_v_reactant_mat, __pyx_v_rates, __pyx_v_tau_scale, __pyx_v_epsilon); -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_n_s_ASCII, __pyx_k_ASCII, sizeof(__pyx_k_ASCII), 0, 0, 1, 1}, - {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0}, - {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0}, - {&__pyx_kp_s_Cannot_assign_to_read_only_memor, __pyx_k_Cannot_assign_to_read_only_memor, sizeof(__pyx_k_Cannot_assign_to_read_only_memor), 0, 0, 1, 0}, - {&__pyx_kp_s_Cannot_create_writable_memory_vi, __pyx_k_Cannot_create_writable_memory_vi, sizeof(__pyx_k_Cannot_create_writable_memory_vi), 0, 0, 1, 0}, - {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0}, - {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1}, - {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0}, - {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, - {&__pyx_kp_s_Incompatible_checksums_0x_x_vs_0, __pyx_k_Incompatible_checksums_0x_x_vs_0, sizeof(__pyx_k_Incompatible_checksums_0x_x_vs_0), 0, 0, 1, 0}, - {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1}, - {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0}, - {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0}, - {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0}, - {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1}, - {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0}, - {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0}, - {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1}, - {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0}, - {&__pyx_n_s_PickleError, __pyx_k_PickleError, sizeof(__pyx_k_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, - {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0}, - {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, - {&__pyx_n_s_View_MemoryView, __pyx_k_View_MemoryView, sizeof(__pyx_k_View_MemoryView), 0, 0, 1, 1}, - {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1}, - {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1}, - {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1}, - {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1}, - {&__pyx_n_s_cdf_val, __pyx_k_cdf_val, sizeof(__pyx_k_cdf_val), 0, 0, 1, 1}, - {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0}, - {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0}, - {&__pyx_n_s_count, __pyx_k_count, sizeof(__pyx_k_count), 0, 0, 1, 1}, - {&__pyx_n_s_cy_test_tau_leap_safety, __pyx_k_cy_test_tau_leap_safety, sizeof(__pyx_k_cy_test_tau_leap_safety), 0, 0, 1, 1}, - {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, - {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1}, - {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1}, - {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1}, - {&__pyx_n_s_epsilon, __pyx_k_epsilon, sizeof(__pyx_k_epsilon), 0, 0, 1, 1}, - {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1}, - {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1}, - {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, - {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1}, - {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1}, - {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, - {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0}, - {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, - {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1}, - {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0}, - {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_max_cdf, __pyx_k_max_cdf, sizeof(__pyx_k_max_cdf), 0, 0, 1, 1}, - {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1}, - {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1}, - {&__pyx_n_s_mu, __pyx_k_mu, sizeof(__pyx_k_mu), 0, 0, 1, 1}, - {&__pyx_n_s_n_rates, __pyx_k_n_rates, sizeof(__pyx_k_n_rates), 0, 0, 1, 1}, - {&__pyx_n_s_n_reactants, __pyx_k_n_reactants, sizeof(__pyx_k_n_reactants), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1}, - {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1}, - {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, - {&__pyx_n_s_new_cdf, __pyx_k_new_cdf, sizeof(__pyx_k_new_cdf), 0, 0, 1, 1}, - {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, - {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, - {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, - {&__pyx_kp_s_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 0, 1, 0}, - {&__pyx_kp_s_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 0, 1, 0}, - {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1}, - {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1}, - {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, - {&__pyx_n_s_pygom_model__tau_leap, __pyx_k_pygom_model__tau_leap, sizeof(__pyx_k_pygom_model__tau_leap), 0, 0, 1, 1}, - {&__pyx_kp_s_pygom_model__tau_leap_pyx, __pyx_k_pygom_model__tau_leap_pyx, sizeof(__pyx_k_pygom_model__tau_leap_pyx), 0, 0, 1, 0}, - {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_checksum, __pyx_k_pyx_checksum, sizeof(__pyx_k_pyx_checksum), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_result, __pyx_k_pyx_result, sizeof(__pyx_k_pyx_result), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_type, __pyx_k_pyx_type, sizeof(__pyx_k_pyx_type), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_unpickle_Enum, __pyx_k_pyx_unpickle_Enum, sizeof(__pyx_k_pyx_unpickle_Enum), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, - {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, - {&__pyx_n_s_rates, __pyx_k_rates, sizeof(__pyx_k_rates), 0, 0, 1, 1}, - {&__pyx_n_s_rates_view, __pyx_k_rates_view, sizeof(__pyx_k_rates_view), 0, 0, 1, 1}, - {&__pyx_n_s_reactant_mat, __pyx_k_reactant_mat, sizeof(__pyx_k_reactant_mat), 0, 0, 1, 1}, - {&__pyx_n_s_reactant_mat_view, __pyx_k_reactant_mat_view, sizeof(__pyx_k_reactant_mat_view), 0, 0, 1, 1}, - {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, - {&__pyx_n_s_safe, __pyx_k_safe, sizeof(__pyx_k_safe), 0, 0, 1, 1}, - {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, - {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, - {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1}, - {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1}, - {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1}, - {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1}, - {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1}, - {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0}, - {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0}, - {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0}, - {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, - {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1}, - {&__pyx_n_s_sum, __pyx_k_sum, sizeof(__pyx_k_sum), 0, 0, 1, 1}, - {&__pyx_n_s_tau_scale, __pyx_k_tau_scale, sizeof(__pyx_k_tau_scale), 0, 0, 1, 1}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_total_rate, __pyx_k_total_rate, sizeof(__pyx_k_total_rate), 0, 0, 1, 1}, - {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0}, - {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0}, - {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1}, - {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, - {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1}, - {&__pyx_n_s_x_view, __pyx_k_x_view, sizeof(__pyx_k_x_view), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 35, __pyx_L1_error) - __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(1, 944, __pyx_L1_error) - __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(2, 134, __pyx_L1_error) - __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(2, 149, __pyx_L1_error) - __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) __PYX_ERR(2, 152, __pyx_L1_error) - __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(2, 2, __pyx_L1_error) - __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) __PYX_ERR(2, 406, __pyx_L1_error) - __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(2, 615, __pyx_L1_error) - __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(2, 834, __pyx_L1_error) - return 0; + /* function exit code */ + goto __pyx_L0; __pyx_L1_error:; - return -1; + __pyx_r = NULL; + __pyx_L0:; + { + 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 CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { +static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_x, PyArrayObject *__pyx_v_reactant_mat, PyArrayObject *__pyx_v_rates, double __pyx_v_tau_scale, double __pyx_v_epsilon) { + __Pyx_memviewslice __pyx_v_rates_view = { 0, 0, { 0 }, { 0 }, { 0 } }; + __pyx_t_5numpy_int64_t __pyx_v_n_rates; + __Pyx_memviewslice __pyx_v_x_view = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_v_reactant_mat_view = { 0, 0, { 0 }, { 0 }, { 0 } }; + __pyx_t_5numpy_int64_t __pyx_v_n_reactants; + double __pyx_v_mu; + double __pyx_v_max_cdf; + double __pyx_v_new_cdf; + double __pyx_v_total_rate; + int __pyx_v_safe; + int __pyx_v_count; + double __pyx_v_cdf_val; + __pyx_t_5numpy_int64_t __pyx_v_i; + __pyx_t_5numpy_int64_t __pyx_v_j; + __Pyx_LocalBuf_ND __pyx_pybuffernd_rates; + __Pyx_Buffer __pyx_pybuffer_rates; + __Pyx_LocalBuf_ND __pyx_pybuffernd_reactant_mat; + __Pyx_Buffer __pyx_pybuffer_reactant_mat; + __Pyx_LocalBuf_ND __pyx_pybuffernd_x; + __Pyx_Buffer __pyx_pybuffer_x; + PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + __Pyx_memviewslice __pyx_t_1 = { 0, 0, { 0 }, { 0 }, { 0 } }; + npy_intp *__pyx_t_2; + __Pyx_memviewslice __pyx_t_3 = { 0, 0, { 0 }, { 0 }, { 0 } }; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + double __pyx_t_8; + int __pyx_t_9; + __pyx_t_5numpy_int64_t __pyx_t_10; + __pyx_t_5numpy_int64_t __pyx_t_11; + __pyx_t_5numpy_int64_t __pyx_t_12; + __pyx_t_5numpy_int64_t __pyx_t_13; + __pyx_t_5numpy_int64_t __pyx_t_14; + __pyx_t_5numpy_int64_t __pyx_t_15; + __pyx_t_5numpy_int64_t __pyx_t_16; + __pyx_t_5numpy_int64_t __pyx_t_17; + int __pyx_t_18; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_cy_test_tau_leap_safety", 1); + __pyx_pybuffer_x.pybuffer.buf = NULL; + __pyx_pybuffer_x.refcount = 0; + __pyx_pybuffernd_x.data = NULL; + __pyx_pybuffernd_x.rcbuffer = &__pyx_pybuffer_x; + __pyx_pybuffer_reactant_mat.pybuffer.buf = NULL; + __pyx_pybuffer_reactant_mat.refcount = 0; + __pyx_pybuffernd_reactant_mat.data = NULL; + __pyx_pybuffernd_reactant_mat.rcbuffer = &__pyx_pybuffer_reactant_mat; + __pyx_pybuffer_rates.pybuffer.buf = NULL; + __pyx_pybuffer_rates.refcount = 0; + __pyx_pybuffernd_rates.data = NULL; + __pyx_pybuffernd_rates.rcbuffer = &__pyx_pybuffer_rates; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x.rcbuffer->pybuffer, (PyObject*)__pyx_v_x, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 8, __pyx_L1_error) + } + __pyx_pybuffernd_x.diminfo[0].strides = __pyx_pybuffernd_x.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x.diminfo[0].shape = __pyx_pybuffernd_x.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer, (PyObject*)__pyx_v_reactant_mat, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 8, __pyx_L1_error) + } + __pyx_pybuffernd_reactant_mat.diminfo[0].strides = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_reactant_mat.diminfo[0].shape = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_reactant_mat.diminfo[1].strides = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_reactant_mat.diminfo[1].shape = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_rates.rcbuffer->pybuffer, (PyObject*)__pyx_v_rates, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 8, __pyx_L1_error) + } + __pyx_pybuffernd_rates.diminfo[0].strides = __pyx_pybuffernd_rates.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_rates.diminfo[0].shape = __pyx_pybuffernd_rates.rcbuffer->pybuffer.shape[0]; - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":944 - * __pyx_import_array() - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_umath() except -1: + /* "pygom/model/_tau_leap.pyx":23 + * """ + * #view on arrays + * cdef double[:] rates_view = rates # <<<<<<<<<<<<<< + * cdef np.int64_t n_rates = rates.shape[0] + * cdef double[:] x_view = x */ - __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_numpy_core_multiarray_failed_to); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 944, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple_); - __Pyx_GIVEREF(__pyx_tuple_); - - /* "../../anaconda3/envs/pygom_test_3.10/lib/python3.10/site-packages/numpy/__init__.pxd":950 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_ufunc() except -1: - */ - __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 950, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__2); - __Pyx_GIVEREF(__pyx_tuple__2); + __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_rates), PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 23, __pyx_L1_error) + __pyx_v_rates_view = __pyx_t_1; + __pyx_t_1.memview = NULL; + __pyx_t_1.data = NULL; - /* "View.MemoryView":134 - * - * if not self.ndim: - * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<< - * - * if itemsize <= 0: + /* "pygom/model/_tau_leap.pyx":24 + * #view on arrays + * cdef double[:] rates_view = rates + * cdef np.int64_t n_rates = rates.shape[0] # <<<<<<<<<<<<<< + * cdef double[:] x_view = x + * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat */ - __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(2, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__3); - __Pyx_GIVEREF(__pyx_tuple__3); + __pyx_t_2 = __pyx_f_5numpy_7ndarray_5shape_shape(((PyArrayObject *)__pyx_v_rates)); if (unlikely(__pyx_t_2 == ((npy_intp *)NULL) && PyErr_Occurred())) __PYX_ERR(0, 24, __pyx_L1_error) + __pyx_v_n_rates = (__pyx_t_2[0]); - /* "View.MemoryView":137 - * - * if itemsize <= 0: - * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<< - * - * if not isinstance(format, bytes): + /* "pygom/model/_tau_leap.pyx":25 + * cdef double[:] rates_view = rates + * cdef np.int64_t n_rates = rates.shape[0] + * cdef double[:] x_view = x # <<<<<<<<<<<<<< + * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat + * cdef np.int64_t n_reactants = reactant_mat.shape[0] */ - __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(2, 137, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__4); - __Pyx_GIVEREF(__pyx_tuple__4); + __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_x), PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 25, __pyx_L1_error) + __pyx_v_x_view = __pyx_t_1; + __pyx_t_1.memview = NULL; + __pyx_t_1.data = NULL; - /* "View.MemoryView":149 - * - * if not self._shape: - * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<< - * + /* "pygom/model/_tau_leap.pyx":26 + * cdef np.int64_t n_rates = rates.shape[0] + * cdef double[:] x_view = x + * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat # <<<<<<<<<<<<<< + * cdef np.int64_t n_reactants = reactant_mat.shape[0] * */ - __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(2, 149, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__5); - __Pyx_GIVEREF(__pyx_tuple__5); + __pyx_t_3 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int64_t(((PyObject *)__pyx_v_reactant_mat), PyBUF_WRITABLE); if (unlikely(!__pyx_t_3.memview)) __PYX_ERR(0, 26, __pyx_L1_error) + __pyx_v_reactant_mat_view = __pyx_t_3; + __pyx_t_3.memview = NULL; + __pyx_t_3.data = NULL; - /* "View.MemoryView":177 - * self.data = malloc(self.len) - * if not self.data: - * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<< + /* "pygom/model/_tau_leap.pyx":27 + * cdef double[:] x_view = x + * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat + * cdef np.int64_t n_reactants = reactant_mat.shape[0] # <<<<<<<<<<<<<< * - * if self.dtype_is_object: + * cdef double mu, max_cdf, new_cdf */ - __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(2, 177, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__6); - __Pyx_GIVEREF(__pyx_tuple__6); + __pyx_t_2 = __pyx_f_5numpy_7ndarray_5shape_shape(((PyArrayObject *)__pyx_v_reactant_mat)); if (unlikely(__pyx_t_2 == ((npy_intp *)NULL) && PyErr_Occurred())) __PYX_ERR(0, 27, __pyx_L1_error) + __pyx_v_n_reactants = (__pyx_t_2[0]); - /* "View.MemoryView":193 - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<< - * info.buf = self.data - * info.len = self.len + /* "pygom/model/_tau_leap.pyx":30 + * + * cdef double mu, max_cdf, new_cdf + * cdef double total_rate = np.sum(rates) # <<<<<<<<<<<<<< + * safe = False + * cdef int count = 0 */ - __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(2, 193, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__7); - __Pyx_GIVEREF(__pyx_tuple__7); + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_sum); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = NULL; + __pyx_t_7 = 0; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + __pyx_t_7 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, ((PyObject *)__pyx_v_rates)}; + __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_total_rate = __pyx_t_8; - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + /* "pygom/model/_tau_leap.pyx":31 + * cdef double mu, max_cdf, new_cdf + * cdef double total_rate = np.sum(rates) + * safe = False # <<<<<<<<<<<<<< + * cdef int count = 0 + * while safe is False: */ - __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__8); - __Pyx_GIVEREF(__pyx_tuple__8); + __pyx_v_safe = 0; - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + /* "pygom/model/_tau_leap.pyx":32 + * cdef double total_rate = np.sum(rates) + * safe = False + * cdef int count = 0 # <<<<<<<<<<<<<< + * while safe is False: + * cdf_val = 1.0 */ - __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__9); - __Pyx_GIVEREF(__pyx_tuple__9); + __pyx_v_count = 0; - /* "View.MemoryView":420 - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: - * raise TypeError("Cannot assign to read-only memoryview") # <<<<<<<<<<<<<< - * - * have_slices, index = _unellipsify(index, self.view.ndim) + /* "pygom/model/_tau_leap.pyx":33 + * safe = False + * cdef int count = 0 + * while safe is False: # <<<<<<<<<<<<<< + * cdf_val = 1.0 + * for i in range(n_rates): */ - __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_Cannot_assign_to_read_only_memor); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(2, 420, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__10); - __Pyx_GIVEREF(__pyx_tuple__10); + while (1) { + __pyx_t_9 = (__pyx_v_safe == 0); + if (!__pyx_t_9) break; - /* "View.MemoryView":497 - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<< - * else: - * if len(self.view.format) == 1: + /* "pygom/model/_tau_leap.pyx":34 + * cdef int count = 0 + * while safe is False: + * cdf_val = 1.0 # <<<<<<<<<<<<<< + * for i in range(n_rates): + * #xi = x[reactant_mat[:, i]] */ - __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(2, 497, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__11); - __Pyx_GIVEREF(__pyx_tuple__11); + __pyx_v_cdf_val = 1.0; - /* "View.MemoryView":522 - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: - * raise ValueError("Cannot create writable memory view from read-only memoryview") # <<<<<<<<<<<<<< - * - * if flags & PyBUF_ND: + /* "pygom/model/_tau_leap.pyx":35 + * while safe is False: + * cdf_val = 1.0 + * for i in range(n_rates): # <<<<<<<<<<<<<< + * #xi = x[reactant_mat[:, i]] + * #new_cdf = _ppois(xi, mu=tau_scale*r).min() */ - __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_Cannot_create_writable_memory_vi); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(2, 522, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__12); - __Pyx_GIVEREF(__pyx_tuple__12); + __pyx_t_10 = __pyx_v_n_rates; + __pyx_t_11 = __pyx_t_10; + for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) { + __pyx_v_i = __pyx_t_12; - /* "View.MemoryView":572 - * if self.view.strides == NULL: - * - * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<< - * - * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) + /* "pygom/model/_tau_leap.pyx":38 + * #xi = x[reactant_mat[:, i]] + * #new_cdf = _ppois(xi, mu=tau_scale*r).min() + * for j in range(n_reactants): # <<<<<<<<<<<<<< + * if reactant_mat_view[j, i] == 1: + * mu = rates_view[i] * tau_scale */ - __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(2, 572, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__13); - __Pyx_GIVEREF(__pyx_tuple__13); + __pyx_t_13 = __pyx_v_n_reactants; + __pyx_t_14 = __pyx_t_13; + for (__pyx_t_15 = 0; __pyx_t_15 < __pyx_t_14; __pyx_t_15+=1) { + __pyx_v_j = __pyx_t_15; - /* "View.MemoryView":579 - * def suboffsets(self): - * if self.view.suboffsets == NULL: - * return (-1,) * self.view.ndim # <<<<<<<<<<<<<< - * - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) + /* "pygom/model/_tau_leap.pyx":39 + * #new_cdf = _ppois(xi, mu=tau_scale*r).min() + * for j in range(n_reactants): + * if reactant_mat_view[j, i] == 1: # <<<<<<<<<<<<<< + * mu = rates_view[i] * tau_scale + * new_cdf = csc.pdtr(floor(x_view[i]), mu) */ - __pyx_tuple__14 = PyTuple_New(1); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(2, 579, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__14); - __Pyx_INCREF(__pyx_int_neg_1); - __Pyx_GIVEREF(__pyx_int_neg_1); - PyTuple_SET_ITEM(__pyx_tuple__14, 0, __pyx_int_neg_1); - __Pyx_GIVEREF(__pyx_tuple__14); + __pyx_t_16 = __pyx_v_j; + __pyx_t_17 = __pyx_v_i; + __pyx_t_9 = ((*((__pyx_t_5numpy_int64_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_reactant_mat_view.data + __pyx_t_16 * __pyx_v_reactant_mat_view.strides[0]) ) + __pyx_t_17 * __pyx_v_reactant_mat_view.strides[1]) ))) == 1); + if (__pyx_t_9) { - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + /* "pygom/model/_tau_leap.pyx":40 + * for j in range(n_reactants): + * if reactant_mat_view[j, i] == 1: + * mu = rates_view[i] * tau_scale # <<<<<<<<<<<<<< + * new_cdf = csc.pdtr(floor(x_view[i]), mu) + * if new_cdf < cdf_val: */ - __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__15); - __Pyx_GIVEREF(__pyx_tuple__15); + __pyx_t_17 = __pyx_v_i; + __pyx_v_mu = ((*((double *) ( /* dim=0 */ (__pyx_v_rates_view.data + __pyx_t_17 * __pyx_v_rates_view.strides[0]) ))) * __pyx_v_tau_scale); - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + /* "pygom/model/_tau_leap.pyx":41 + * if reactant_mat_view[j, i] == 1: + * mu = rates_view[i] * tau_scale + * new_cdf = csc.pdtr(floor(x_view[i]), mu) # <<<<<<<<<<<<<< + * if new_cdf < cdf_val: + * cdf_val = new_cdf */ - __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__16); - __Pyx_GIVEREF(__pyx_tuple__16); + __pyx_t_17 = __pyx_v_i; + __pyx_v_new_cdf = __pyx_f_5scipy_7special_14cython_special_pdtr(floor((*((double *) ( /* dim=0 */ (__pyx_v_x_view.data + __pyx_t_17 * __pyx_v_x_view.strides[0]) )))), __pyx_v_mu, 0); - /* "View.MemoryView":684 - * if item is Ellipsis: - * if not seen_ellipsis: - * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<< - * seen_ellipsis = True - * else: + /* "pygom/model/_tau_leap.pyx":39 + * #new_cdf = _ppois(xi, mu=tau_scale*r).min() + * for j in range(n_reactants): + * if reactant_mat_view[j, i] == 1: # <<<<<<<<<<<<<< + * mu = rates_view[i] * tau_scale + * new_cdf = csc.pdtr(floor(x_view[i]), mu) */ - __pyx_slice__17 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__17)) __PYX_ERR(2, 684, __pyx_L1_error) - __Pyx_GOTREF(__pyx_slice__17); - __Pyx_GIVEREF(__pyx_slice__17); + } - /* "View.MemoryView":705 - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: - * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<< - * - * + /* "pygom/model/_tau_leap.pyx":42 + * mu = rates_view[i] * tau_scale + * new_cdf = csc.pdtr(floor(x_view[i]), mu) + * if new_cdf < cdf_val: # <<<<<<<<<<<<<< + * cdf_val = new_cdf + * if new_cdf < cdf_val: */ - __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(2, 705, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__18); - __Pyx_GIVEREF(__pyx_tuple__18); + __pyx_t_9 = (__pyx_v_new_cdf < __pyx_v_cdf_val); + if (__pyx_t_9) { - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + /* "pygom/model/_tau_leap.pyx":43 + * new_cdf = csc.pdtr(floor(x_view[i]), mu) + * if new_cdf < cdf_val: + * cdf_val = new_cdf # <<<<<<<<<<<<<< + * if new_cdf < cdf_val: + * cdf_val = new_cdf */ - __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__19); - __Pyx_GIVEREF(__pyx_tuple__19); + __pyx_v_cdf_val = __pyx_v_new_cdf; - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + /* "pygom/model/_tau_leap.pyx":42 + * mu = rates_view[i] * tau_scale + * new_cdf = csc.pdtr(floor(x_view[i]), mu) + * if new_cdf < cdf_val: # <<<<<<<<<<<<<< + * cdf_val = new_cdf + * if new_cdf < cdf_val: */ - __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__20); - __Pyx_GIVEREF(__pyx_tuple__20); - __pyx_tuple__21 = PyTuple_Pack(3, __pyx_int_184977713, __pyx_int_136983863, __pyx_int_112105877); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__21); - __Pyx_GIVEREF(__pyx_tuple__21); + } + } - /* "pygom/model/_tau_leap.pyx":11 - * @cython.wraparound(False) # Deactivate negative indexing. - * @cython.cdivision(True) # Deactivate the div 0 error checking - * def _cy_test_tau_leap_safety(np.ndarray[np.float64_t] x, # <<<<<<<<<<<<<< - * np.ndarray[np.int64_t, ndim=2] reactant_mat, - * np.ndarray[np.float64_t] rates, + /* "pygom/model/_tau_leap.pyx":44 + * if new_cdf < cdf_val: + * cdf_val = new_cdf + * if new_cdf < cdf_val: # <<<<<<<<<<<<<< + * cdf_val = new_cdf + * #cdf_val[i * reactant_mat.shape[0] : (i * reactant_mat.shape[0]) + len(rates)] = _ppois(xi, mu=tau_scale*r) */ - __pyx_tuple__22 = PyTuple_Pack(19, __pyx_n_s_x, __pyx_n_s_reactant_mat, __pyx_n_s_rates, __pyx_n_s_tau_scale, __pyx_n_s_epsilon, __pyx_n_s_rates_view, __pyx_n_s_n_rates, __pyx_n_s_x_view, __pyx_n_s_reactant_mat_view, __pyx_n_s_n_reactants, __pyx_n_s_mu, __pyx_n_s_max_cdf, __pyx_n_s_new_cdf, __pyx_n_s_total_rate, __pyx_n_s_safe, __pyx_n_s_count, __pyx_n_s_cdf_val, __pyx_n_s_i, __pyx_n_s_j); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 11, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__22); - __Pyx_GIVEREF(__pyx_tuple__22); - __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(5, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pygom_model__tau_leap_pyx, __pyx_n_s_cy_test_tau_leap_safety, 11, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) __PYX_ERR(0, 11, __pyx_L1_error) + __pyx_t_9 = (__pyx_v_new_cdf < __pyx_v_cdf_val); + if (__pyx_t_9) { - /* "View.MemoryView":287 - * return self.name + /* "pygom/model/_tau_leap.pyx":45 + * cdf_val = new_cdf + * if new_cdf < cdf_val: + * cdf_val = new_cdf # <<<<<<<<<<<<<< + * #cdf_val[i * reactant_mat.shape[0] : (i * reactant_mat.shape[0]) + len(rates)] = _ppois(xi, mu=tau_scale*r) * - * cdef generic = Enum("") # <<<<<<<<<<<<<< - * cdef strided = Enum("") # default - * cdef indirect = Enum("") */ - __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(2, 287, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__24); - __Pyx_GIVEREF(__pyx_tuple__24); + __pyx_v_cdf_val = __pyx_v_new_cdf; - /* "View.MemoryView":288 - * - * cdef generic = Enum("") - * cdef strided = Enum("") # default # <<<<<<<<<<<<<< - * cdef indirect = Enum("") - * + /* "pygom/model/_tau_leap.pyx":44 + * if new_cdf < cdf_val: + * cdf_val = new_cdf + * if new_cdf < cdf_val: # <<<<<<<<<<<<<< + * cdf_val = new_cdf + * #cdf_val[i * reactant_mat.shape[0] : (i * reactant_mat.shape[0]) + len(rates)] = _ppois(xi, mu=tau_scale*r) */ - __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(2, 288, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__25); - __Pyx_GIVEREF(__pyx_tuple__25); + } + } - /* "View.MemoryView":289 - * cdef generic = Enum("") - * cdef strided = Enum("") # default - * cdef indirect = Enum("") # <<<<<<<<<<<<<< + /* "pygom/model/_tau_leap.pyx":49 * + * # the expected probability that our jump will exceed the value + * max_cdf = 1.0 - cdf_val # <<<<<<<<<<<<<< + * # cannot allow it to exceed out epsilon + * if max_cdf > epsilon: + */ + __pyx_v_max_cdf = (1.0 - __pyx_v_cdf_val); + + /* "pygom/model/_tau_leap.pyx":51 + * max_cdf = 1.0 - cdf_val + * # cannot allow it to exceed out epsilon + * if max_cdf > epsilon: # <<<<<<<<<<<<<< + * tau_scale /= (max_cdf / epsilon) + * else: + */ + __pyx_t_9 = (__pyx_v_max_cdf > __pyx_v_epsilon); + if (__pyx_t_9) { + + /* "pygom/model/_tau_leap.pyx":52 + * # cannot allow it to exceed out epsilon + * if max_cdf > epsilon: + * tau_scale /= (max_cdf / epsilon) # <<<<<<<<<<<<<< + * else: + * safe = True + */ + __pyx_v_tau_scale = (__pyx_v_tau_scale / (__pyx_v_max_cdf / __pyx_v_epsilon)); + + /* "pygom/model/_tau_leap.pyx":51 + * max_cdf = 1.0 - cdf_val + * # cannot allow it to exceed out epsilon + * if max_cdf > epsilon: # <<<<<<<<<<<<<< + * tau_scale /= (max_cdf / epsilon) + * else: + */ + goto __pyx_L12; + } + + /* "pygom/model/_tau_leap.pyx":54 + * tau_scale /= (max_cdf / epsilon) + * else: + * safe = True # <<<<<<<<<<<<<< * + * if tau_scale*total_rate <= 1.0 or count > 256: */ - __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(2, 289, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__26); - __Pyx_GIVEREF(__pyx_tuple__26); + /*else*/ { + __pyx_v_safe = 1; + } + __pyx_L12:; - /* "View.MemoryView":292 + /* "pygom/model/_tau_leap.pyx":56 + * safe = True * + * if tau_scale*total_rate <= 1.0 or count > 256: # <<<<<<<<<<<<<< + * return False + * count += 1 + */ + __pyx_t_18 = ((__pyx_v_tau_scale * __pyx_v_total_rate) <= 1.0); + if (!__pyx_t_18) { + } else { + __pyx_t_9 = __pyx_t_18; + goto __pyx_L14_bool_binop_done; + } + __pyx_t_18 = (__pyx_v_count > 0x100); + __pyx_t_9 = __pyx_t_18; + __pyx_L14_bool_binop_done:; + if (__pyx_t_9) { + + /* "pygom/model/_tau_leap.pyx":57 * - * cdef contiguous = Enum("") # <<<<<<<<<<<<<< - * cdef indirect_contiguous = Enum("") + * if tau_scale*total_rate <= 1.0 or count > 256: + * return False # <<<<<<<<<<<<<< + * count += 1 * */ - __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(2, 292, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__27); - __Pyx_GIVEREF(__pyx_tuple__27); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_False); + __pyx_r = Py_False; + goto __pyx_L0; - /* "View.MemoryView":293 + /* "pygom/model/_tau_leap.pyx":56 + * safe = True * - * cdef contiguous = Enum("") - * cdef indirect_contiguous = Enum("") # <<<<<<<<<<<<<< + * if tau_scale*total_rate <= 1.0 or count > 256: # <<<<<<<<<<<<<< + * return False + * count += 1 + */ + } + + /* "pygom/model/_tau_leap.pyx":58 + * if tau_scale*total_rate <= 1.0 or count > 256: + * return False + * count += 1 # <<<<<<<<<<<<<< * + * return tau_scale, True + */ + __pyx_v_count = (__pyx_v_count + 1); + } + + /* "pygom/model/_tau_leap.pyx":60 + * count += 1 * + * return tau_scale, True # <<<<<<<<<<<<<< */ - __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(2, 293, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__28); - __Pyx_GIVEREF(__pyx_tuple__28); + __Pyx_XDECREF(__pyx_r); + __pyx_t_4 = PyFloat_FromDouble(__pyx_v_tau_scale); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4)) __PYX_ERR(0, 60, __pyx_L1_error); + __Pyx_INCREF(Py_True); + __Pyx_GIVEREF(Py_True); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, Py_True)) __PYX_ERR(0, 60, __pyx_L1_error); + __pyx_t_4 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; - /* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result + /* "pygom/model/_tau_leap.pyx":8 + * cimport cython + * + * @cython.boundscheck(False) # Deactivate bounds checking # <<<<<<<<<<<<<< + * @cython.wraparound(False) # Deactivate negative indexing. + * @cython.cdivision(True) # Deactivate the div 0 error checking */ - __pyx_tuple__29 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(2, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__29); - __Pyx_GIVEREF(__pyx_tuple__29); - __pyx_codeobj__30 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__29, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_Enum, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__30)) __PYX_ERR(2, 1, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; + + /* function exit code */ __pyx_L1_error:; + __PYX_XCLEAR_MEMVIEW(&__pyx_t_1, 1); + __PYX_XCLEAR_MEMVIEW(&__pyx_t_3, 1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_rates.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("pygom.model._tau_leap._cy_test_tau_leap_safety", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_rates.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); + __pyx_L2:; + __PYX_XCLEAR_MEMVIEW(&__pyx_v_rates_view, 1); + __PYX_XCLEAR_MEMVIEW(&__pyx_v_x_view, 1); + __PYX_XCLEAR_MEMVIEW(&__pyx_v_reactant_mat_view, 1); + __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); - return -1; + return __pyx_r; } +static struct __pyx_vtabstruct_array __pyx_vtable_array; -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_112105877 = PyInt_FromLong(112105877L); if (unlikely(!__pyx_int_112105877)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_136983863 = PyInt_FromLong(136983863L); if (unlikely(!__pyx_int_136983863)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_184977713 = PyInt_FromLong(184977713L); if (unlikely(!__pyx_int_184977713)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) __PYX_ERR(0, 1, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; +static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) { + struct __pyx_array_obj *p; + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + if (likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + #endif + p = ((struct __pyx_array_obj *)o); + p->__pyx_vtab = __pyx_vtabptr_array; + p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None); + if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) goto bad; + return o; + bad: + Py_DECREF(o); o = 0; + return NULL; } -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ +static void __pyx_tp_dealloc_array(PyObject *o) { + struct __pyx_array_obj *p = (struct __pyx_array_obj *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && (!PyType_IS_GC(Py_TYPE(o)) || !__Pyx_PyObject_GC_IsFinalized(o))) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_array) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + { + PyObject *etype, *eval, *etb; + PyErr_Fetch(&etype, &eval, &etb); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); + __pyx_array___dealloc__(o); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); + PyErr_Restore(etype, eval, etb); + } + Py_CLEAR(p->mode); + Py_CLEAR(p->_format); + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif +} +static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) { + PyObject *r; + PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; + r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); + Py_DECREF(x); + return r; +} -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - generic = Py_None; Py_INCREF(Py_None); - strided = Py_None; Py_INCREF(Py_None); - indirect = Py_None; Py_INCREF(Py_None); - contiguous = Py_None; Py_INCREF(Py_None); - indirect_contiguous = Py_None; Py_INCREF(Py_None); - __Pyx_RefNannyFinishContext(); - return 0; +static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) { + if (v) { + return __pyx_array___setitem__(o, i, v); + } + else { + __Pyx_TypeName o_type_name; + o_type_name = __Pyx_PyType_GetName(Py_TYPE(o)); + PyErr_Format(PyExc_NotImplementedError, + "Subscript deletion not supported by " __Pyx_FMT_TYPENAME, o_type_name); + __Pyx_DECREF_TypeName(o_type_name); + return -1; + } } -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; +static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) { + PyObject *v = __Pyx_PyObject_GenericGetAttr(o, n); + if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + v = __pyx_array___getattr__(o, n); + } + return v; } -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; +static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(o); } -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - __pyx_vtabptr_array = &__pyx_vtable_array; - __pyx_vtable_array.get_memview = (PyObject *(*)(struct __pyx_array_obj *))__pyx_array_get_memview; - if (PyType_Ready(&__pyx_type___pyx_array) < 0) __PYX_ERR(2, 106, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type___pyx_array.tp_print = 0; +static PyMethodDef __pyx_methods_array[] = { + {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0}, + {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_array_1__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_array_3__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {0, 0, 0, 0} +}; + +static struct PyGetSetDef __pyx_getsets_array[] = { + {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, (char *)0, 0}, + {0, 0, 0, 0, 0} +}; +#if CYTHON_USE_TYPE_SPECS +#if !CYTHON_COMPILING_IN_LIMITED_API + +static PyBufferProcs __pyx_tp_as_buffer_array = { + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getreadbuffer*/ #endif - if (__Pyx_SetVtable(__pyx_type___pyx_array.tp_dict, __pyx_vtabptr_array) < 0) __PYX_ERR(2, 106, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type___pyx_array) < 0) __PYX_ERR(2, 106, __pyx_L1_error) - __pyx_array_type = &__pyx_type___pyx_array; - if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) __PYX_ERR(2, 280, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type___pyx_MemviewEnum.tp_print = 0; + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getwritebuffer*/ #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type___pyx_MemviewEnum.tp_dictoffset && __pyx_type___pyx_MemviewEnum.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type___pyx_MemviewEnum.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (__Pyx_setup_reduce((PyObject*)&__pyx_type___pyx_MemviewEnum) < 0) __PYX_ERR(2, 280, __pyx_L1_error) - __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum; - __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview; - __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer; - __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice; - __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment; - __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar; - __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed; - __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object; - __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object; - if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) __PYX_ERR(2, 331, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type___pyx_memoryview.tp_print = 0; + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getsegcount*/ #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type___pyx_memoryview.tp_dictoffset && __pyx_type___pyx_memoryview.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type___pyx_memoryview.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) __PYX_ERR(2, 331, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type___pyx_memoryview) < 0) __PYX_ERR(2, 331, __pyx_L1_error) - __pyx_memoryview_type = &__pyx_type___pyx_memoryview; - __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice; - __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview; - __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object; - __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object; - __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type; - if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) __PYX_ERR(2, 967, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type___pyx_memoryviewslice.tp_print = 0; + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getcharbuffer*/ + #endif + __pyx_array_getbuffer, /*bf_getbuffer*/ + 0, /*bf_releasebuffer*/ +}; +#endif +static PyType_Slot __pyx_type___pyx_array_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_array}, + {Py_sq_length, (void *)__pyx_array___len__}, + {Py_sq_item, (void *)__pyx_sq_item_array}, + {Py_mp_length, (void *)__pyx_array___len__}, + {Py_mp_subscript, (void *)__pyx_array___getitem__}, + {Py_mp_ass_subscript, (void *)__pyx_mp_ass_subscript_array}, + {Py_tp_getattro, (void *)__pyx_tp_getattro_array}, + #if defined(Py_bf_getbuffer) + {Py_bf_getbuffer, (void *)__pyx_array_getbuffer}, + #endif + {Py_tp_methods, (void *)__pyx_methods_array}, + {Py_tp_getset, (void *)__pyx_getsets_array}, + {Py_tp_new, (void *)__pyx_tp_new_array}, + {0, 0}, +}; +static PyType_Spec __pyx_type___pyx_array_spec = { + "pygom.model._tau_leap.array", + sizeof(struct __pyx_array_obj), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_SEQUENCE, + __pyx_type___pyx_array_slots, +}; +#else + +static PySequenceMethods __pyx_tp_as_sequence_array = { + __pyx_array___len__, /*sq_length*/ + 0, /*sq_concat*/ + 0, /*sq_repeat*/ + __pyx_sq_item_array, /*sq_item*/ + 0, /*sq_slice*/ + 0, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ + 0, /*sq_contains*/ + 0, /*sq_inplace_concat*/ + 0, /*sq_inplace_repeat*/ +}; + +static PyMappingMethods __pyx_tp_as_mapping_array = { + __pyx_array___len__, /*mp_length*/ + __pyx_array___getitem__, /*mp_subscript*/ + __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/ +}; + +static PyBufferProcs __pyx_tp_as_buffer_array = { + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getreadbuffer*/ + #endif + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getwritebuffer*/ + #endif + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getsegcount*/ + #endif + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getcharbuffer*/ + #endif + __pyx_array_getbuffer, /*bf_getbuffer*/ + 0, /*bf_releasebuffer*/ +}; + +static PyTypeObject __pyx_type___pyx_array = { + PyVarObject_HEAD_INIT(0, 0) + "pygom.model._tau_leap.""array", /*tp_name*/ + sizeof(struct __pyx_array_obj), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_array, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + &__pyx_tp_as_sequence_array, /*tp_as_sequence*/ + &__pyx_tp_as_mapping_array, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + __pyx_tp_getattro_array, /*tp_getattro*/ + 0, /*tp_setattro*/ + &__pyx_tp_as_buffer_array, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_SEQUENCE, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_array, /*tp_methods*/ + 0, /*tp_members*/ + __pyx_getsets_array, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_array, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type___pyx_memoryviewslice.tp_dictoffset && __pyx_type___pyx_memoryviewslice.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type___pyx_memoryviewslice.tp_getattro = __Pyx_PyObject_GenericGetAttr; +}; +#endif + +static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + struct __pyx_MemviewEnum_obj *p; + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + if (likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); } - if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) __PYX_ERR(2, 967, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type___pyx_memoryviewslice) < 0) __PYX_ERR(2, 967, __pyx_L1_error) - __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; + if (unlikely(!o)) return 0; + #endif + p = ((struct __pyx_MemviewEnum_obj *)o); + p->name = Py_None; Py_INCREF(Py_None); + return o; } -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", - #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyTypeObject), +static void __pyx_tp_dealloc_Enum(PyObject *o) { + struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_Enum) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->name); + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); #else - sizeof(PyHeapTypeObject), + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } #endif - __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(3, 9, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule("numpy"); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 199, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_5numpy_dtype = __Pyx_ImportType(__pyx_t_1, "numpy", "dtype", sizeof(PyArray_Descr), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_dtype) __PYX_ERR(1, 199, __pyx_L1_error) - __pyx_ptype_5numpy_flatiter = __Pyx_ImportType(__pyx_t_1, "numpy", "flatiter", sizeof(PyArrayIterObject), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_flatiter) __PYX_ERR(1, 222, __pyx_L1_error) - __pyx_ptype_5numpy_broadcast = __Pyx_ImportType(__pyx_t_1, "numpy", "broadcast", sizeof(PyArrayMultiIterObject), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_broadcast) __PYX_ERR(1, 226, __pyx_L1_error) - __pyx_ptype_5numpy_ndarray = __Pyx_ImportType(__pyx_t_1, "numpy", "ndarray", sizeof(PyArrayObject), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_ndarray) __PYX_ERR(1, 238, __pyx_L1_error) - __pyx_ptype_5numpy_generic = __Pyx_ImportType(__pyx_t_1, "numpy", "generic", sizeof(PyObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_generic) __PYX_ERR(1, 770, __pyx_L1_error) - __pyx_ptype_5numpy_number = __Pyx_ImportType(__pyx_t_1, "numpy", "number", sizeof(PyObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_number) __PYX_ERR(1, 772, __pyx_L1_error) - __pyx_ptype_5numpy_integer = __Pyx_ImportType(__pyx_t_1, "numpy", "integer", sizeof(PyObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_integer) __PYX_ERR(1, 774, __pyx_L1_error) - __pyx_ptype_5numpy_signedinteger = __Pyx_ImportType(__pyx_t_1, "numpy", "signedinteger", sizeof(PyObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_signedinteger) __PYX_ERR(1, 776, __pyx_L1_error) - __pyx_ptype_5numpy_unsignedinteger = __Pyx_ImportType(__pyx_t_1, "numpy", "unsignedinteger", sizeof(PyObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_unsignedinteger) __PYX_ERR(1, 778, __pyx_L1_error) - __pyx_ptype_5numpy_inexact = __Pyx_ImportType(__pyx_t_1, "numpy", "inexact", sizeof(PyObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_inexact) __PYX_ERR(1, 780, __pyx_L1_error) - __pyx_ptype_5numpy_floating = __Pyx_ImportType(__pyx_t_1, "numpy", "floating", sizeof(PyObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_floating) __PYX_ERR(1, 782, __pyx_L1_error) - __pyx_ptype_5numpy_complexfloating = __Pyx_ImportType(__pyx_t_1, "numpy", "complexfloating", sizeof(PyObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_complexfloating) __PYX_ERR(1, 784, __pyx_L1_error) - __pyx_ptype_5numpy_flexible = __Pyx_ImportType(__pyx_t_1, "numpy", "flexible", sizeof(PyObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_flexible) __PYX_ERR(1, 786, __pyx_L1_error) - __pyx_ptype_5numpy_character = __Pyx_ImportType(__pyx_t_1, "numpy", "character", sizeof(PyObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_character) __PYX_ERR(1, 788, __pyx_L1_error) - __pyx_ptype_5numpy_ufunc = __Pyx_ImportType(__pyx_t_1, "numpy", "ufunc", sizeof(PyUFuncObject), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_ufunc) __PYX_ERR(1, 826, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; } -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); +static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; + if (p->name) { + e = (*v)(p->name, a); if (e) return e; + } return 0; } -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __pyx_t_1 = PyImport_ImportModule("scipy.special.cython_special"); if (!__pyx_t_1) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (__Pyx_ImportFunction(__pyx_t_1, "pdtr", (void (**)(void))&__pyx_f_5scipy_7special_14cython_special_pdtr, "double (double, double, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_RefNannyFinishContext(); +static int __pyx_tp_clear_Enum(PyObject *o) { + PyObject* tmp; + struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; + tmp = ((PyObject*)p->name); + p->name = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; } +static PyObject *__pyx_specialmethod___pyx_MemviewEnum___repr__(PyObject *self, CYTHON_UNUSED PyObject *arg) { + return __pyx_MemviewEnum___repr__(self); +} -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif +static PyMethodDef __pyx_methods_Enum[] = { + {"__repr__", (PyCFunction)__pyx_specialmethod___pyx_MemviewEnum___repr__, METH_NOARGS|METH_COEXIST, 0}, + {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_MemviewEnum_1__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_MemviewEnum_3__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {0, 0, 0, 0} +}; +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type___pyx_MemviewEnum_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_Enum}, + {Py_tp_repr, (void *)__pyx_MemviewEnum___repr__}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_Enum}, + {Py_tp_clear, (void *)__pyx_tp_clear_Enum}, + {Py_tp_methods, (void *)__pyx_methods_Enum}, + {Py_tp_init, (void *)__pyx_MemviewEnum___init__}, + {Py_tp_new, (void *)__pyx_tp_new_Enum}, + {0, 0}, +}; +static PyType_Spec __pyx_type___pyx_MemviewEnum_spec = { + "pygom.model._tau_leap.Enum", + sizeof(struct __pyx_MemviewEnum_obj), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, + __pyx_type___pyx_MemviewEnum_slots, +}; #else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC init_tau_leap(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC init_tau_leap(void) -#else -__Pyx_PyMODINIT_FUNC PyInit__tau_leap(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit__tau_leap(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { - result = PyDict_SetItemString(moddict, to_name, value); - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - -static CYTHON_SMALL_CODE int __pyx_pymod_exec__tau_leap(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - static PyThread_type_lock __pyx_t_2[8]; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module '_tau_leap' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); +static PyTypeObject __pyx_type___pyx_MemviewEnum = { + PyVarObject_HEAD_INIT(0, 0) + "pygom.model._tau_leap.""Enum", /*tp_name*/ + sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_Enum, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ #endif - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__tau_leap(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_MemviewEnum___repr__, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_Enum, /*tp_traverse*/ + __pyx_tp_clear_Enum, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_Enum, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_MemviewEnum___init__, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_Enum, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - PyEval_InitThreads(); + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("_tau_leap", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_b); - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_cython_runtime); - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) +}; +#endif +static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview; + +static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) { + struct __pyx_memoryview_obj *p; + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + if (likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; #endif - if (__pyx_module_is_main_pygom__model___tau_leap) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name_2, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + p = ((struct __pyx_memoryview_obj *)o); + p->__pyx_vtab = __pyx_vtabptr_memoryview; + p->obj = Py_None; Py_INCREF(Py_None); + p->_size = Py_None; Py_INCREF(Py_None); + p->_array_interface = Py_None; Py_INCREF(Py_None); + p->view.obj = NULL; + if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) goto bad; + return o; + bad: + Py_DECREF(o); o = 0; + return NULL; +} + +static void __pyx_tp_dealloc_memoryview(PyObject *o) { + struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_memoryview) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } } - #if PY_MAJOR_VERSION >= 3 + #endif + PyObject_GC_UnTrack(o); { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "pygom.model._tau_leap")) { - if (unlikely(PyDict_SetItemString(modules, "pygom.model._tau_leap", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } + PyObject *etype, *eval, *etb; + PyErr_Fetch(&etype, &eval, &etb); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); + __pyx_memoryview___dealloc__(o); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); + PyErr_Restore(etype, eval, etb); + } + Py_CLEAR(p->obj); + Py_CLEAR(p->_size); + Py_CLEAR(p->_array_interface); + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); } #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - if (unlikely(__Pyx_modinit_type_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - (void)__Pyx_modinit_variable_import_code(); - if (unlikely(__Pyx_modinit_function_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "pygom/model/_tau_leap.pyx":1 - * import numpy as np # <<<<<<<<<<<<<< - * cimport numpy as np - * - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; +} - /* "pygom/model/_tau_leap.pyx":11 - * @cython.wraparound(False) # Deactivate negative indexing. - * @cython.cdivision(True) # Deactivate the div 0 error checking - * def _cy_test_tau_leap_safety(np.ndarray[np.float64_t] x, # <<<<<<<<<<<<<< - * np.ndarray[np.int64_t, ndim=2] reactant_mat, - * np.ndarray[np.float64_t] rates, - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety, NULL, __pyx_n_s_pygom_model__tau_leap); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 11, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_cy_test_tau_leap_safety, __pyx_t_1) < 0) __PYX_ERR(0, 11, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; +static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; + if (p->obj) { + e = (*v)(p->obj, a); if (e) return e; + } + if (p->_size) { + e = (*v)(p->_size, a); if (e) return e; + } + if (p->_array_interface) { + e = (*v)(p->_array_interface, a); if (e) return e; + } + if (p->view.obj) { + e = (*v)(p->view.obj, a); if (e) return e; + } + return 0; +} - /* "pygom/model/_tau_leap.pyx":1 - * import numpy as np # <<<<<<<<<<<<<< - * cimport numpy as np - * - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; +static int __pyx_tp_clear_memoryview(PyObject *o) { + PyObject* tmp; + struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; + tmp = ((PyObject*)p->obj); + p->obj = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_size); + p->_size = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_array_interface); + p->_array_interface = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + Py_CLEAR(p->view.obj); + return 0; +} +static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) { + PyObject *r; + PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; + r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); + Py_DECREF(x); + return r; +} - /* "View.MemoryView":210 - * info.obj = self - * - * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<< - * - * def __dealloc__(array self): - */ - __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), ((char *)"getbuffer(obj, view, flags)")); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 210, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem((PyObject *)__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) __PYX_ERR(2, 210, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - PyType_Modified(__pyx_array_type); +static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) { + if (v) { + return __pyx_memoryview___setitem__(o, i, v); + } + else { + __Pyx_TypeName o_type_name; + o_type_name = __Pyx_PyType_GetName(Py_TYPE(o)); + PyErr_Format(PyExc_NotImplementedError, + "Subscript deletion not supported by " __Pyx_FMT_TYPENAME, o_type_name); + __Pyx_DECREF_TypeName(o_type_name); + return -1; + } +} - /* "View.MemoryView":287 - * return self.name - * - * cdef generic = Enum("") # <<<<<<<<<<<<<< - * cdef strided = Enum("") # default - * cdef indirect = Enum("") - */ - __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 287, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(generic); - __Pyx_DECREF_SET(generic, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; +static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(o); +} - /* "View.MemoryView":288 - * - * cdef generic = Enum("") - * cdef strided = Enum("") # default # <<<<<<<<<<<<<< - * cdef indirect = Enum("") - * - */ - __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 288, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(strided); - __Pyx_DECREF_SET(strided, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; +static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(o); +} - /* "View.MemoryView":289 - * cdef generic = Enum("") - * cdef strided = Enum("") # default - * cdef indirect = Enum("") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 289, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(indirect); - __Pyx_DECREF_SET(indirect, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; +static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(o); +} - /* "View.MemoryView":292 - * - * - * cdef contiguous = Enum("") # <<<<<<<<<<<<<< - * cdef indirect_contiguous = Enum("") - * - */ - __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 292, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(contiguous); - __Pyx_DECREF_SET(contiguous, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; +static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(o); +} - /* "View.MemoryView":293 - * - * cdef contiguous = Enum("") - * cdef indirect_contiguous = Enum("") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 293, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XGOTREF(indirect_contiguous); - __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __pyx_t_1 = 0; +static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(o); +} - /* "View.MemoryView":317 - * - * DEF THREAD_LOCKS_PREALLOCATED = 8 - * cdef int __pyx_memoryview_thread_locks_used = 0 # <<<<<<<<<<<<<< - * cdef PyThread_type_lock[THREAD_LOCKS_PREALLOCATED] __pyx_memoryview_thread_locks = [ - * PyThread_allocate_lock(), - */ - __pyx_memoryview_thread_locks_used = 0; +static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(o); +} - /* "View.MemoryView":318 - * DEF THREAD_LOCKS_PREALLOCATED = 8 - * cdef int __pyx_memoryview_thread_locks_used = 0 - * cdef PyThread_type_lock[THREAD_LOCKS_PREALLOCATED] __pyx_memoryview_thread_locks = [ # <<<<<<<<<<<<<< - * PyThread_allocate_lock(), - * PyThread_allocate_lock(), - */ - __pyx_t_2[0] = PyThread_allocate_lock(); - __pyx_t_2[1] = PyThread_allocate_lock(); - __pyx_t_2[2] = PyThread_allocate_lock(); - __pyx_t_2[3] = PyThread_allocate_lock(); - __pyx_t_2[4] = PyThread_allocate_lock(); - __pyx_t_2[5] = PyThread_allocate_lock(); - __pyx_t_2[6] = PyThread_allocate_lock(); - __pyx_t_2[7] = PyThread_allocate_lock(); - memcpy(&(__pyx_memoryview_thread_locks[0]), __pyx_t_2, sizeof(__pyx_memoryview_thread_locks[0]) * (8)); +static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(o); +} - /* "View.MemoryView":551 - * info.obj = self - * - * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), ((char *)"getbuffer(obj, view, flags)")); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 551, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem((PyObject *)__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) __PYX_ERR(2, 551, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - PyType_Modified(__pyx_memoryview_type); +static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(o); +} - /* "View.MemoryView":997 - * return self.from_object - * - * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), ((char *)"getbuffer(obj, view, flags)")); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 997, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem((PyObject *)__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) __PYX_ERR(2, 997, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - PyType_Modified(__pyx_memoryviewslice_type); +static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(o); +} - /* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_15View_dot_MemoryView_1__pyx_unpickle_Enum, NULL, __pyx_n_s_View_MemoryView); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_Enum, __pyx_t_1) < 0) __PYX_ERR(2, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; +static PyObject *__pyx_specialmethod___pyx_memoryview___repr__(PyObject *self, CYTHON_UNUSED PyObject *arg) { + return __pyx_memoryview___repr__(self); +} - /* "(tree fragment)":11 - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - */ +static PyMethodDef __pyx_methods_memoryview[] = { + {"__repr__", (PyCFunction)__pyx_specialmethod___pyx_memoryview___repr__, METH_NOARGS|METH_COEXIST, 0}, + {"is_c_contig", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_memoryview_is_c_contig, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {"is_f_contig", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_memoryview_is_f_contig, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {"copy", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_memoryview_copy, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {"copy_fortran", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_memoryview_copy_fortran, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_memoryview_1__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_memoryview_3__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {0, 0, 0, 0} +}; - /*--- Wrapped vars code ---*/ +static struct PyGetSetDef __pyx_getsets_memoryview[] = { + {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, (char *)0, 0}, + {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, (char *)0, 0}, + {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, (char *)0, 0}, + {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, (char *)0, 0}, + {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, (char *)0, 0}, + {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, (char *)0, 0}, + {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, (char *)0, 0}, + {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, (char *)0, 0}, + {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, (char *)0, 0}, + {0, 0, 0, 0, 0} +}; +#if CYTHON_USE_TYPE_SPECS +#if !CYTHON_COMPILING_IN_LIMITED_API - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init pygom.model._tau_leap", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - Py_CLEAR(__pyx_m); - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init pygom.model._tau_leap"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; +static PyBufferProcs __pyx_tp_as_buffer_memoryview = { + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getreadbuffer*/ #endif -} + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getwritebuffer*/ + #endif + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getsegcount*/ + #endif + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getcharbuffer*/ + #endif + __pyx_memoryview_getbuffer, /*bf_getbuffer*/ + 0, /*bf_releasebuffer*/ +}; +#endif +static PyType_Slot __pyx_type___pyx_memoryview_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_memoryview}, + {Py_tp_repr, (void *)__pyx_memoryview___repr__}, + {Py_sq_length, (void *)__pyx_memoryview___len__}, + {Py_sq_item, (void *)__pyx_sq_item_memoryview}, + {Py_mp_length, (void *)__pyx_memoryview___len__}, + {Py_mp_subscript, (void *)__pyx_memoryview___getitem__}, + {Py_mp_ass_subscript, (void *)__pyx_mp_ass_subscript_memoryview}, + {Py_tp_str, (void *)__pyx_memoryview___str__}, + #if defined(Py_bf_getbuffer) + {Py_bf_getbuffer, (void *)__pyx_memoryview_getbuffer}, + #endif + {Py_tp_traverse, (void *)__pyx_tp_traverse_memoryview}, + {Py_tp_clear, (void *)__pyx_tp_clear_memoryview}, + {Py_tp_methods, (void *)__pyx_methods_memoryview}, + {Py_tp_getset, (void *)__pyx_getsets_memoryview}, + {Py_tp_new, (void *)__pyx_tp_new_memoryview}, + {0, 0}, +}; +static PyType_Spec __pyx_type___pyx_memoryview_spec = { + "pygom.model._tau_leap.memoryview", + sizeof(struct __pyx_memoryview_obj), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, + __pyx_type___pyx_memoryview_slots, +}; +#else -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif +static PySequenceMethods __pyx_tp_as_sequence_memoryview = { + __pyx_memoryview___len__, /*sq_length*/ + 0, /*sq_concat*/ + 0, /*sq_repeat*/ + __pyx_sq_item_memoryview, /*sq_item*/ + 0, /*sq_slice*/ + 0, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ + 0, /*sq_contains*/ + 0, /*sq_inplace_concat*/ + 0, /*sq_inplace_repeat*/ +}; -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +static PyMappingMethods __pyx_tp_as_mapping_memoryview = { + __pyx_memoryview___len__, /*mp_length*/ + __pyx_memoryview___getitem__, /*mp_subscript*/ + __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/ +}; + +static PyBufferProcs __pyx_tp_as_buffer_memoryview = { + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getreadbuffer*/ + #endif + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getwritebuffer*/ + #endif + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getsegcount*/ + #endif + #if PY_MAJOR_VERSION < 3 + 0, /*bf_getcharbuffer*/ + #endif + __pyx_memoryview_getbuffer, /*bf_getbuffer*/ + 0, /*bf_releasebuffer*/ +}; + +static PyTypeObject __pyx_type___pyx_memoryview = { + PyVarObject_HEAD_INIT(0, 0) + "pygom.model._tau_leap.""memoryview", /*tp_name*/ + sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_memoryview, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + __pyx_memoryview___repr__, /*tp_repr*/ + 0, /*tp_as_number*/ + &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/ + &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + __pyx_memoryview___str__, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_memoryview, /*tp_traverse*/ + __pyx_tp_clear_memoryview, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_memoryview, /*tp_methods*/ + 0, /*tp_members*/ + __pyx_getsets_memoryview, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_memoryview, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; #endif - return PyObject_GetAttr(obj, attr_name); +static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice; + +static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) { + struct __pyx_memoryviewslice_obj *p; + PyObject *o = __pyx_tp_new_memoryview(t, a, k); + if (unlikely(!o)) return 0; + p = ((struct __pyx_memoryviewslice_obj *)o); + p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice; + p->from_object = Py_None; Py_INCREF(Py_None); + p->from_slice.memview = NULL; + return o; } -#endif -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); - if (unlikely(!result)) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif +static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) { + struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc__memoryviewslice) { + if (PyObject_CallFinalizerFromDealloc(o)) return; } - return result; + } + #endif + PyObject_GC_UnTrack(o); + { + PyObject *etype, *eval, *etb; + PyErr_Fetch(&etype, &eval, &etb); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); + __pyx_memoryviewslice___dealloc__(o); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); + PyErr_Restore(etype, eval, etb); + } + Py_CLEAR(p->from_object); + PyObject_GC_Track(o); + __pyx_tp_dealloc_memoryview(o); } -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); +static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; + e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e; + if (p->from_object) { + e = (*v)(p->from_object, a); if (e) return e; + } + return 0; } -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif +static int __pyx_tp_clear__memoryviewslice(PyObject *o) { + PyObject* tmp; + struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; + __pyx_tp_clear_memoryview(o); + tmp = ((PyObject*)p->from_object); + p->from_object = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + __PYX_XCLEAR_MEMVIEW(&p->from_slice, 1); + return 0; } -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; +static PyMethodDef __pyx_methods__memoryviewslice[] = { + {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_memoryviewslice_1__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_memoryviewslice_3__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, + {0, 0, 0, 0} +}; +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type___pyx_memoryviewslice_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc__memoryviewslice}, + {Py_tp_doc, (void *)PyDoc_STR("Internal class for passing memoryview slices to Python")}, + {Py_tp_traverse, (void *)__pyx_tp_traverse__memoryviewslice}, + {Py_tp_clear, (void *)__pyx_tp_clear__memoryviewslice}, + {Py_tp_methods, (void *)__pyx_methods__memoryviewslice}, + {Py_tp_new, (void *)__pyx_tp_new__memoryviewslice}, + {0, 0}, +}; +static PyType_Spec __pyx_type___pyx_memoryviewslice_spec = { + "pygom.model._tau_leap._memoryviewslice", + sizeof(struct __pyx_memoryviewslice_obj), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_SEQUENCE, + __pyx_type___pyx_memoryviewslice_slots, +}; +#else + +static PyTypeObject __pyx_type___pyx_memoryviewslice = { + PyVarObject_HEAD_INIT(0, 0) + "pygom.model._tau_leap.""_memoryviewslice", /*tp_name*/ + sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + #if CYTHON_COMPILING_IN_PYPY || 0 + __pyx_memoryview___repr__, /*tp_repr*/ + #else + 0, /*tp_repr*/ + #endif + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + #if CYTHON_COMPILING_IN_PYPY || 0 + __pyx_memoryview___str__, /*tp_str*/ + #else + 0, /*tp_str*/ + #endif + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_SEQUENCE, /*tp_flags*/ + PyDoc_STR("Internal class for passing memoryview slices to Python"), /*tp_doc*/ + __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/ + __pyx_tp_clear__memoryviewslice, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods__memoryviewslice, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new__memoryviewslice, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif +/* #### Code section: pystring_table ### */ + +static int __Pyx_CreateStringTabAndInitStrings(void) { + __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_u_, __pyx_k_, sizeof(__pyx_k_), 0, 1, 0, 0}, + {&__pyx_n_s_ASCII, __pyx_k_ASCII, sizeof(__pyx_k_ASCII), 0, 0, 1, 1}, + {&__pyx_kp_s_All_dimensions_preceding_dimensi, __pyx_k_All_dimensions_preceding_dimensi, sizeof(__pyx_k_All_dimensions_preceding_dimensi), 0, 0, 1, 0}, + {&__pyx_n_s_AssertionError, __pyx_k_AssertionError, sizeof(__pyx_k_AssertionError), 0, 0, 1, 1}, + {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0}, + {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0}, + {&__pyx_kp_s_Cannot_assign_to_read_only_memor, __pyx_k_Cannot_assign_to_read_only_memor, sizeof(__pyx_k_Cannot_assign_to_read_only_memor), 0, 0, 1, 0}, + {&__pyx_kp_s_Cannot_create_writable_memory_vi, __pyx_k_Cannot_create_writable_memory_vi, sizeof(__pyx_k_Cannot_create_writable_memory_vi), 0, 0, 1, 0}, + {&__pyx_kp_u_Cannot_index_with_type, __pyx_k_Cannot_index_with_type, sizeof(__pyx_k_Cannot_index_with_type), 0, 1, 0, 0}, + {&__pyx_kp_s_Cannot_transpose_memoryview_with, __pyx_k_Cannot_transpose_memoryview_with, sizeof(__pyx_k_Cannot_transpose_memoryview_with), 0, 0, 1, 0}, + {&__pyx_kp_s_Dimension_d_is_not_direct, __pyx_k_Dimension_d_is_not_direct, sizeof(__pyx_k_Dimension_d_is_not_direct), 0, 0, 1, 0}, + {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1}, + {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0}, + {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, + {&__pyx_kp_s_Incompatible_checksums_0x_x_vs_0, __pyx_k_Incompatible_checksums_0x_x_vs_0, sizeof(__pyx_k_Incompatible_checksums_0x_x_vs_0), 0, 0, 1, 0}, + {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1}, + {&__pyx_kp_s_Index_out_of_bounds_axis_d, __pyx_k_Index_out_of_bounds_axis_d, sizeof(__pyx_k_Index_out_of_bounds_axis_d), 0, 0, 1, 0}, + {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0}, + {&__pyx_kp_u_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 1, 0, 0}, + {&__pyx_kp_u_Invalid_shape_in_axis, __pyx_k_Invalid_shape_in_axis, sizeof(__pyx_k_Invalid_shape_in_axis), 0, 1, 0, 0}, + {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1}, + {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0}, + {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0}, + {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1}, + {&__pyx_kp_u_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 1, 0, 0}, + {&__pyx_n_s_PickleError, __pyx_k_PickleError, sizeof(__pyx_k_PickleError), 0, 0, 1, 1}, + {&__pyx_n_s_Sequence, __pyx_k_Sequence, sizeof(__pyx_k_Sequence), 0, 0, 1, 1}, + {&__pyx_kp_s_Step_may_not_be_zero_axis_d, __pyx_k_Step_may_not_be_zero_axis_d, sizeof(__pyx_k_Step_may_not_be_zero_axis_d), 0, 0, 1, 0}, + {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, + {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0}, + {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, + {&__pyx_n_s_View_MemoryView, __pyx_k_View_MemoryView, sizeof(__pyx_k_View_MemoryView), 0, 0, 1, 1}, + {&__pyx_kp_u__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 1, 0, 0}, + {&__pyx_n_s__24, __pyx_k__24, sizeof(__pyx_k__24), 0, 0, 1, 1}, + {&__pyx_n_s__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 0, 1, 1}, + {&__pyx_kp_u__6, __pyx_k__6, sizeof(__pyx_k__6), 0, 1, 0, 0}, + {&__pyx_kp_u__7, __pyx_k__7, sizeof(__pyx_k__7), 0, 1, 0, 0}, + {&__pyx_n_s_abc, __pyx_k_abc, sizeof(__pyx_k_abc), 0, 0, 1, 1}, + {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1}, + {&__pyx_kp_u_and, __pyx_k_and, sizeof(__pyx_k_and), 0, 1, 0, 0}, + {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1}, + {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1}, + {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1}, + {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1}, + {&__pyx_n_s_cdf_val, __pyx_k_cdf_val, sizeof(__pyx_k_cdf_val), 0, 0, 1, 1}, + {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1}, + {&__pyx_n_s_class_getitem, __pyx_k_class_getitem, sizeof(__pyx_k_class_getitem), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_collections, __pyx_k_collections, sizeof(__pyx_k_collections), 0, 0, 1, 1}, + {&__pyx_kp_s_collections_abc, __pyx_k_collections_abc, sizeof(__pyx_k_collections_abc), 0, 0, 1, 0}, + {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0}, + {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0}, + {&__pyx_n_s_count, __pyx_k_count, sizeof(__pyx_k_count), 0, 0, 1, 1}, + {&__pyx_n_s_cy_test_tau_leap_safety, __pyx_k_cy_test_tau_leap_safety, sizeof(__pyx_k_cy_test_tau_leap_safety), 0, 0, 1, 1}, + {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, + {&__pyx_kp_u_disable, __pyx_k_disable, sizeof(__pyx_k_disable), 0, 1, 0, 0}, + {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1}, + {&__pyx_kp_u_enable, __pyx_k_enable, sizeof(__pyx_k_enable), 0, 1, 0, 0}, + {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1}, + {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1}, + {&__pyx_n_s_epsilon, __pyx_k_epsilon, sizeof(__pyx_k_epsilon), 0, 0, 1, 1}, + {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1}, + {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1}, + {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, + {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1}, + {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1}, + {&__pyx_kp_u_gc, __pyx_k_gc, sizeof(__pyx_k_gc), 0, 1, 0, 0}, + {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, + {&__pyx_kp_u_got, __pyx_k_got, sizeof(__pyx_k_got), 0, 1, 0, 0}, + {&__pyx_kp_u_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 1, 0, 0}, + {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, + {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1}, + {&__pyx_n_s_initializing, __pyx_k_initializing, sizeof(__pyx_k_initializing), 0, 0, 1, 1}, + {&__pyx_n_s_is_coroutine, __pyx_k_is_coroutine, sizeof(__pyx_k_is_coroutine), 0, 0, 1, 1}, + {&__pyx_kp_u_isenabled, __pyx_k_isenabled, sizeof(__pyx_k_isenabled), 0, 1, 0, 0}, + {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1}, + {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0}, + {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_max_cdf, __pyx_k_max_cdf, sizeof(__pyx_k_max_cdf), 0, 0, 1, 1}, + {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1}, + {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1}, + {&__pyx_n_s_mu, __pyx_k_mu, sizeof(__pyx_k_mu), 0, 0, 1, 1}, + {&__pyx_n_s_n_rates, __pyx_k_n_rates, sizeof(__pyx_k_n_rates), 0, 0, 1, 1}, + {&__pyx_n_s_n_reactants, __pyx_k_n_reactants, sizeof(__pyx_k_n_reactants), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1}, + {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1}, + {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, + {&__pyx_n_s_new_cdf, __pyx_k_new_cdf, sizeof(__pyx_k_new_cdf), 0, 0, 1, 1}, + {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, + {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, + {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, + {&__pyx_kp_s_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 0, 1, 0}, + {&__pyx_kp_s_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 0, 1, 0}, + {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1}, + {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1}, + {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, + {&__pyx_n_s_pygom_model__tau_leap, __pyx_k_pygom_model__tau_leap, sizeof(__pyx_k_pygom_model__tau_leap), 0, 0, 1, 1}, + {&__pyx_kp_s_pygom_model__tau_leap_pyx, __pyx_k_pygom_model__tau_leap_pyx, sizeof(__pyx_k_pygom_model__tau_leap_pyx), 0, 0, 1, 0}, + {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_checksum, __pyx_k_pyx_checksum, sizeof(__pyx_k_pyx_checksum), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_result, __pyx_k_pyx_result, sizeof(__pyx_k_pyx_result), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_type, __pyx_k_pyx_type, sizeof(__pyx_k_pyx_type), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_unpickle_Enum, __pyx_k_pyx_unpickle_Enum, sizeof(__pyx_k_pyx_unpickle_Enum), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_rates, __pyx_k_rates, sizeof(__pyx_k_rates), 0, 0, 1, 1}, + {&__pyx_n_s_rates_view, __pyx_k_rates_view, sizeof(__pyx_k_rates_view), 0, 0, 1, 1}, + {&__pyx_n_s_reactant_mat, __pyx_k_reactant_mat, sizeof(__pyx_k_reactant_mat), 0, 0, 1, 1}, + {&__pyx_n_s_reactant_mat_view, __pyx_k_reactant_mat_view, sizeof(__pyx_k_reactant_mat_view), 0, 0, 1, 1}, + {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, + {&__pyx_n_s_register, __pyx_k_register, sizeof(__pyx_k_register), 0, 0, 1, 1}, + {&__pyx_n_s_safe, __pyx_k_safe, sizeof(__pyx_k_safe), 0, 0, 1, 1}, + {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, + {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, + {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1}, + {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1}, + {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1}, + {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1}, + {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1}, + {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1}, + {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0}, + {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0}, + {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0}, + {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, + {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1}, + {&__pyx_n_s_sum, __pyx_k_sum, sizeof(__pyx_k_sum), 0, 0, 1, 1}, + {&__pyx_n_s_sys, __pyx_k_sys, sizeof(__pyx_k_sys), 0, 0, 1, 1}, + {&__pyx_n_s_tau_scale, __pyx_k_tau_scale, sizeof(__pyx_k_tau_scale), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_total_rate, __pyx_k_total_rate, sizeof(__pyx_k_total_rate), 0, 0, 1, 1}, + {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0}, + {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0}, + {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1}, + {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, + {&__pyx_n_s_version_info, __pyx_k_version_info, sizeof(__pyx_k_version_info), 0, 0, 1, 1}, + {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1}, + {&__pyx_n_s_x_view, __pyx_k_x_view, sizeof(__pyx_k_x_view), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} + }; + return __Pyx_InitStrings(__pyx_string_tab); +} +/* #### Code section: cached_builtins ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 35, __pyx_L1_error) + __pyx_builtin___import__ = __Pyx_GetBuiltinName(__pyx_n_s_import); if (!__pyx_builtin___import__) __PYX_ERR(1, 100, __pyx_L1_error) + __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 141, __pyx_L1_error) + __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(1, 156, __pyx_L1_error) + __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) __PYX_ERR(1, 159, __pyx_L1_error) + __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(1, 2, __pyx_L1_error) + __pyx_builtin_AssertionError = __Pyx_GetBuiltinName(__pyx_n_s_AssertionError); if (!__pyx_builtin_AssertionError) __PYX_ERR(1, 373, __pyx_L1_error) + __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) __PYX_ERR(1, 408, __pyx_L1_error) + __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(1, 618, __pyx_L1_error) + __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(1, 914, __pyx_L1_error) + __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(2, 984, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cached_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "View.MemoryView":582 + * def suboffsets(self): + * if self.view.suboffsets == NULL: + * return (-1,) * self.view.ndim # <<<<<<<<<<<<<< + * + * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) + */ + __pyx_tuple__4 = PyTuple_New(1); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 582, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_INCREF(__pyx_int_neg_1); + __Pyx_GIVEREF(__pyx_int_neg_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_tuple__4, 0, __pyx_int_neg_1)) __PYX_ERR(1, 582, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_tuple__4); + + /* "View.MemoryView":679 + * tup = index if isinstance(index, tuple) else (index,) + * + * result = [slice(None)] * ndim # <<<<<<<<<<<<<< + * have_slices = False + * seen_ellipsis = False + */ + __pyx_slice__5 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__5)) __PYX_ERR(1, 679, __pyx_L1_error) + __Pyx_GOTREF(__pyx_slice__5); + __Pyx_GIVEREF(__pyx_slice__5); + + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum not in (0x82a3537, 0x6ae9995, 0xb068931): # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum + */ + __pyx_tuple__8 = PyTuple_Pack(3, __pyx_int_136983863, __pyx_int_112105877, __pyx_int_184977713); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(1, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__8); + __Pyx_GIVEREF(__pyx_tuple__8); + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":984 + * __pyx_import_array() + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_umath() except -1: + */ + __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_multiarray_failed_to); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(2, 984, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__9); + __Pyx_GIVEREF(__pyx_tuple__9); + + /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":990 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_ufunc() except -1: + */ + __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(2, 990, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__10); + __Pyx_GIVEREF(__pyx_tuple__10); + + /* "View.MemoryView":100 + * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" + * try: + * if __import__("sys").version_info >= (3, 3): # <<<<<<<<<<<<<< + * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence + * else: + */ + __pyx_tuple__11 = PyTuple_Pack(1, __pyx_n_s_sys); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(1, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__11); + __Pyx_GIVEREF(__pyx_tuple__11); + __pyx_tuple__12 = PyTuple_Pack(2, __pyx_int_3, __pyx_int_3); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(1, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__12); + __Pyx_GIVEREF(__pyx_tuple__12); + + /* "View.MemoryView":101 + * try: + * if __import__("sys").version_info >= (3, 3): + * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence # <<<<<<<<<<<<<< + * else: + * __pyx_collections_abc_Sequence = __import__("collections").Sequence + */ + __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_collections_abc); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(1, 101, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__13); + __Pyx_GIVEREF(__pyx_tuple__13); + + /* "View.MemoryView":103 + * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence + * else: + * __pyx_collections_abc_Sequence = __import__("collections").Sequence # <<<<<<<<<<<<<< + * except: + * + */ + __pyx_tuple__14 = PyTuple_Pack(1, __pyx_n_s_collections); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(1, 103, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__14); + __Pyx_GIVEREF(__pyx_tuple__14); + + /* "View.MemoryView":309 + * return self.name + * + * cdef generic = Enum("") # <<<<<<<<<<<<<< + * cdef strided = Enum("") # default + * cdef indirect = Enum("") + */ + __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(1, 309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__15); + __Pyx_GIVEREF(__pyx_tuple__15); + + /* "View.MemoryView":310 + * + * cdef generic = Enum("") + * cdef strided = Enum("") # default # <<<<<<<<<<<<<< + * cdef indirect = Enum("") + * + */ + __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(1, 310, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__16); + __Pyx_GIVEREF(__pyx_tuple__16); + + /* "View.MemoryView":311 + * cdef generic = Enum("") + * cdef strided = Enum("") # default + * cdef indirect = Enum("") # <<<<<<<<<<<<<< + * + * + */ + __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(1, 311, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__17); + __Pyx_GIVEREF(__pyx_tuple__17); + + /* "View.MemoryView":314 + * + * + * cdef contiguous = Enum("") # <<<<<<<<<<<<<< + * cdef indirect_contiguous = Enum("") + * + */ + __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(1, 314, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__18); + __Pyx_GIVEREF(__pyx_tuple__18); + + /* "View.MemoryView":315 + * + * cdef contiguous = Enum("") + * cdef indirect_contiguous = Enum("") # <<<<<<<<<<<<<< + * + * + */ + __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(1, 315, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__19); + __Pyx_GIVEREF(__pyx_tuple__19); + + /* "(tree fragment)":1 + * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + __pyx_tuple__20 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__20); + __Pyx_GIVEREF(__pyx_tuple__20); + __pyx_codeobj__21 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_Enum, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__21)) __PYX_ERR(1, 1, __pyx_L1_error) + + /* "pygom/model/_tau_leap.pyx":8 + * cimport cython + * + * @cython.boundscheck(False) # Deactivate bounds checking # <<<<<<<<<<<<<< + * @cython.wraparound(False) # Deactivate negative indexing. + * @cython.cdivision(True) # Deactivate the div 0 error checking + */ + __pyx_tuple__22 = PyTuple_Pack(19, __pyx_n_s_x, __pyx_n_s_reactant_mat, __pyx_n_s_rates, __pyx_n_s_tau_scale, __pyx_n_s_epsilon, __pyx_n_s_rates_view, __pyx_n_s_n_rates, __pyx_n_s_x_view, __pyx_n_s_reactant_mat_view, __pyx_n_s_n_reactants, __pyx_n_s_mu, __pyx_n_s_max_cdf, __pyx_n_s_new_cdf, __pyx_n_s_total_rate, __pyx_n_s_safe, __pyx_n_s_count, __pyx_n_s_cdf_val, __pyx_n_s_i, __pyx_n_s_j); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__22); + __Pyx_GIVEREF(__pyx_tuple__22); + __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pygom_model__tau_leap_pyx, __pyx_n_s_cy_test_tau_leap_safety, 8, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitConstants(void) { + if (__Pyx_CreateStringTabAndInitStrings() < 0) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_112105877 = PyInt_FromLong(112105877L); if (unlikely(!__pyx_int_112105877)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_136983863 = PyInt_FromLong(136983863L); if (unlikely(!__pyx_int_136983863)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_184977713 = PyInt_FromLong(184977713L); if (unlikely(!__pyx_int_184977713)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) __PYX_ERR(0, 1, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_globals ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + /* AssertionsEnabled.init */ + if (likely(__Pyx_init_assertions_enabled() == 0)); else + +if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* NumpyImportArray.init */ + /* + * Cython has automatically inserted a call to _import_array since + * you didn't include one when you cimported numpy. To disable this + * add the line + * numpy._import_array + */ +#ifdef NPY_FEATURE_VERSION +#ifndef NO_IMPORT_ARRAY +if (unlikely(_import_array() == -1)) { + PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import " + "(auto-generated because you didn't call 'numpy.import_array()' after cimporting numpy; " + "use 'numpy._import_array' to disable if you are certain you don't need it)."); +} +#endif +#endif + +if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_module ### */ + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __pyx_collections_abc_Sequence = Py_None; Py_INCREF(Py_None); + generic = Py_None; Py_INCREF(Py_None); + strided = Py_None; Py_INCREF(Py_None); + indirect = Py_None; Py_INCREF(Py_None); + contiguous = Py_None; Py_INCREF(Py_None); + indirect_contiguous = Py_None; Py_INCREF(Py_None); + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __pyx_vtabptr_array = &__pyx_vtable_array; + __pyx_vtable_array.get_memview = (PyObject *(*)(struct __pyx_array_obj *))__pyx_array_get_memview; + #if CYTHON_USE_TYPE_SPECS + __pyx_array_type = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type___pyx_array_spec, NULL); if (unlikely(!__pyx_array_type)) __PYX_ERR(1, 114, __pyx_L1_error) + #if !CYTHON_COMPILING_IN_LIMITED_API + __pyx_array_type->tp_as_buffer = &__pyx_tp_as_buffer_array; + if (!__pyx_array_type->tp_as_buffer->bf_releasebuffer && __pyx_array_type->tp_base->tp_as_buffer && __pyx_array_type->tp_base->tp_as_buffer->bf_releasebuffer) { + __pyx_array_type->tp_as_buffer->bf_releasebuffer = __pyx_array_type->tp_base->tp_as_buffer->bf_releasebuffer; + } + #elif defined(Py_bf_getbuffer) && defined(Py_bf_releasebuffer) + /* PY_VERSION_HEX >= 0x03090000 || Py_LIMITED_API >= 0x030B0000 */ + #elif defined(_MSC_VER) + #pragma message ("The buffer protocol is not supported in the Limited C-API < 3.11.") + #else + #warning "The buffer protocol is not supported in the Limited C-API < 3.11." + #endif + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type___pyx_array_spec, __pyx_array_type) < 0) __PYX_ERR(1, 114, __pyx_L1_error) + #else + __pyx_array_type = &__pyx_type___pyx_array; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_array_type) < 0) __PYX_ERR(1, 114, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_array_type->tp_print = 0; + #endif + if (__Pyx_SetVtable(__pyx_array_type, __pyx_vtabptr_array) < 0) __PYX_ERR(1, 114, __pyx_L1_error) + #if !CYTHON_COMPILING_IN_LIMITED_API + if (__Pyx_MergeVtables(__pyx_array_type) < 0) __PYX_ERR(1, 114, __pyx_L1_error) + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if (__Pyx_setup_reduce((PyObject *) __pyx_array_type) < 0) __PYX_ERR(1, 114, __pyx_L1_error) + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_MemviewEnum_type = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type___pyx_MemviewEnum_spec, NULL); if (unlikely(!__pyx_MemviewEnum_type)) __PYX_ERR(1, 302, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type___pyx_MemviewEnum_spec, __pyx_MemviewEnum_type) < 0) __PYX_ERR(1, 302, __pyx_L1_error) + #else + __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_MemviewEnum_type) < 0) __PYX_ERR(1, 302, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_MemviewEnum_type->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_MemviewEnum_type->tp_dictoffset && __pyx_MemviewEnum_type->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_MemviewEnum_type->tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if (__Pyx_setup_reduce((PyObject *) __pyx_MemviewEnum_type) < 0) __PYX_ERR(1, 302, __pyx_L1_error) + #endif + __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview; + __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer; + __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice; + __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment; + __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar; + __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed; + __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object; + __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object; + __pyx_vtable_memoryview._get_base = (PyObject *(*)(struct __pyx_memoryview_obj *))__pyx_memoryview__get_base; + #if CYTHON_USE_TYPE_SPECS + __pyx_memoryview_type = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type___pyx_memoryview_spec, NULL); if (unlikely(!__pyx_memoryview_type)) __PYX_ERR(1, 337, __pyx_L1_error) + #if !CYTHON_COMPILING_IN_LIMITED_API + __pyx_memoryview_type->tp_as_buffer = &__pyx_tp_as_buffer_memoryview; + if (!__pyx_memoryview_type->tp_as_buffer->bf_releasebuffer && __pyx_memoryview_type->tp_base->tp_as_buffer && __pyx_memoryview_type->tp_base->tp_as_buffer->bf_releasebuffer) { + __pyx_memoryview_type->tp_as_buffer->bf_releasebuffer = __pyx_memoryview_type->tp_base->tp_as_buffer->bf_releasebuffer; + } + #elif defined(Py_bf_getbuffer) && defined(Py_bf_releasebuffer) + /* PY_VERSION_HEX >= 0x03090000 || Py_LIMITED_API >= 0x030B0000 */ + #elif defined(_MSC_VER) + #pragma message ("The buffer protocol is not supported in the Limited C-API < 3.11.") + #else + #warning "The buffer protocol is not supported in the Limited C-API < 3.11." + #endif + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type___pyx_memoryview_spec, __pyx_memoryview_type) < 0) __PYX_ERR(1, 337, __pyx_L1_error) + #else + __pyx_memoryview_type = &__pyx_type___pyx_memoryview; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_memoryview_type) < 0) __PYX_ERR(1, 337, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_memoryview_type->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_memoryview_type->tp_dictoffset && __pyx_memoryview_type->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_memoryview_type->tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + #endif + if (__Pyx_SetVtable(__pyx_memoryview_type, __pyx_vtabptr_memoryview) < 0) __PYX_ERR(1, 337, __pyx_L1_error) + #if !CYTHON_COMPILING_IN_LIMITED_API + if (__Pyx_MergeVtables(__pyx_memoryview_type) < 0) __PYX_ERR(1, 337, __pyx_L1_error) + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if (__Pyx_setup_reduce((PyObject *) __pyx_memoryview_type) < 0) __PYX_ERR(1, 337, __pyx_L1_error) + #endif + __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice; + __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview; + __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object; + __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object; + __pyx_vtable__memoryviewslice.__pyx_base._get_base = (PyObject *(*)(struct __pyx_memoryview_obj *))__pyx_memoryviewslice__get_base; + #if CYTHON_USE_TYPE_SPECS + __pyx_t_1 = PyTuple_Pack(1, (PyObject *)__pyx_memoryview_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 952, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_memoryviewslice_type = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type___pyx_memoryviewslice_spec, __pyx_t_1); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_memoryviewslice_type)) __PYX_ERR(1, 952, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type___pyx_memoryviewslice_spec, __pyx_memoryviewslice_type) < 0) __PYX_ERR(1, 952, __pyx_L1_error) + #else + __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + __pyx_memoryviewslice_type->tp_base = __pyx_memoryview_type; + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_memoryviewslice_type) < 0) __PYX_ERR(1, 952, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_memoryviewslice_type->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_memoryviewslice_type->tp_dictoffset && __pyx_memoryviewslice_type->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_memoryviewslice_type->tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + #endif + if (__Pyx_SetVtable(__pyx_memoryviewslice_type, __pyx_vtabptr__memoryviewslice) < 0) __PYX_ERR(1, 952, __pyx_L1_error) + #if !CYTHON_COMPILING_IN_LIMITED_API + if (__Pyx_MergeVtables(__pyx_memoryviewslice_type) < 0) __PYX_ERR(1, 952, __pyx_L1_error) + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if (__Pyx_setup_reduce((PyObject *) __pyx_memoryviewslice_type) < 0) __PYX_ERR(1, 952, __pyx_L1_error) + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType_3_0_10(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", + #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 + sizeof(PyTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyTypeObject), + #elif CYTHON_COMPILING_IN_LIMITED_API + sizeof(PyTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyTypeObject), + #else + sizeof(PyHeapTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyHeapTypeObject), + #endif + __Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(3, 9, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule("numpy"); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 202, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_5numpy_dtype = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "dtype", sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArray_Descr),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_dtype) __PYX_ERR(2, 202, __pyx_L1_error) + __pyx_ptype_5numpy_flatiter = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "flatiter", sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayIterObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_flatiter) __PYX_ERR(2, 225, __pyx_L1_error) + __pyx_ptype_5numpy_broadcast = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "broadcast", sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayMultiIterObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_broadcast) __PYX_ERR(2, 229, __pyx_L1_error) + __pyx_ptype_5numpy_ndarray = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "ndarray", sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_ndarray) __PYX_ERR(2, 238, __pyx_L1_error) + __pyx_ptype_5numpy_generic = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "generic", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_generic) __PYX_ERR(2, 809, __pyx_L1_error) + __pyx_ptype_5numpy_number = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "number", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_number) __PYX_ERR(2, 811, __pyx_L1_error) + __pyx_ptype_5numpy_integer = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "integer", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_integer) __PYX_ERR(2, 813, __pyx_L1_error) + __pyx_ptype_5numpy_signedinteger = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "signedinteger", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_signedinteger) __PYX_ERR(2, 815, __pyx_L1_error) + __pyx_ptype_5numpy_unsignedinteger = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "unsignedinteger", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_unsignedinteger) __PYX_ERR(2, 817, __pyx_L1_error) + __pyx_ptype_5numpy_inexact = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "inexact", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_inexact) __PYX_ERR(2, 819, __pyx_L1_error) + __pyx_ptype_5numpy_floating = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "floating", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_floating) __PYX_ERR(2, 821, __pyx_L1_error) + __pyx_ptype_5numpy_complexfloating = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "complexfloating", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_complexfloating) __PYX_ERR(2, 823, __pyx_L1_error) + __pyx_ptype_5numpy_flexible = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "flexible", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_flexible) __PYX_ERR(2, 825, __pyx_L1_error) + __pyx_ptype_5numpy_character = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "character", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_character) __PYX_ERR(2, 827, __pyx_L1_error) + __pyx_ptype_5numpy_ufunc = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "ufunc", sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyUFuncObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_ufunc) __PYX_ERR(2, 866, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __pyx_t_1 = PyImport_ImportModule("scipy.special.cython_special"); if (!__pyx_t_1) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_ImportFunction_3_0_10(__pyx_t_1, "pdtr", (void (**)(void))&__pyx_f_5scipy_7special_14cython_special_pdtr, "double (double, double, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_RefNannyFinishContext(); + return -1; +} + + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec__tau_leap(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec__tau_leap}, + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "_tau_leap", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #elif CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstate), /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif +#endif + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC init_tau_leap(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC init_tau_leap(void) +#else +__Pyx_PyMODINIT_FUNC PyInit__tau_leap(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit__tau_leap(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none) +#else +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +#endif +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { +#if CYTHON_COMPILING_IN_LIMITED_API + result = PyModule_AddObject(module, to_name, value); +#else + result = PyDict_SetItemString(moddict, to_name, value); +#endif + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; +#if CYTHON_COMPILING_IN_LIMITED_API + moddict = module; +#else + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; +#endif + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec__tau_leap(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + static PyThread_type_lock __pyx_t_8[8]; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_tau_leap' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("_tau_leap", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #elif CYTHON_USE_MODULE_STATE + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + { + int add_module_result = PyState_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "_tau_leap" pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #endif + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_cython_runtime = __Pyx_PyImport_AddModuleRef((const char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__tau_leap(void)", 0); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + PyEval_InitThreads(); + #endif + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_pygom__model___tau_leap) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name_2, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "pygom.model._tau_leap")) { + if (unlikely((PyDict_SetItemString(modules, "pygom.model._tau_leap", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + if (unlikely((__Pyx_modinit_type_init_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + if (unlikely((__Pyx_modinit_type_import_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_variable_import_code(); + if (unlikely((__Pyx_modinit_function_import_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "View.MemoryView":99 + * + * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" + * try: # <<<<<<<<<<<<<< + * if __import__("sys").version_info >= (3, 3): + * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "View.MemoryView":100 + * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" + * try: + * if __import__("sys").version_info >= (3, 3): # <<<<<<<<<<<<<< + * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence + * else: + */ + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 100, __pyx_L2_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_version_info); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 100, __pyx_L2_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_tuple__12, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 100, __pyx_L2_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(1, 100, __pyx_L2_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + + /* "View.MemoryView":101 + * try: + * if __import__("sys").version_info >= (3, 3): + * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence # <<<<<<<<<<<<<< + * else: + * __pyx_collections_abc_Sequence = __import__("collections").Sequence + */ + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 101, __pyx_L2_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_abc); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 101, __pyx_L2_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_Sequence); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 101, __pyx_L2_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XGOTREF(__pyx_collections_abc_Sequence); + __Pyx_DECREF_SET(__pyx_collections_abc_Sequence, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + + /* "View.MemoryView":100 + * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" + * try: + * if __import__("sys").version_info >= (3, 3): # <<<<<<<<<<<<<< + * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence + * else: + */ + goto __pyx_L8; + } + + /* "View.MemoryView":103 + * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence + * else: + * __pyx_collections_abc_Sequence = __import__("collections").Sequence # <<<<<<<<<<<<<< + * except: + * + */ + /*else*/ { + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 103, __pyx_L2_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Sequence); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 103, __pyx_L2_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XGOTREF(__pyx_collections_abc_Sequence); + __Pyx_DECREF_SET(__pyx_collections_abc_Sequence, __pyx_t_5); + __Pyx_GIVEREF(__pyx_t_5); + __pyx_t_5 = 0; + } + __pyx_L8:; + + /* "View.MemoryView":99 + * + * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" + * try: # <<<<<<<<<<<<<< + * if __import__("sys").version_info >= (3, 3): + * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L7_try_end; + __pyx_L2_error:; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "View.MemoryView":104 + * else: + * __pyx_collections_abc_Sequence = __import__("collections").Sequence + * except: # <<<<<<<<<<<<<< + * + * __pyx_collections_abc_Sequence = None + */ + /*except:*/ { + __Pyx_AddTraceback("View.MemoryView", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_4, &__pyx_t_7) < 0) __PYX_ERR(1, 104, __pyx_L4_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_7); + + /* "View.MemoryView":106 + * except: + * + * __pyx_collections_abc_Sequence = None # <<<<<<<<<<<<<< + * + * + */ + __Pyx_INCREF(Py_None); + __Pyx_XGOTREF(__pyx_collections_abc_Sequence); + __Pyx_DECREF_SET(__pyx_collections_abc_Sequence, Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L3_exception_handled; + } + + /* "View.MemoryView":99 + * + * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" + * try: # <<<<<<<<<<<<<< + * if __import__("sys").version_info >= (3, 3): + * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence + */ + __pyx_L4_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L3_exception_handled:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + __pyx_L7_try_end:; + } + + /* "View.MemoryView":241 + * + * + * try: # <<<<<<<<<<<<<< + * count = __pyx_collections_abc_Sequence.count + * index = __pyx_collections_abc_Sequence.index + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_2, &__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_1); + /*try:*/ { + + /* "View.MemoryView":242 + * + * try: + * count = __pyx_collections_abc_Sequence.count # <<<<<<<<<<<<<< + * index = __pyx_collections_abc_Sequence.index + * except: + */ + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_count); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 242, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_SetItemOnTypeDict(__pyx_array_type, __pyx_n_s_count, __pyx_t_7) < 0) __PYX_ERR(1, 242, __pyx_L11_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + PyType_Modified(__pyx_array_type); + + /* "View.MemoryView":243 + * try: + * count = __pyx_collections_abc_Sequence.count + * index = __pyx_collections_abc_Sequence.index # <<<<<<<<<<<<<< + * except: + * pass + */ + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_index); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 243, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_SetItemOnTypeDict(__pyx_array_type, __pyx_n_s_index, __pyx_t_7) < 0) __PYX_ERR(1, 243, __pyx_L11_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + PyType_Modified(__pyx_array_type); + + /* "View.MemoryView":241 + * + * + * try: # <<<<<<<<<<<<<< + * count = __pyx_collections_abc_Sequence.count + * index = __pyx_collections_abc_Sequence.index + */ + } + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L16_try_end; + __pyx_L11_error:; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "View.MemoryView":244 + * count = __pyx_collections_abc_Sequence.count + * index = __pyx_collections_abc_Sequence.index + * except: # <<<<<<<<<<<<<< + * pass + * + */ + /*except:*/ { + __Pyx_ErrRestore(0,0,0); + goto __pyx_L12_exception_handled; + } + __pyx_L12_exception_handled:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_2, __pyx_t_1); + __pyx_L16_try_end:; + } + + /* "View.MemoryView":309 + * return self.name + * + * cdef generic = Enum("") # <<<<<<<<<<<<<< + * cdef strided = Enum("") # default + * cdef indirect = Enum("") + */ + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_XGOTREF(generic); + __Pyx_DECREF_SET(generic, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_7); + __pyx_t_7 = 0; + + /* "View.MemoryView":310 + * + * cdef generic = Enum("") + * cdef strided = Enum("") # default # <<<<<<<<<<<<<< + * cdef indirect = Enum("") + * + */ + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 310, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_XGOTREF(strided); + __Pyx_DECREF_SET(strided, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_7); + __pyx_t_7 = 0; + + /* "View.MemoryView":311 + * cdef generic = Enum("") + * cdef strided = Enum("") # default + * cdef indirect = Enum("") # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 311, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_XGOTREF(indirect); + __Pyx_DECREF_SET(indirect, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_7); + __pyx_t_7 = 0; + + /* "View.MemoryView":314 + * + * + * cdef contiguous = Enum("") # <<<<<<<<<<<<<< + * cdef indirect_contiguous = Enum("") + * + */ + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 314, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_XGOTREF(contiguous); + __Pyx_DECREF_SET(contiguous, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_7); + __pyx_t_7 = 0; + + /* "View.MemoryView":315 + * + * cdef contiguous = Enum("") + * cdef indirect_contiguous = Enum("") # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 315, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_XGOTREF(indirect_contiguous); + __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_7); + __pyx_t_7 = 0; + + /* "View.MemoryView":323 + * + * + * cdef int __pyx_memoryview_thread_locks_used = 0 # <<<<<<<<<<<<<< + * cdef PyThread_type_lock[8] __pyx_memoryview_thread_locks = [ + * PyThread_allocate_lock(), + */ + __pyx_memoryview_thread_locks_used = 0; + + /* "View.MemoryView":324 + * + * cdef int __pyx_memoryview_thread_locks_used = 0 + * cdef PyThread_type_lock[8] __pyx_memoryview_thread_locks = [ # <<<<<<<<<<<<<< + * PyThread_allocate_lock(), + * PyThread_allocate_lock(), + */ + __pyx_t_8[0] = PyThread_allocate_lock(); + __pyx_t_8[1] = PyThread_allocate_lock(); + __pyx_t_8[2] = PyThread_allocate_lock(); + __pyx_t_8[3] = PyThread_allocate_lock(); + __pyx_t_8[4] = PyThread_allocate_lock(); + __pyx_t_8[5] = PyThread_allocate_lock(); + __pyx_t_8[6] = PyThread_allocate_lock(); + __pyx_t_8[7] = PyThread_allocate_lock(); + memcpy(&(__pyx_memoryview_thread_locks[0]), __pyx_t_8, sizeof(__pyx_memoryview_thread_locks[0]) * (8)); + + /* "View.MemoryView":982 + * + * + * try: # <<<<<<<<<<<<<< + * count = __pyx_collections_abc_Sequence.count + * index = __pyx_collections_abc_Sequence.index + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "View.MemoryView":983 + * + * try: + * count = __pyx_collections_abc_Sequence.count # <<<<<<<<<<<<<< + * index = __pyx_collections_abc_Sequence.index + * except: + */ + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_count); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 983, __pyx_L17_error) + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_SetItemOnTypeDict(__pyx_memoryviewslice_type, __pyx_n_s_count, __pyx_t_7) < 0) __PYX_ERR(1, 983, __pyx_L17_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + PyType_Modified(__pyx_memoryviewslice_type); + + /* "View.MemoryView":984 + * try: + * count = __pyx_collections_abc_Sequence.count + * index = __pyx_collections_abc_Sequence.index # <<<<<<<<<<<<<< + * except: + * pass + */ + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_index); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 984, __pyx_L17_error) + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_SetItemOnTypeDict(__pyx_memoryviewslice_type, __pyx_n_s_index, __pyx_t_7) < 0) __PYX_ERR(1, 984, __pyx_L17_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + PyType_Modified(__pyx_memoryviewslice_type); + + /* "View.MemoryView":982 + * + * + * try: # <<<<<<<<<<<<<< + * count = __pyx_collections_abc_Sequence.count + * index = __pyx_collections_abc_Sequence.index + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L22_try_end; + __pyx_L17_error:; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "View.MemoryView":985 + * count = __pyx_collections_abc_Sequence.count + * index = __pyx_collections_abc_Sequence.index + * except: # <<<<<<<<<<<<<< + * pass + * + */ + /*except:*/ { + __Pyx_ErrRestore(0,0,0); + goto __pyx_L18_exception_handled; + } + __pyx_L18_exception_handled:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + __pyx_L22_try_end:; + } + + /* "View.MemoryView":988 + * pass + * + * try: # <<<<<<<<<<<<<< + * if __pyx_collections_abc_Sequence: + * + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_2, &__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_1); + /*try:*/ { + + /* "View.MemoryView":989 + * + * try: + * if __pyx_collections_abc_Sequence: # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_collections_abc_Sequence); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(1, 989, __pyx_L23_error) + if (__pyx_t_6) { + + /* "View.MemoryView":993 + * + * + * __pyx_collections_abc_Sequence.register(_memoryviewslice) # <<<<<<<<<<<<<< + * __pyx_collections_abc_Sequence.register(array) + * except: + */ + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_register); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 993, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_7, ((PyObject *)__pyx_memoryviewslice_type)); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 993, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "View.MemoryView":994 + * + * __pyx_collections_abc_Sequence.register(_memoryviewslice) + * __pyx_collections_abc_Sequence.register(array) # <<<<<<<<<<<<<< + * except: + * pass # ignore failure, it's a minor issue + */ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_register); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 994, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_4, ((PyObject *)__pyx_array_type)); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 994, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "View.MemoryView":989 + * + * try: + * if __pyx_collections_abc_Sequence: # <<<<<<<<<<<<<< + * + * + */ + } + + /* "View.MemoryView":988 + * pass + * + * try: # <<<<<<<<<<<<<< + * if __pyx_collections_abc_Sequence: + * + */ + } + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L28_try_end; + __pyx_L23_error:; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "View.MemoryView":995 + * __pyx_collections_abc_Sequence.register(_memoryviewslice) + * __pyx_collections_abc_Sequence.register(array) + * except: # <<<<<<<<<<<<<< + * pass # ignore failure, it's a minor issue + * + */ + /*except:*/ { + __Pyx_ErrRestore(0,0,0); + goto __pyx_L24_exception_handled; + } + __pyx_L24_exception_handled:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_2, __pyx_t_1); + __pyx_L28_try_end:; + } + + /* "(tree fragment)":1 + * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + __pyx_t_7 = PyCFunction_NewEx(&__pyx_mdef_15View_dot_MemoryView_1__pyx_unpickle_Enum, NULL, __pyx_n_s_View_MemoryView); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_Enum, __pyx_t_7) < 0) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "pygom/model/_tau_leap.pyx":1 + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * + */ + __pyx_t_7 = __Pyx_ImportDottedModule(__pyx_n_s_numpy, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_7) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "pygom/model/_tau_leap.pyx":8 + * cimport cython + * + * @cython.boundscheck(False) # Deactivate bounds checking # <<<<<<<<<<<<<< + * @cython.wraparound(False) # Deactivate negative indexing. + * @cython.cdivision(True) # Deactivate the div 0 error checking + */ + __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety, 0, __pyx_n_s_cy_test_tau_leap_safety, NULL, __pyx_n_s_pygom_model__tau_leap, __pyx_d, ((PyObject *)__pyx_codeobj__23)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_cy_test_tau_leap_safety, __pyx_t_7) < 0) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "pygom/model/_tau_leap.pyx":1 + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * + */ + __pyx_t_7 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_7) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_7); + if (__pyx_m) { + if (__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init pygom.model._tau_leap", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init pygom.model._tau_leap"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* TupleAndListFromArray */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + Py_INCREF(__pyx_empty_tuple); + return __pyx_empty_tuple; + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames); + for (i = 0; i < n; i++) + { + if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; + return kwvalues[i]; + } + } + return NULL; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs = PyTuple_GET_SIZE(kwnames); + PyObject *dict; + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; i= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds)); + while (1) { + Py_XDECREF(key); key = NULL; + Py_XDECREF(value); value = NULL; + if (kwds_is_tuple) { + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(kwds); +#else + size = PyTuple_Size(kwds); + if (size < 0) goto bad; +#endif + if (pos >= size) break; +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); + if (!key) goto bad; +#elif CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kwds, pos); +#else + key = PyTuple_GetItem(kwds, pos); + if (!key) goto bad; +#endif + value = kwvalues[pos]; + pos++; + } + else + { + if (!PyDict_Next(kwds, &pos, &key, &value)) break; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + } + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(value); + Py_DECREF(key); +#endif + key = NULL; + value = NULL; + continue; + } +#if !CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + Py_INCREF(value); + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; +#endif + break; + } + name++; + } + if (*name) continue; else { PyObject*** argname = argnames; while (argname != first_kw_arg) { @@ -19337,14 +23028,18 @@ static int __Pyx_ParseOptionalKeywords( #endif if (likely(PyUnicode_Check(key))) { while (*name) { - int cmp = (**name == key) ? 0 : + int cmp = ( #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : #endif - PyUnicode_Compare(**name, key); + PyUnicode_Compare(**name, key) + ); if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; if (cmp == 0) { values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; +#endif break; } name++; @@ -19363,2395 +23058,4327 @@ static int __Pyx_ParseOptionalKeywords( argname++; } } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + Py_XDECREF(key); + Py_XDECREF(value); + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + #if PY_MAJOR_VERSION < 3 + PyErr_Format(PyExc_TypeError, + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + Py_XDECREF(key); + Py_XDECREF(value); + return -1; +} + +/* ArgTypeTest */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +{ + __Pyx_TypeName type_name; + __Pyx_TypeName obj_type_name; + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + else if (exact) { + #if PY_MAJOR_VERSION == 2 + if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(__Pyx_TypeCheck(obj, type))) return 1; + } + type_name = __Pyx_PyType_GetName(type); + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected " __Pyx_FMT_TYPENAME + ", got " __Pyx_FMT_TYPENAME ")", name, type_name, obj_type_name); + __Pyx_DECREF_TypeName(type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return 0; +} + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + __Pyx_PyThreadState_declare + CYTHON_UNUSED_VAR(cause); + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); } else { - goto invalid_keyword; + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { + #if PY_VERSION_HEX >= 0x030C00A6 + PyException_SetTraceback(value, tb); + #elif CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) { + return NULL; + } + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) { + return NULL; + } + #endif + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = Py_TYPE(func)->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) < 0) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + #if PY_VERSION_HEX < 0x030800B1 + #if CYTHON_FAST_PYCCALL + if (PyCFunction_Check(func)) { + if (kwargs) { + return _PyCFunction_FastCallDict(func, args, nargs, kwargs); + } else { + return _PyCFunction_FastCallKeywords(func, args, nargs, NULL); + } + } + #if PY_VERSION_HEX >= 0x030700A1 + if (!kwargs && __Pyx_IS_TYPE(func, &PyMethodDescr_Type)) { + return _PyMethodDescr_FastCallKeywords(func, args, nargs, NULL); + } + #endif + #endif + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs); + } + #endif + #endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if PY_VERSION_HEX < 0x03090000 + vectorcallfunc f = _PyVectorcall_Function(func); + #else + vectorcallfunc f = PyVectorcall_Function(func); + #endif + if (f) { + return f(func, args, (size_t)nargs, NULL); } + #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL + if (__Pyx_CyFunction_CheckExact(func)) { + __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func); + if (f) return f(func, args, (size_t)nargs, NULL); + } + #endif } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); #endif -bad: - return -1; } -/* ArgTypeTest */ -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +/* RaiseUnexpectedTypeError */ +static int +__Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj) { - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; + __Pyx_TypeName obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, "Expected %s, got " __Pyx_FMT_TYPENAME, + expected, obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return 0; +} + +/* CIntToDigits */ +static const char DIGIT_PAIRS_10[2*10*10+1] = { + "00010203040506070809" + "10111213141516171819" + "20212223242526272829" + "30313233343536373839" + "40414243444546474849" + "50515253545556575859" + "60616263646566676869" + "70717273747576777879" + "80818283848586878889" + "90919293949596979899" +}; +static const char DIGIT_PAIRS_8[2*8*8+1] = { + "0001020304050607" + "1011121314151617" + "2021222324252627" + "3031323334353637" + "4041424344454647" + "5051525354555657" + "6061626364656667" + "7071727374757677" +}; +static const char DIGITS_HEX[2*16+1] = { + "0123456789abcdef" + "0123456789ABCDEF" +}; + +/* BuildPyUnicode */ +static PyObject* __Pyx_PyUnicode_BuildFromAscii(Py_ssize_t ulength, char* chars, int clength, + int prepend_sign, char padding_char) { + PyObject *uval; + Py_ssize_t uoffset = ulength - clength; +#if CYTHON_USE_UNICODE_INTERNALS + Py_ssize_t i; +#if CYTHON_PEP393_ENABLED + void *udata; + uval = PyUnicode_New(ulength, 127); + if (unlikely(!uval)) return NULL; + udata = PyUnicode_DATA(uval); +#else + Py_UNICODE *udata; + uval = PyUnicode_FromUnicode(NULL, ulength); + if (unlikely(!uval)) return NULL; + udata = PyUnicode_AS_UNICODE(uval); +#endif + if (uoffset > 0) { + i = 0; + if (prepend_sign) { + __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, 0, '-'); + i++; + } + for (; i < uoffset; i++) { + __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, i, padding_char); + } } - else if (exact) { - #if PY_MAJOR_VERSION == 2 - if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; - #endif + for (i=0; i < clength; i++) { + __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, uoffset+i, chars[i]); } - else { - if (likely(__Pyx_TypeCheck(obj, type))) return 1; +#else + { + PyObject *sign = NULL, *padding = NULL; + uval = NULL; + if (uoffset > 0) { + prepend_sign = !!prepend_sign; + if (uoffset > prepend_sign) { + padding = PyUnicode_FromOrdinal(padding_char); + if (likely(padding) && uoffset > prepend_sign + 1) { + PyObject *tmp; + PyObject *repeat = PyInt_FromSsize_t(uoffset - prepend_sign); + if (unlikely(!repeat)) goto done_or_error; + tmp = PyNumber_Multiply(padding, repeat); + Py_DECREF(repeat); + Py_DECREF(padding); + padding = tmp; + } + if (unlikely(!padding)) goto done_or_error; + } + if (prepend_sign) { + sign = PyUnicode_FromOrdinal('-'); + if (unlikely(!sign)) goto done_or_error; + } + } + uval = PyUnicode_DecodeASCII(chars, clength, NULL); + if (likely(uval) && padding) { + PyObject *tmp = PyNumber_Add(padding, uval); + Py_DECREF(uval); + uval = tmp; + } + if (likely(uval) && sign) { + PyObject *tmp = PyNumber_Add(sign, uval); + Py_DECREF(uval); + uval = tmp; + } +done_or_error: + Py_XDECREF(padding); + Py_XDECREF(sign); } - PyErr_Format(PyExc_TypeError, - "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", - name, type->tp_name, Py_TYPE(obj)->tp_name); - return 0; +#endif + return uval; } -/* IsLittleEndian */ -static CYTHON_INLINE int __Pyx_Is_Little_Endian(void) -{ - union { - uint32_t u32; - uint8_t u8[4]; - } S; - S.u32 = 0x01020304; - return S.u8[0] == 4; +/* CIntToPyUnicode */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_int(int value, Py_ssize_t width, char padding_char, char format_char) { + char digits[sizeof(int)*3+2]; + char *dpos, *end = digits + sizeof(int)*3+2; + const char *hex_digits = DIGITS_HEX; + Py_ssize_t length, ulength; + int prepend_sign, last_one_off; + int remaining; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (format_char == 'X') { + hex_digits += 16; + format_char = 'x'; + } + remaining = value; + last_one_off = 0; + dpos = end; + do { + int digit_pos; + switch (format_char) { + case 'o': + digit_pos = abs((int)(remaining % (8*8))); + remaining = (int) (remaining / (8*8)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); + last_one_off = (digit_pos < 8); + break; + case 'd': + digit_pos = abs((int)(remaining % (10*10))); + remaining = (int) (remaining / (10*10)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); + last_one_off = (digit_pos < 10); + break; + case 'x': + *(--dpos) = hex_digits[abs((int)(remaining % 16))]; + remaining = (int) (remaining / 16); + break; + default: + assert(0); + break; + } + } while (unlikely(remaining != 0)); + assert(!last_one_off || *dpos == '0'); + dpos += last_one_off; + length = end - dpos; + ulength = length; + prepend_sign = 0; + if (!is_unsigned && value <= neg_one) { + if (padding_char == ' ' || width <= length + 1) { + *(--dpos) = '-'; + ++length; + } else { + prepend_sign = 1; + } + ++ulength; + } + if (width > ulength) { + ulength = width; + } + if (ulength == 1) { + return PyUnicode_FromOrdinal(*dpos); + } + return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); } -/* BufferFormatCheck */ -static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, - __Pyx_BufFmt_StackElem* stack, - __Pyx_TypeInfo* type) { - stack[0].field = &ctx->root; - stack[0].parent_offset = 0; - ctx->root.type = type; - ctx->root.name = "buffer dtype"; - ctx->root.offset = 0; - ctx->head = stack; - ctx->head->field = &ctx->root; - ctx->fmt_offset = 0; - ctx->head->parent_offset = 0; - ctx->new_packmode = '@'; - ctx->enc_packmode = '@'; - ctx->new_count = 1; - ctx->enc_count = 0; - ctx->enc_type = 0; - ctx->is_complex = 0; - ctx->is_valid_array = 0; - ctx->struct_alignment = 0; - while (type->typegroup == 'S') { - ++ctx->head; - ctx->head->field = type->fields; - ctx->head->parent_offset = 0; - type = type->fields->type; - } -} -static int __Pyx_BufFmt_ParseNumber(const char** ts) { - int count; - const char* t = *ts; - if (*t < '0' || *t > '9') { - return -1; - } else { - count = *t++ - '0'; - while (*t >= '0' && *t <= '9') { - count *= 10; - count += *t++ - '0'; +/* CIntToPyUnicode */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_Py_ssize_t(Py_ssize_t value, Py_ssize_t width, char padding_char, char format_char) { + char digits[sizeof(Py_ssize_t)*3+2]; + char *dpos, *end = digits + sizeof(Py_ssize_t)*3+2; + const char *hex_digits = DIGITS_HEX; + Py_ssize_t length, ulength; + int prepend_sign, last_one_off; + Py_ssize_t remaining; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const Py_ssize_t neg_one = (Py_ssize_t) -1, const_zero = (Py_ssize_t) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (format_char == 'X') { + hex_digits += 16; + format_char = 'x'; + } + remaining = value; + last_one_off = 0; + dpos = end; + do { + int digit_pos; + switch (format_char) { + case 'o': + digit_pos = abs((int)(remaining % (8*8))); + remaining = (Py_ssize_t) (remaining / (8*8)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); + last_one_off = (digit_pos < 8); + break; + case 'd': + digit_pos = abs((int)(remaining % (10*10))); + remaining = (Py_ssize_t) (remaining / (10*10)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); + last_one_off = (digit_pos < 10); + break; + case 'x': + *(--dpos) = hex_digits[abs((int)(remaining % 16))]; + remaining = (Py_ssize_t) (remaining / 16); + break; + default: + assert(0); + break; + } + } while (unlikely(remaining != 0)); + assert(!last_one_off || *dpos == '0'); + dpos += last_one_off; + length = end - dpos; + ulength = length; + prepend_sign = 0; + if (!is_unsigned && value <= neg_one) { + if (padding_char == ' ' || width <= length + 1) { + *(--dpos) = '-'; + ++length; + } else { + prepend_sign = 1; + } + ++ulength; + } + if (width > ulength) { + ulength = width; + } + if (ulength == 1) { + return PyUnicode_FromOrdinal(*dpos); + } + return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); +} + +/* JoinPyUnicode */ +static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength, + Py_UCS4 max_char) { +#if CYTHON_USE_UNICODE_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + PyObject *result_uval; + int result_ukind, kind_shift; + Py_ssize_t i, char_pos; + void *result_udata; + CYTHON_MAYBE_UNUSED_VAR(max_char); +#if CYTHON_PEP393_ENABLED + result_uval = PyUnicode_New(result_ulength, max_char); + if (unlikely(!result_uval)) return NULL; + result_ukind = (max_char <= 255) ? PyUnicode_1BYTE_KIND : (max_char <= 65535) ? PyUnicode_2BYTE_KIND : PyUnicode_4BYTE_KIND; + kind_shift = (result_ukind == PyUnicode_4BYTE_KIND) ? 2 : result_ukind - 1; + result_udata = PyUnicode_DATA(result_uval); +#else + result_uval = PyUnicode_FromUnicode(NULL, result_ulength); + if (unlikely(!result_uval)) return NULL; + result_ukind = sizeof(Py_UNICODE); + kind_shift = (result_ukind == 4) ? 2 : result_ukind - 1; + result_udata = PyUnicode_AS_UNICODE(result_uval); +#endif + assert(kind_shift == 2 || kind_shift == 1 || kind_shift == 0); + char_pos = 0; + for (i=0; i < value_count; i++) { + int ukind; + Py_ssize_t ulength; + void *udata; + PyObject *uval = PyTuple_GET_ITEM(value_tuple, i); + if (unlikely(__Pyx_PyUnicode_READY(uval))) + goto bad; + ulength = __Pyx_PyUnicode_GET_LENGTH(uval); + if (unlikely(!ulength)) + continue; + if (unlikely((PY_SSIZE_T_MAX >> kind_shift) - ulength < char_pos)) + goto overflow; + ukind = __Pyx_PyUnicode_KIND(uval); + udata = __Pyx_PyUnicode_DATA(uval); + if (!CYTHON_PEP393_ENABLED || ukind == result_ukind) { + memcpy((char *)result_udata + (char_pos << kind_shift), udata, (size_t) (ulength << kind_shift)); + } else { + #if PY_VERSION_HEX >= 0x030d0000 + if (unlikely(PyUnicode_CopyCharacters(result_uval, char_pos, uval, 0, ulength) < 0)) goto bad; + #elif CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030300F0 || defined(_PyUnicode_FastCopyCharacters) + _PyUnicode_FastCopyCharacters(result_uval, char_pos, uval, 0, ulength); + #else + Py_ssize_t j; + for (j=0; j < ulength; j++) { + Py_UCS4 uchar = __Pyx_PyUnicode_READ(ukind, udata, j); + __Pyx_PyUnicode_WRITE(result_ukind, result_udata, char_pos+j, uchar); + } + #endif } + char_pos += ulength; } - *ts = t; - return count; + return result_uval; +overflow: + PyErr_SetString(PyExc_OverflowError, "join() result is too long for a Python string"); +bad: + Py_DECREF(result_uval); + return NULL; +#else + CYTHON_UNUSED_VAR(max_char); + CYTHON_UNUSED_VAR(result_ulength); + CYTHON_UNUSED_VAR(value_count); + return PyUnicode_Join(__pyx_empty_unicode, value_tuple); +#endif } -static int __Pyx_BufFmt_ExpectNumber(const char **ts) { - int number = __Pyx_BufFmt_ParseNumber(ts); - if (number == -1) - PyErr_Format(PyExc_ValueError,\ - "Does not understand character buffer dtype format string ('%c')", **ts); - return number; + +/* GetAttr */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { +#if CYTHON_USE_TYPE_SLOTS +#if PY_MAJOR_VERSION >= 3 + if (likely(PyUnicode_Check(n))) +#else + if (likely(PyString_Check(n))) +#endif + return __Pyx_PyObject_GetAttrStr(o, n); +#endif + return PyObject_GetAttr(o, n); } -static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { - PyErr_Format(PyExc_ValueError, - "Unexpected format string character: '%c'", ch); + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (unlikely(!j)) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; + PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; + if (mm && mm->mp_subscript) { + PyObject *r, *key = PyInt_FromSsize_t(i); + if (unlikely(!key)) return NULL; + r = mm->mp_subscript(o, key); + Py_DECREF(key); + return r; + } + if (likely(sm && sm->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { + Py_ssize_t l = sm->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return sm->sq_item(o, i); + } + } +#else + if (is_list || !PyMapping_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); } -static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { - switch (ch) { - case '?': return "'bool'"; - case 'c': return "'char'"; - case 'b': return "'signed char'"; - case 'B': return "'unsigned char'"; - case 'h': return "'short'"; - case 'H': return "'unsigned short'"; - case 'i': return "'int'"; - case 'I': return "'unsigned int'"; - case 'l': return "'long'"; - case 'L': return "'unsigned long'"; - case 'q': return "'long long'"; - case 'Q': return "'unsigned long long'"; - case 'f': return (is_complex ? "'complex float'" : "'float'"); - case 'd': return (is_complex ? "'complex double'" : "'double'"); - case 'g': return (is_complex ? "'complex long double'" : "'long double'"); - case 'T': return "a struct"; - case 'O': return "Python object"; - case 'P': return "a pointer"; - case 's': case 'p': return "a string"; - case 0: return "end"; - default: return "unparseable format string"; - } + +/* PyObjectCallOneArg */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); } -static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return 2; - case 'i': case 'I': case 'l': case 'L': return 4; - case 'q': case 'Q': return 8; - case 'f': return (is_complex ? 8 : 4); - case 'd': return (is_complex ? 16 : 8); - case 'g': { - PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); - return 0; + +/* ObjectGetItem */ +#if CYTHON_USE_TYPE_SLOTS +static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject *index) { + PyObject *runerr = NULL; + Py_ssize_t key_value; + key_value = __Pyx_PyIndex_AsSsize_t(index); + if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { + return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); } - case 'O': case 'P': return sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; + if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { + __Pyx_TypeName index_type_name = __Pyx_PyType_GetName(Py_TYPE(index)); + PyErr_Clear(); + PyErr_Format(PyExc_IndexError, + "cannot fit '" __Pyx_FMT_TYPENAME "' into an index-sized integer", index_type_name); + __Pyx_DECREF_TypeName(index_type_name); } + return NULL; } -static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(short); - case 'i': case 'I': return sizeof(int); - case 'l': case 'L': return sizeof(long); - #ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(PY_LONG_LONG); - #endif - case 'f': return sizeof(float) * (is_complex ? 2 : 1); - case 'd': return sizeof(double) * (is_complex ? 2 : 1); - case 'g': return sizeof(long double) * (is_complex ? 2 : 1); - case 'O': case 'P': return sizeof(void*); - default: { - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; +static PyObject *__Pyx_PyObject_GetItem_Slow(PyObject *obj, PyObject *key) { + __Pyx_TypeName obj_type_name; + if (likely(PyType_Check(obj))) { + PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(obj, __pyx_n_s_class_getitem); + if (!meth) { + PyErr_Clear(); + } else { + PyObject *result = __Pyx_PyObject_CallOneArg(meth, key); + Py_DECREF(meth); + return result; + } } - } + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "'" __Pyx_FMT_TYPENAME "' object is not subscriptable", obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return NULL; } -typedef struct { char c; short x; } __Pyx_st_short; -typedef struct { char c; int x; } __Pyx_st_int; -typedef struct { char c; long x; } __Pyx_st_long; -typedef struct { char c; float x; } __Pyx_st_float; -typedef struct { char c; double x; } __Pyx_st_double; -typedef struct { char c; long double x; } __Pyx_st_longdouble; -typedef struct { char c; void *x; } __Pyx_st_void_p; -#ifdef HAVE_LONG_LONG -typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; -#endif -static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); - case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); - case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); -#ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); -#endif - case 'f': return sizeof(__Pyx_st_float) - sizeof(float); - case 'd': return sizeof(__Pyx_st_double) - sizeof(double); - case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); - case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; +static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key) { + PyTypeObject *tp = Py_TYPE(obj); + PyMappingMethods *mm = tp->tp_as_mapping; + PySequenceMethods *sm = tp->tp_as_sequence; + if (likely(mm && mm->mp_subscript)) { + return mm->mp_subscript(obj, key); + } + if (likely(sm && sm->sq_item)) { + return __Pyx_PyObject_GetIndex(obj, key); } + return __Pyx_PyObject_GetItem_Slow(obj, key); } -/* These are for computing the padding at the end of the struct to align - on the first member of the struct. This will probably the same as above, - but we don't have any guarantees. - */ -typedef struct { short x; char c; } __Pyx_pad_short; -typedef struct { int x; char c; } __Pyx_pad_int; -typedef struct { long x; char c; } __Pyx_pad_long; -typedef struct { float x; char c; } __Pyx_pad_float; -typedef struct { double x; char c; } __Pyx_pad_double; -typedef struct { long double x; char c; } __Pyx_pad_longdouble; -typedef struct { void *x; char c; } __Pyx_pad_void_p; -#ifdef HAVE_LONG_LONG -typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; #endif -static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); - case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); - case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); -#ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); + +/* KeywordStringCheck */ +static int __Pyx_CheckKeywordStrings( + PyObject *kw, + const char* function_name, + int kw_allowed) +{ + PyObject* key = 0; + Py_ssize_t pos = 0; +#if CYTHON_COMPILING_IN_PYPY + if (!kw_allowed && PyDict_Next(kw, &pos, &key, 0)) + goto invalid_keyword; + return 1; +#else + if (CYTHON_METH_FASTCALL && likely(PyTuple_Check(kw))) { + Py_ssize_t kwsize; +#if CYTHON_ASSUME_SAFE_MACROS + kwsize = PyTuple_GET_SIZE(kw); +#else + kwsize = PyTuple_Size(kw); + if (kwsize < 0) return 0; #endif - case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); - case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); - case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); - case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; + if (unlikely(kwsize == 0)) + return 1; + if (!kw_allowed) { +#if CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kw, 0); +#else + key = PyTuple_GetItem(kw, pos); + if (!key) return 0; +#endif + goto invalid_keyword; + } +#if PY_VERSION_HEX < 0x03090000 + for (pos = 0; pos < kwsize; pos++) { +#if CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kw, pos); +#else + key = PyTuple_GetItem(kw, pos); + if (!key) return 0; +#endif + if (unlikely(!PyUnicode_Check(key))) + goto invalid_keyword_type; + } +#endif + return 1; + } + while (PyDict_Next(kw, &pos, &key, 0)) { + #if PY_MAJOR_VERSION < 3 + if (unlikely(!PyString_Check(key))) + #endif + if (unlikely(!PyUnicode_Check(key))) + goto invalid_keyword_type; } + if (!kw_allowed && unlikely(key)) + goto invalid_keyword; + return 1; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + return 0; +#endif +invalid_keyword: + #if PY_MAJOR_VERSION < 3 + PyErr_Format(PyExc_TypeError, + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif + return 0; } -static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { - switch (ch) { - case 'c': - return 'H'; - case 'b': case 'h': case 'i': - case 'l': case 'q': case 's': case 'p': - return 'I'; - case '?': case 'B': case 'H': case 'I': case 'L': case 'Q': - return 'U'; - case 'f': case 'd': case 'g': - return (is_complex ? 'C' : 'R'); - case 'O': - return 'O'; - case 'P': - return 'P'; - default: { - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; + +/* DivInt[Py_ssize_t] */ +static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) { + Py_ssize_t q = a / b; + Py_ssize_t r = a - q*b; + q -= ((r != 0) & ((r ^ b) < 0)); + return q; +} + +/* GetAttr3 */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 +static PyObject *__Pyx_GetAttr3Default(PyObject *d) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + return NULL; + __Pyx_PyErr_Clear(); + Py_INCREF(d); + return d; +} +#endif +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { + PyObject *r; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + int res = PyObject_GetOptionalAttr(o, n, &r); + return (res != 0) ? r : __Pyx_NewRef(d); +#else + #if CYTHON_USE_TYPE_SLOTS + if (likely(PyString_Check(n))) { + r = __Pyx_PyObject_GetAttrStrNoError(o, n); + if (unlikely(!r) && likely(!PyErr_Occurred())) { + r = __Pyx_NewRef(d); + } + return r; } - } + #endif + r = PyObject_GetAttr(o, n); + return (likely(r)) ? r : __Pyx_GetAttr3Default(d); +#endif } -static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { - if (ctx->head == NULL || ctx->head->field == &ctx->root) { - const char* expected; - const char* quote; - if (ctx->head == NULL) { - expected = "end"; - quote = ""; - } else { - expected = ctx->head->field->type->name; - quote = "'"; + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif } - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch, expected %s%s%s but got %s", - quote, expected, quote, - __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); - } else { - __Pyx_StructField* field = ctx->head->field; - __Pyx_StructField* parent = (ctx->head - 1)->field; - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", - field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), - parent->type->name, field->name); - } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; } -static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { - char group; - size_t size, offset, arraysize = 1; - if (ctx->enc_type == 0) return 0; - if (ctx->head->field->type->arraysize[0]) { - int i, ndim = 0; - if (ctx->enc_type == 's' || ctx->enc_type == 'p') { - ctx->is_valid_array = ctx->head->field->type->ndim == 1; - ndim = 1; - if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { - PyErr_Format(PyExc_ValueError, - "Expected a dimension of size %zu, got %zu", - ctx->head->field->type->arraysize[0], ctx->enc_count); - return -1; - } +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && PY_VERSION_HEX < 0x030d0000 + result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } else if (unlikely(PyErr_Occurred())) { + return NULL; } - if (!ctx->is_valid_array) { - PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", - ctx->head->field->type->ndim, ndim); - return -1; +#elif CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(!__pyx_m)) { + return NULL; } - for (i = 0; i < ctx->head->field->type->ndim; i++) { - arraysize *= ctx->head->field->type->arraysize[i]; + result = PyObject_GetAttr(__pyx_m, name); + if (likely(result)) { + return result; } - ctx->is_valid_array = 0; - ctx->enc_count = 1; - } - group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); - do { - __Pyx_StructField* field = ctx->head->field; - __Pyx_TypeInfo* type = field->type; - if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { - size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); - } else { - size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); +#else + result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); } - if (ctx->enc_packmode == '@') { - size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); - size_t align_mod_offset; - if (align_at == 0) return -1; - align_mod_offset = ctx->fmt_offset % align_at; - if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; - if (ctx->struct_alignment == 0) - ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, - ctx->is_complex); +#endif +#else + result = PyObject_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); } - if (type->size != size || type->typegroup != group) { - if (type->typegroup == 'C' && type->fields != NULL) { - size_t parent_offset = ctx->head->parent_offset + field->offset; - ++ctx->head; - ctx->head->field = type->fields; - ctx->head->parent_offset = parent_offset; - continue; - } - if ((type->typegroup == 'H' || group == 'H') && type->size == size) { - } else { - __Pyx_BufFmt_RaiseExpected(ctx); - return -1; - } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* RaiseNoneIterError */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); +} + +/* ExtTypeTest */ +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { + __Pyx_TypeName obj_type_name; + __Pyx_TypeName type_name; + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; } - offset = ctx->head->parent_offset + field->offset; - if (ctx->fmt_offset != offset) { - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", - (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); - return -1; + if (likely(__Pyx_TypeCheck(obj, type))) + return 1; + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + type_name = __Pyx_PyType_GetName(type); + PyErr_Format(PyExc_TypeError, + "Cannot convert " __Pyx_FMT_TYPENAME " to " __Pyx_FMT_TYPENAME, + obj_type_name, type_name); + __Pyx_DECREF_TypeName(obj_type_name); + __Pyx_DECREF_TypeName(type_name); + return 0; +} + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; } - ctx->fmt_offset += size; - if (arraysize) - ctx->fmt_offset += (arraysize - 1) * size; - --ctx->enc_count; - while (1) { - if (field == &ctx->root) { - ctx->head = NULL; - if (ctx->enc_count != 0) { - __Pyx_BufFmt_RaiseExpected(ctx); - return -1; - } - break; - } - ctx->head->field = ++field; - if (field->type == NULL) { - --ctx->head; - field = ctx->head->field; - continue; - } else if (field->type->typegroup == 'S') { - size_t parent_offset = ctx->head->parent_offset + field->offset; - if (field->type->fields->type == NULL) continue; - field = field->type->fields; - ++ctx->head; - ctx->head->field = field; - ctx->head->parent_offset = parent_offset; - break; - } else { - break; - } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + PyObject *exc_value = exc_info->exc_value; + if (exc_value == NULL || exc_value == Py_None) { + *value = NULL; + *type = NULL; + *tb = NULL; + } else { + *value = exc_value; + Py_INCREF(*value); + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + *tb = PyException_GetTraceback(exc_value); } - } while (ctx->enc_count); - ctx->enc_type = 0; - ctx->is_complex = 0; - return 0; + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #endif } -static PyObject * -__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + PyObject *tmp_value = exc_info->exc_value; + exc_info->exc_value = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); + #else + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); + #endif +} +#endif + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif { - const char *ts = *tsp; - int i = 0, number, ndim; - ++ts; - if (ctx->new_count != 1) { - PyErr_SetString(PyExc_ValueError, - "Cannot handle repeated arrays in format string"); - return NULL; + PyObject *local_type = NULL, *local_value, *local_tb = NULL; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if PY_VERSION_HEX >= 0x030C00A6 + local_value = tstate->current_exception; + tstate->current_exception = 0; + if (likely(local_value)) { + local_type = (PyObject*) Py_TYPE(local_value); + Py_INCREF(local_type); + local_tb = PyException_GetTraceback(local_value); + } + #else + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + #endif +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE && PY_VERSION_HEX >= 0x030C00A6 + if (unlikely(tstate->current_exception)) +#elif CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ndim = ctx->head->field->type->ndim; - while (*ts && *ts != ')') { - switch (*ts) { - case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; - default: break; - } - number = __Pyx_BufFmt_ExpectNumber(&ts); - if (number == -1) return NULL; - if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) - return PyErr_Format(PyExc_ValueError, - "Expected a dimension of size %zu, got %d", - ctx->head->field->type->arraysize[i], number); - if (*ts != ',' && *ts != ')') - return PyErr_Format(PyExc_ValueError, - "Expected a comma in format string, got '%c'", *ts); - if (*ts == ',') ts++; - i++; + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + #if PY_VERSION_HEX >= 0x030B00a4 + tmp_value = exc_info->exc_value; + exc_info->exc_value = local_value; + tmp_type = NULL; + tmp_tb = NULL; + Py_XDECREF(local_type); + Py_XDECREF(local_tb); + #else + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + #endif } - if (i != ndim) - return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", - ctx->head->field->type->ndim, i); - if (!*ts) { - PyErr_SetString(PyExc_ValueError, - "Unexpected end of format string, expected ')'"); - return NULL; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* SwapException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_value = exc_info->exc_value; + exc_info->exc_value = *value; + if (tmp_value == NULL || tmp_value == Py_None) { + Py_XDECREF(tmp_value); + tmp_value = NULL; + tmp_type = NULL; + tmp_tb = NULL; + } else { + tmp_type = (PyObject*) Py_TYPE(tmp_value); + Py_INCREF(tmp_type); + #if CYTHON_COMPILING_IN_CPYTHON + tmp_tb = ((PyBaseExceptionObject*) tmp_value)->traceback; + Py_XINCREF(tmp_tb); + #else + tmp_tb = PyException_GetTraceback(tmp_value); + #endif } - ctx->is_valid_array = 1; - ctx->new_count = 1; - *tsp = ++ts; - return Py_None; + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = *type; + tstate->exc_value = *value; + tstate->exc_traceback = *tb; + #endif + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; } -static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { - int got_Z = 0; - while (1) { - switch(*ts) { - case 0: - if (ctx->enc_type != 0 && ctx->head == NULL) { - __Pyx_BufFmt_RaiseExpected(ctx); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - if (ctx->head != NULL) { - __Pyx_BufFmt_RaiseExpected(ctx); - return NULL; - } - return ts; - case ' ': - case '\r': - case '\n': - ++ts; - break; - case '<': - if (!__Pyx_Is_Little_Endian()) { - PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); - return NULL; - } - ctx->new_packmode = '='; - ++ts; - break; - case '>': - case '!': - if (__Pyx_Is_Little_Endian()) { - PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); - return NULL; - } - ctx->new_packmode = '='; - ++ts; - break; - case '=': - case '@': - case '^': - ctx->new_packmode = *ts++; - break; - case 'T': - { - const char* ts_after_sub; - size_t i, struct_count = ctx->new_count; - size_t struct_alignment = ctx->struct_alignment; - ctx->new_count = 1; - ++ts; - if (*ts != '{') { - PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_type = 0; - ctx->enc_count = 0; - ctx->struct_alignment = 0; - ++ts; - ts_after_sub = ts; - for (i = 0; i != struct_count; ++i) { - ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); - if (!ts_after_sub) return NULL; - } - ts = ts_after_sub; - if (struct_alignment) ctx->struct_alignment = struct_alignment; - } - break; - case '}': - { - size_t alignment = ctx->struct_alignment; - ++ts; - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_type = 0; - if (alignment && ctx->fmt_offset % alignment) { - ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); - } - } - return ts; - case 'x': - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->fmt_offset += ctx->new_count; - ctx->new_count = 1; - ctx->enc_count = 0; - ctx->enc_type = 0; - ctx->enc_packmode = ctx->new_packmode; - ++ts; - break; - case 'Z': - got_Z = 1; - ++ts; - if (*ts != 'f' && *ts != 'd' && *ts != 'g') { - __Pyx_BufFmt_RaiseUnexpectedChar('Z'); - return NULL; - } - CYTHON_FALLTHROUGH; - case '?': case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': - case 'l': case 'L': case 'q': case 'Q': - case 'f': case 'd': case 'g': - case 'O': case 'p': - if ((ctx->enc_type == *ts) && (got_Z == ctx->is_complex) && - (ctx->enc_packmode == ctx->new_packmode) && (!ctx->is_valid_array)) { - ctx->enc_count += ctx->new_count; - ctx->new_count = 1; - got_Z = 0; - ++ts; - break; - } - CYTHON_FALLTHROUGH; - case 's': - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_count = ctx->new_count; - ctx->enc_packmode = ctx->new_packmode; - ctx->enc_type = *ts; - ctx->is_complex = got_Z; - ++ts; - ctx->new_count = 1; - got_Z = 0; - break; - case ':': - ++ts; - while(*ts != ':') ++ts; - ++ts; - break; - case '(': - if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; - break; - default: - { - int number = __Pyx_BufFmt_ExpectNumber(&ts); - if (number == -1) return NULL; - ctx->new_count = (size_t)number; +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); + PyErr_SetExcInfo(*type, *value, *tb); + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#endif + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *empty_list = 0; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (unlikely(!py_import)) + goto bad; + if (!from_list) { + empty_list = PyList_New(0); + if (unlikely(!empty_list)) + goto bad; + from_list = empty_list; + } + #endif + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.') != NULL) { + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, 1); + if (unlikely(!module)) { + if (unlikely(!PyErr_ExceptionMatches(PyExc_ImportError))) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (unlikely(!py_level)) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, __pyx_d, empty_dict, from_list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, level); + #endif } } - } +bad: + Py_XDECREF(empty_dict); + Py_XDECREF(empty_list); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + return module; } -/* BufferGetAndValidate */ - static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { - if (unlikely(info->buf == NULL)) return; - if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; - __Pyx_ReleaseBuffer(info); +/* ImportDottedModule */ +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Error(PyObject *name, PyObject *parts_tuple, Py_ssize_t count) { + PyObject *partial_name = NULL, *slice = NULL, *sep = NULL; + if (unlikely(PyErr_Occurred())) { + PyErr_Clear(); + } + if (likely(PyTuple_GET_SIZE(parts_tuple) == count)) { + partial_name = name; + } else { + slice = PySequence_GetSlice(parts_tuple, 0, count); + if (unlikely(!slice)) + goto bad; + sep = PyUnicode_FromStringAndSize(".", 1); + if (unlikely(!sep)) + goto bad; + partial_name = PyUnicode_Join(sep, slice); + } + PyErr_Format( +#if PY_MAJOR_VERSION < 3 + PyExc_ImportError, + "No module named '%s'", PyString_AS_STRING(partial_name)); +#else +#if PY_VERSION_HEX >= 0x030600B1 + PyExc_ModuleNotFoundError, +#else + PyExc_ImportError, +#endif + "No module named '%U'", partial_name); +#endif +bad: + Py_XDECREF(sep); + Py_XDECREF(slice); + Py_XDECREF(partial_name); + return NULL; } -static void __Pyx_ZeroBuffer(Py_buffer* buf) { - buf->buf = NULL; - buf->obj = NULL; - buf->strides = __Pyx_zeros; - buf->shape = __Pyx_zeros; - buf->suboffsets = __Pyx_minusones; +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Lookup(PyObject *name) { + PyObject *imported_module; +#if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + return NULL; + imported_module = __Pyx_PyDict_GetItemStr(modules, name); + Py_XINCREF(imported_module); +#else + imported_module = PyImport_GetModule(name); +#endif + return imported_module; } -static int __Pyx__GetBufferAndValidate( - Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, - int nd, int cast, __Pyx_BufFmt_StackElem* stack) -{ - buf->buf = NULL; - if (unlikely(__Pyx_GetBuffer(obj, buf, flags) == -1)) { - __Pyx_ZeroBuffer(buf); - return -1; - } - if (unlikely(buf->ndim != nd)) { - PyErr_Format(PyExc_ValueError, - "Buffer has wrong number of dimensions (expected %d, got %d)", - nd, buf->ndim); - goto fail; - } - if (!cast) { - __Pyx_BufFmt_Context ctx; - __Pyx_BufFmt_Init(&ctx, stack, dtype); - if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; - } - if (unlikely((size_t)buf->itemsize != dtype->size)) { - PyErr_Format(PyExc_ValueError, - "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", - buf->itemsize, (buf->itemsize > 1) ? "s" : "", - dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); - goto fail; - } - if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; - return 0; -fail:; - __Pyx_SafeReleaseBuffer(buf); - return -1; +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple) { + Py_ssize_t i, nparts; + nparts = PyTuple_GET_SIZE(parts_tuple); + for (i=1; i < nparts && module; i++) { + PyObject *part, *submodule; +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + part = PyTuple_GET_ITEM(parts_tuple, i); +#else + part = PySequence_ITEM(parts_tuple, i); +#endif + submodule = __Pyx_PyObject_GetAttrStrNoError(module, part); +#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(part); +#endif + Py_DECREF(module); + module = submodule; + } + if (unlikely(!module)) { + return __Pyx__ImportDottedModule_Error(name, parts_tuple, i); + } + return module; } - -/* PyDictVersioning */ - #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +#endif +static PyObject *__Pyx__ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if PY_MAJOR_VERSION < 3 + PyObject *module, *from_list, *star = __pyx_n_s__3; + CYTHON_UNUSED_VAR(parts_tuple); + from_list = PyList_New(1); + if (unlikely(!from_list)) + return NULL; + Py_INCREF(star); + PyList_SET_ITEM(from_list, 0, star); + module = __Pyx_Import(name, from_list, 0); + Py_DECREF(from_list); + return module; +#else + PyObject *imported_module; + PyObject *module = __Pyx_Import(name, NULL, 0); + if (!parts_tuple || unlikely(!module)) + return module; + imported_module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(imported_module)) { + Py_DECREF(module); + return imported_module; + } + PyErr_Clear(); + return __Pyx_ImportDottedModule_WalkParts(module, name, parts_tuple); +#endif +} +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030400B1 + PyObject *module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(module)) { + PyObject *spec = __Pyx_PyObject_GetAttrStrNoError(module, __pyx_n_s_spec); + if (likely(spec)) { + PyObject *unsafe = __Pyx_PyObject_GetAttrStrNoError(spec, __pyx_n_s_initializing); + if (likely(!unsafe || !__Pyx_PyObject_IsTrue(unsafe))) { + Py_DECREF(spec); + spec = NULL; + } + Py_XDECREF(unsafe); + } + if (likely(!spec)) { + PyErr_Clear(); + return module; + } + Py_DECREF(spec); + Py_DECREF(module); + } else if (PyErr_Occurred()) { + PyErr_Clear(); + } +#endif + return __Pyx__ImportDottedModule(name, parts_tuple); } -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { + +/* FastTypeChecks */ #if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} #else - dictptr = _PyObject_GetDictPtr(obj); +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} #endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; itp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject* exc_type) { + if (likely(err == exc_type)) return 1; + if (likely(PyExceptionClass_Check(err))) { + if (likely(PyExceptionClass_Check(exc_type))) { + return __Pyx_inner_PyErr_GivenExceptionMatches2(err, NULL, exc_type); + } else if (likely(PyTuple_Check(exc_type))) { + return __Pyx_PyErr_GivenExceptionMatchesTuple(err, exc_type); + } else { + } + } + return PyErr_GivenExceptionMatches(err, exc_type); +} +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *exc_type1, PyObject *exc_type2) { + assert(PyExceptionClass_Check(exc_type1)); + assert(PyExceptionClass_Check(exc_type2)); + if (likely(err == exc_type1 || err == exc_type2)) return 1; + if (likely(PyExceptionClass_Check(err))) { + return __Pyx_inner_PyErr_GivenExceptionMatches2(err, exc_type1, exc_type2); + } + return (PyErr_GivenExceptionMatches(err, exc_type1) || PyErr_GivenExceptionMatches(err, exc_type2)); } #endif -/* GetModuleGlobalName */ - #if CYTHON_USE_DICT_VERSIONS -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) -#else -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) -#endif -{ - PyObject *result; -#if !CYTHON_AVOID_BORROWED_REFS -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 - result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } else if (unlikely(PyErr_Occurred())) { +/* PySequenceMultiply */ +static PyObject* __Pyx_PySequence_Multiply_Generic(PyObject *seq, Py_ssize_t mul) { + PyObject *result, *pymul = PyInt_FromSsize_t(mul); + if (unlikely(!pymul)) return NULL; + result = PyNumber_Multiply(seq, pymul); + Py_DECREF(pymul); + return result; +} +static CYTHON_INLINE PyObject* __Pyx_PySequence_Multiply(PyObject *seq, Py_ssize_t mul) { +#if CYTHON_USE_TYPE_SLOTS + PyTypeObject *type = Py_TYPE(seq); + if (likely(type->tp_as_sequence && type->tp_as_sequence->sq_repeat)) { + return type->tp_as_sequence->sq_repeat(seq, mul); + } else +#endif + { + return __Pyx_PySequence_Multiply_Generic(seq, mul); } -#else - result = PyDict_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); +} + +/* SetItemInt */ +static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { + int r; + if (unlikely(!j)) return -1; + r = PyObject_SetItem(o, j, v); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int is_list, + CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o)); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o)))) { + PyObject* old = PyList_GET_ITEM(o, n); + Py_INCREF(v); + PyList_SET_ITEM(o, n, v); + Py_DECREF(old); + return 1; + } + } else { + PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; + PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; + if (mm && mm->mp_ass_subscript) { + int r; + PyObject *key = PyInt_FromSsize_t(i); + if (unlikely(!key)) return -1; + r = mm->mp_ass_subscript(o, key, v); + Py_DECREF(key); + return r; + } + if (likely(sm && sm->sq_ass_item)) { + if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { + Py_ssize_t l = sm->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return -1; + PyErr_Clear(); + } + } + return sm->sq_ass_item(o, i, v); + } } -#endif #else - result = PyObject_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); + if (is_list || !PyMapping_Check(o)) + { + return PySequence_SetItem(o, i, v); } - PyErr_Clear(); #endif - return __Pyx_GetBuiltinName(name); + return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v); } -/* PyCFunctionFastCall */ - #if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { - PyCFunctionObject *func = (PyCFunctionObject*)func_obj; - PyCFunction meth = PyCFunction_GET_FUNCTION(func); - PyObject *self = PyCFunction_GET_SELF(func); - int flags = PyCFunction_GET_FLAGS(func); - assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - /* _PyCFunction_FastCallDict() must not be called with an exception set, - because it may clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); - if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); - } else { - return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); - } +/* RaiseUnboundLocalError */ +static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) { + PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname); } -#endif -/* PyFunctionFastCall */ - #if CYTHON_FAST_PYCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; +/* DivInt[long] */ +static CYTHON_INLINE long __Pyx_div_long(long a, long b) { + long q = a / b; + long r = a - q*b; + q -= ((r != 0) & ((r ^ b) < 0)); + return q; +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_kp_u__2); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; + return value; } -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { - return NULL; + +/* HasAttr */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { + PyObject *r; + if (unlikely(!__Pyx_PyBaseString_Check(n))) { + PyErr_SetString(PyExc_TypeError, + "hasattr(): attribute name must be string"); + return -1; } - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } + r = __Pyx_GetAttr(o, n); + if (!r) { + PyErr_Clear(); + return 0; + } else { + Py_DECREF(r); + return 1; } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; +} +#endif + +/* IsLittleEndian */ +static CYTHON_INLINE int __Pyx_Is_Little_Endian(void) +{ + union { + uint32_t u32; + uint8_t u8[4]; + } S; + S.u32 = 0x01020304; + return S.u8[0] == 4; +} + +/* BufferFormatCheck */ +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type) { + stack[0].field = &ctx->root; + stack[0].parent_offset = 0; + ctx->root.type = type; + ctx->root.name = "buffer dtype"; + ctx->root.offset = 0; + ctx->head = stack; + ctx->head->field = &ctx->root; + ctx->fmt_offset = 0; + ctx->head->parent_offset = 0; + ctx->new_packmode = '@'; + ctx->enc_packmode = '@'; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->is_complex = 0; + ctx->is_valid_array = 0; + ctx->struct_alignment = 0; + while (type->typegroup == 'S') { + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = 0; + type = type->fields->type; + } +} +static int __Pyx_BufFmt_ParseNumber(const char** ts) { + int count; + const char* t = *ts; + if (*t < '0' || *t > '9') { + return -1; + } else { + count = *t++ - '0'; + while (*t >= '0' && *t <= '9') { + count *= 10; + count += *t++ - '0'; } - nk = i / 2; } - else { - kwtuple = NULL; - k = NULL; + *ts = t; + return count; +} +static int __Pyx_BufFmt_ExpectNumber(const char **ts) { + int number = __Pyx_BufFmt_ParseNumber(ts); + if (number == -1) + PyErr_Format(PyExc_ValueError,\ + "Does not understand character buffer dtype format string ('%c')", **ts); + return number; +} +static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { + PyErr_Format(PyExc_ValueError, + "Unexpected format string character: '%c'", ch); +} +static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { + switch (ch) { + case '?': return "'bool'"; + case 'c': return "'char'"; + case 'b': return "'signed char'"; + case 'B': return "'unsigned char'"; + case 'h': return "'short'"; + case 'H': return "'unsigned short'"; + case 'i': return "'int'"; + case 'I': return "'unsigned int'"; + case 'l': return "'long'"; + case 'L': return "'unsigned long'"; + case 'q': return "'long long'"; + case 'Q': return "'unsigned long long'"; + case 'f': return (is_complex ? "'complex float'" : "'float'"); + case 'd': return (is_complex ? "'complex double'" : "'double'"); + case 'g': return (is_complex ? "'complex long double'" : "'long double'"); + case 'T': return "a struct"; + case 'O': return "Python object"; + case 'P': return "a pointer"; + case 's': case 'p': return "a string"; + case 0: return "end"; + default: return "unparsable format string"; + } +} +static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return 2; + case 'i': case 'I': case 'l': case 'L': return 4; + case 'q': case 'Q': return 8; + case 'f': return (is_complex ? 8 : 4); + case 'd': return (is_complex ? 16 : 8); + case 'g': { + PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); + return 0; } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); + case 'O': case 'P': return sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; } - else { - d = NULL; - nd = 0; +} +static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(short); + case 'i': case 'I': return sizeof(int); + case 'l': case 'L': return sizeof(long); + #ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(PY_LONG_LONG); + #endif + case 'f': return sizeof(float) * (is_complex ? 2 : 1); + case 'd': return sizeof(double) * (is_complex ? 2 : 1); + case 'g': return sizeof(long double) * (is_complex ? 2 : 1); + case 'O': case 'P': return sizeof(void*); + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; + } } +typedef struct { char c; short x; } __Pyx_st_short; +typedef struct { char c; int x; } __Pyx_st_int; +typedef struct { char c; long x; } __Pyx_st_long; +typedef struct { char c; float x; } __Pyx_st_float; +typedef struct { char c; double x; } __Pyx_st_double; +typedef struct { char c; long double x; } __Pyx_st_longdouble; +typedef struct { char c; void *x; } __Pyx_st_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; #endif +static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, int is_complex) { + CYTHON_UNUSED_VAR(is_complex); + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); #endif - -/* PyObjectCall */ - #if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = Py_TYPE(func)->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); + case 'f': return sizeof(__Pyx_st_float) - sizeof(float); + case 'd': return sizeof(__Pyx_st_double) - sizeof(double); + case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; } - return result; } +/* These are for computing the padding at the end of the struct to align + on the first member of the struct. This will probably the same as above, + but we don't have any guarantees. + */ +typedef struct { short x; char c; } __Pyx_pad_short; +typedef struct { int x; char c; } __Pyx_pad_int; +typedef struct { long x; char c; } __Pyx_pad_long; +typedef struct { float x; char c; } __Pyx_pad_float; +typedef struct { double x; char c; } __Pyx_pad_double; +typedef struct { long double x; char c; } __Pyx_pad_longdouble; +typedef struct { void *x; char c; } __Pyx_pad_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; #endif - -/* PyObjectCall2Args */ - static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { - PyObject *args, *result = NULL; - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyFunction_FastCall(function, args, 2); - } - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyCFunction_FastCall(function, args, 2); +static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, int is_complex) { + CYTHON_UNUSED_VAR(is_complex); + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); + case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); + case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; } - #endif - args = PyTuple_New(2); - if (unlikely(!args)) goto done; - Py_INCREF(arg1); - PyTuple_SET_ITEM(args, 0, arg1); - Py_INCREF(arg2); - PyTuple_SET_ITEM(args, 1, arg2); - Py_INCREF(function); - result = __Pyx_PyObject_Call(function, args, NULL); - Py_DECREF(args); - Py_DECREF(function); -done: - return result; } - -/* PyObjectCallMethO */ - #if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = PyCFunction_GET_FUNCTION(func); - self = PyCFunction_GET_SELF(func); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); +static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { + switch (ch) { + case 'c': + return 'H'; + case 'b': case 'h': case 'i': + case 'l': case 'q': case 's': case 'p': + return 'I'; + case '?': case 'B': case 'H': case 'I': case 'L': case 'Q': + return 'U'; + case 'f': case 'd': case 'g': + return (is_complex ? 'C' : 'R'); + case 'O': + return 'O'; + case 'P': + return 'P'; + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; } - return result; + } } -#endif - -/* PyObjectCallOneArg */ - #if CYTHON_COMPILING_IN_CPYTHON -static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_New(1); - if (unlikely(!args)) return NULL; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; +static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { + if (ctx->head == NULL || ctx->head->field == &ctx->root) { + const char* expected; + const char* quote; + if (ctx->head == NULL) { + expected = "end"; + quote = ""; + } else { + expected = ctx->head->field->type->name; + quote = "'"; + } + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected %s%s%s but got %s", + quote, expected, quote, + __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); + } else { + __Pyx_StructField* field = ctx->head->field; + __Pyx_StructField* parent = (ctx->head - 1)->field; + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", + field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), + parent->type->name, field->name); + } } -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, &arg, 1); +static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { + char group; + size_t size, offset, arraysize = 1; + if (ctx->enc_type == 0) return 0; + if (ctx->head->field->type->arraysize[0]) { + int i, ndim = 0; + if (ctx->enc_type == 's' || ctx->enc_type == 'p') { + ctx->is_valid_array = ctx->head->field->type->ndim == 1; + ndim = 1; + if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { + PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %zu", + ctx->head->field->type->arraysize[0], ctx->enc_count); + return -1; + } } -#endif - if (likely(PyCFunction_Check(func))) { - if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { - return __Pyx_PyObject_CallMethO(func, arg); -#if CYTHON_FAST_PYCCALL - } else if (__Pyx_PyFastCFunction_Check(func)) { - return __Pyx_PyCFunction_FastCall(func, &arg, 1); -#endif + if (!ctx->is_valid_array) { + PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", + ctx->head->field->type->ndim, ndim); + return -1; + } + for (i = 0; i < ctx->head->field->type->ndim; i++) { + arraysize *= ctx->head->field->type->arraysize[i]; + } + ctx->is_valid_array = 0; + ctx->enc_count = 1; + } + group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); + do { + __Pyx_StructField* field = ctx->head->field; + __Pyx_TypeInfo* type = field->type; + if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { + size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); + } else { + size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); + } + if (ctx->enc_packmode == '@') { + size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); + size_t align_mod_offset; + if (align_at == 0) return -1; + align_mod_offset = ctx->fmt_offset % align_at; + if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; + if (ctx->struct_alignment == 0) + ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, + ctx->is_complex); + } + if (type->size != size || type->typegroup != group) { + if (type->typegroup == 'C' && type->fields != NULL) { + size_t parent_offset = ctx->head->parent_offset + field->offset; + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = parent_offset; + continue; + } + if ((type->typegroup == 'H' || group == 'H') && type->size == size) { + } else { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + } + offset = ctx->head->parent_offset + field->offset; + if (ctx->fmt_offset != offset) { + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", + (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); + return -1; + } + ctx->fmt_offset += size; + if (arraysize) + ctx->fmt_offset += (arraysize - 1) * size; + --ctx->enc_count; + while (1) { + if (field == &ctx->root) { + ctx->head = NULL; + if (ctx->enc_count != 0) { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; } + break; + } + ctx->head->field = ++field; + if (field->type == NULL) { + --ctx->head; + field = ctx->head->field; + continue; + } else if (field->type->typegroup == 'S') { + size_t parent_offset = ctx->head->parent_offset + field->offset; + if (field->type->fields->type == NULL) continue; + field = field->type->fields; + ++ctx->head; + ctx->head->field = field; + ctx->head->parent_offset = parent_offset; + break; + } else { + break; + } } - return __Pyx__PyObject_CallOneArg(func, arg); -} -#else -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_Pack(1, arg); - if (unlikely(!args)) return NULL; - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; + } while (ctx->enc_count); + ctx->enc_type = 0; + ctx->is_complex = 0; + return 0; } -#endif - -/* MemviewSliceInit */ - static int -__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview, - int ndim, - __Pyx_memviewslice *memviewslice, - int memview_is_new_reference) +static int +__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) { - __Pyx_RefNannyDeclarations - int i, retval=-1; - Py_buffer *buf = &memview->view; - __Pyx_RefNannySetupContext("init_memviewslice", 0); - if (unlikely(memviewslice->memview || memviewslice->data)) { + const char *ts = *tsp; + int i = 0, number, ndim; + ++ts; + if (ctx->new_count != 1) { PyErr_SetString(PyExc_ValueError, - "memviewslice is already initialized!"); - goto fail; + "Cannot handle repeated arrays in format string"); + return -1; } - if (buf->strides) { - for (i = 0; i < ndim; i++) { - memviewslice->strides[i] = buf->strides[i]; + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return -1; + ndim = ctx->head->field->type->ndim; + while (*ts && *ts != ')') { + switch (*ts) { + case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; + default: break; } - } else { - Py_ssize_t stride = buf->itemsize; - for (i = ndim - 1; i >= 0; i--) { - memviewslice->strides[i] = stride; - stride *= buf->shape[i]; + number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return -1; + if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) { + PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %d", + ctx->head->field->type->arraysize[i], number); + return -1; } - } - for (i = 0; i < ndim; i++) { - memviewslice->shape[i] = buf->shape[i]; - if (buf->suboffsets) { - memviewslice->suboffsets[i] = buf->suboffsets[i]; - } else { - memviewslice->suboffsets[i] = -1; + if (*ts != ',' && *ts != ')') { + PyErr_Format(PyExc_ValueError, + "Expected a comma in format string, got '%c'", *ts); + return -1; } + if (*ts == ',') ts++; + i++; } - memviewslice->memview = memview; - memviewslice->data = (char *)buf->buf; - if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) { - Py_INCREF(memview); + if (i != ndim) { + PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", + ctx->head->field->type->ndim, i); + return -1; } - retval = 0; - goto no_fail; -fail: - memviewslice->memview = 0; - memviewslice->data = 0; - retval = -1; -no_fail: - __Pyx_RefNannyFinishContext(); - return retval; -} -#ifndef Py_NO_RETURN -#define Py_NO_RETURN -#endif -static void __pyx_fatalerror(const char *fmt, ...) Py_NO_RETURN { - va_list vargs; - char msg[200]; -#if PY_VERSION_HEX >= 0x030A0000 || defined(HAVE_STDARG_PROTOTYPES) - va_start(vargs, fmt); -#else - va_start(vargs); -#endif - vsnprintf(msg, 200, fmt, vargs); - va_end(vargs); - Py_FatalError(msg); -} -static CYTHON_INLINE int -__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count, - PyThread_type_lock lock) -{ - int result; - PyThread_acquire_lock(lock, 1); - result = (*acquisition_count)++; - PyThread_release_lock(lock); - return result; -} -static CYTHON_INLINE int -__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count, - PyThread_type_lock lock) -{ - int result; - PyThread_acquire_lock(lock, 1); - result = (*acquisition_count)--; - PyThread_release_lock(lock); - return result; -} -static CYTHON_INLINE void -__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno) -{ - int first_time; - struct __pyx_memoryview_obj *memview = memslice->memview; - if (unlikely(!memview || (PyObject *) memview == Py_None)) - return; - if (unlikely(__pyx_get_slice_count(memview) < 0)) - __pyx_fatalerror("Acquisition count is %d (line %d)", - __pyx_get_slice_count(memview), lineno); - first_time = __pyx_add_acquisition_count(memview) == 0; - if (unlikely(first_time)) { - if (have_gil) { - Py_INCREF((PyObject *) memview); - } else { - PyGILState_STATE _gilstate = PyGILState_Ensure(); - Py_INCREF((PyObject *) memview); - PyGILState_Release(_gilstate); - } + if (!*ts) { + PyErr_SetString(PyExc_ValueError, + "Unexpected end of format string, expected ')'"); + return -1; } + ctx->is_valid_array = 1; + ctx->new_count = 1; + *tsp = ++ts; + return 0; } -static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice, - int have_gil, int lineno) { - int last_time; - struct __pyx_memoryview_obj *memview = memslice->memview; - if (unlikely(!memview || (PyObject *) memview == Py_None)) { - memslice->memview = NULL; - return; - } - if (unlikely(__pyx_get_slice_count(memview) <= 0)) - __pyx_fatalerror("Acquisition count is %d (line %d)", - __pyx_get_slice_count(memview), lineno); - last_time = __pyx_sub_acquisition_count(memview) == 1; - memslice->data = NULL; - if (unlikely(last_time)) { - if (have_gil) { - Py_CLEAR(memslice->memview); - } else { - PyGILState_STATE _gilstate = PyGILState_Ensure(); - Py_CLEAR(memslice->memview); - PyGILState_Release(_gilstate); +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { + int got_Z = 0; + while (1) { + switch(*ts) { + case 0: + if (ctx->enc_type != 0 && ctx->head == NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + if (ctx->head != NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + return ts; + case ' ': + case '\r': + case '\n': + ++ts; + break; + case '<': + if (!__Pyx_Is_Little_Endian()) { + PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '>': + case '!': + if (__Pyx_Is_Little_Endian()) { + PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '=': + case '@': + case '^': + ctx->new_packmode = *ts++; + break; + case 'T': + { + const char* ts_after_sub; + size_t i, struct_count = ctx->new_count; + size_t struct_alignment = ctx->struct_alignment; + ctx->new_count = 1; + ++ts; + if (*ts != '{') { + PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + ctx->enc_count = 0; + ctx->struct_alignment = 0; + ++ts; + ts_after_sub = ts; + for (i = 0; i != struct_count; ++i) { + ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); + if (!ts_after_sub) return NULL; + } + ts = ts_after_sub; + if (struct_alignment) ctx->struct_alignment = struct_alignment; + } + break; + case '}': + { + size_t alignment = ctx->struct_alignment; + ++ts; + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + if (alignment && ctx->fmt_offset % alignment) { + ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); + } + } + return ts; + case 'x': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->fmt_offset += ctx->new_count; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->enc_packmode = ctx->new_packmode; + ++ts; + break; + case 'Z': + got_Z = 1; + ++ts; + if (*ts != 'f' && *ts != 'd' && *ts != 'g') { + __Pyx_BufFmt_RaiseUnexpectedChar('Z'); + return NULL; + } + CYTHON_FALLTHROUGH; + case '?': case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': + case 'l': case 'L': case 'q': case 'Q': + case 'f': case 'd': case 'g': + case 'O': case 'p': + if ((ctx->enc_type == *ts) && (got_Z == ctx->is_complex) && + (ctx->enc_packmode == ctx->new_packmode) && (!ctx->is_valid_array)) { + ctx->enc_count += ctx->new_count; + ctx->new_count = 1; + got_Z = 0; + ++ts; + break; + } + CYTHON_FALLTHROUGH; + case 's': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_count = ctx->new_count; + ctx->enc_packmode = ctx->new_packmode; + ctx->enc_type = *ts; + ctx->is_complex = got_Z; + ++ts; + ctx->new_count = 1; + got_Z = 0; + break; + case ':': + ++ts; + while(*ts != ':') ++ts; + ++ts; + break; + case '(': + if (__pyx_buffmt_parse_array(ctx, &ts) < 0) return NULL; + break; + default: + { + int number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + ctx->new_count = (size_t)number; } - } else { - memslice->memview = NULL; - } -} - -/* PyErrFetchRestore */ - #if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* GetTopmostException */ - #if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * -__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) -{ - _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && - exc_info->previous_item != NULL) - { - exc_info = exc_info->previous_item; } - return exc_info; -} -#endif - -/* SaveResetException */ - #if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - *type = exc_info->exc_type; - *value = exc_info->exc_value; - *tb = exc_info->exc_traceback; - #else - *type = tstate->exc_type; - *value = tstate->exc_value; - *tb = tstate->exc_traceback; - #endif - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); -} -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = type; - exc_info->exc_value = value; - exc_info->exc_traceback = tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = type; - tstate->exc_value = value; - tstate->exc_traceback = tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); + } } -#endif -/* PyErrExceptionMatches */ - #if CYTHON_FAST_THREAD_STATE -static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; ibuf == NULL)) return; + if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; + __Pyx_ReleaseBuffer(info); } -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err) { - PyObject *exc_type = tstate->curexc_type; - if (exc_type == err) return 1; - if (unlikely(!exc_type)) return 0; - if (unlikely(PyTuple_Check(err))) - return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); - return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); +static void __Pyx_ZeroBuffer(Py_buffer* buf) { + buf->buf = NULL; + buf->obj = NULL; + buf->strides = __Pyx_zeros; + buf->shape = __Pyx_zeros; + buf->suboffsets = __Pyx_minusones; } -#endif - -/* GetException */ - #if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) -#endif +static int __Pyx__GetBufferAndValidate( + Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, + int nd, int cast, __Pyx_BufFmt_StackElem* stack) { - PyObject *local_type, *local_value, *local_tb; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if CYTHON_USE_EXC_INFO_STACK - { - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = local_type; - exc_info->exc_value = local_value; - exc_info->exc_traceback = local_tb; - } - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); + buf->buf = NULL; + if (unlikely(__Pyx_GetBuffer(obj, buf, flags) == -1)) { + __Pyx_ZeroBuffer(buf); return -1; + } + if (unlikely(buf->ndim != nd)) { + PyErr_Format(PyExc_ValueError, + "Buffer has wrong number of dimensions (expected %d, got %d)", + nd, buf->ndim); + goto fail; + } + if (!cast) { + __Pyx_BufFmt_Context ctx; + __Pyx_BufFmt_Init(&ctx, stack, dtype); + if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; + } + if (unlikely((size_t)buf->itemsize != dtype->size)) { + PyErr_Format(PyExc_ValueError, + "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", + buf->itemsize, (buf->itemsize > 1) ? "s" : "", + dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); + goto fail; + } + if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; + return 0; +fail:; + __Pyx_SafeReleaseBuffer(buf); + return -1; } -/* RaiseException */ - #if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, - CYTHON_UNUSED PyObject *cause) { - __Pyx_PyThreadState_declare - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } +/* PyObject_GenericGetAttrNoDict */ + #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { + __Pyx_TypeName type_name = __Pyx_PyType_GetName(tp); + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, attr_name); +#else + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", + type_name, PyString_AS_STRING(attr_name)); +#endif + __Pyx_DECREF_TypeName(type_name); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { + PyObject *descr; + PyTypeObject *tp = Py_TYPE(obj); + if (unlikely(!PyString_Check(attr_name))) { + return PyObject_GenericGetAttr(obj, attr_name); } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; + assert(!tp->tp_dictoffset); + descr = _PyType_Lookup(tp, attr_name); + if (unlikely(!descr)) { + return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); + } + Py_INCREF(descr); + #if PY_MAJOR_VERSION < 3 + if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) + #endif + { + descrgetfunc f = Py_TYPE(descr)->tp_descr_get; + if (unlikely(f)) { + PyObject *res = f(descr, obj, (PyObject *)tp); + Py_DECREF(descr); + return res; } + } + return descr; +} #endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } + +/* PyObject_GenericGetAttr */ + #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { + if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { + return PyObject_GenericGetAttr(obj, attr_name); } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; + return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); } +#endif + +/* FixUpExtensionType */ + #if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); #else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; + const PyType_Slot *slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { + int changed = 0; +#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON) + const +#endif + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { +#if PY_VERSION_HEX < 0x030900b1 + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); +#if PY_VERSION_HEX >= 0x030800b4 + type->tp_vectorcall_offset = memb->offset; +#else + type->tp_print = (printfunc) memb->offset; +#endif + changed = 1; + } +#endif +#else + if ((0)); +#endif +#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + changed = 1; + } +#endif } + memb++; } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; + if (changed) + PyType_Modified(type); + } +#endif + return 0; +} +#endif + +/* PyObjectCallNoArg */ + static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { + PyObject *arg[2] = {NULL, NULL}; + return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetMethod */ + static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + __Pyx_TypeName type_name; + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR + if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) +#elif PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; } } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; } - PyException_SetCause(value, fixed_cause); + Py_DECREF(dict); } - PyErr_SetObject(type, value); - if (tb) { -#if CYTHON_COMPILING_IN_PYPY - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (likely(descr != NULL)) { + *method = descr; + return 0; + } + type_name = __Pyx_PyType_GetName(tp); + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, name); #else - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", + type_name, PyString_AS_STRING(name)); #endif + __Pyx_DECREF_TypeName(type_name); + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; } -bad: - Py_XDECREF(owned_instance); - return; -} #endif + *method = attr; + return 0; +} -/* BytesEquals */ - static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY - return PyObject_RichCompareBool(s1, s2, equals); -#else - if (s1 == s2) { - return (equals == Py_EQ); - } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { - const char *ps1, *ps2; - Py_ssize_t length = PyBytes_GET_SIZE(s1); - if (length != PyBytes_GET_SIZE(s2)) - return (equals == Py_NE); - ps1 = PyBytes_AS_STRING(s1); - ps2 = PyBytes_AS_STRING(s2); - if (ps1[0] != ps2[0]) { - return (equals == Py_NE); - } else if (length == 1) { - return (equals == Py_EQ); - } else { - int result; -#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) - Py_hash_t hash1, hash2; - hash1 = ((PyBytesObject*)s1)->ob_shash; - hash2 = ((PyBytesObject*)s2)->ob_shash; - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - return (equals == Py_NE); - } -#endif - result = memcmp(ps1, ps2, (size_t)length); - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { - return (equals == Py_NE); - } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { - return (equals == Py_NE); - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); +/* PyObjectCallMethod0 */ + static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { + PyObject *method = NULL, *result = NULL; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_CallOneArg(method, obj); + Py_DECREF(method); return result; } -#endif + if (unlikely(!method)) goto bad; + result = __Pyx_PyObject_CallNoArg(method); + Py_DECREF(method); +bad: + return result; } -/* UnicodeEquals */ - static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY - return PyObject_RichCompareBool(s1, s2, equals); +/* ValidateBasesTuple */ + #if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) { + Py_ssize_t i, n; +#if CYTHON_ASSUME_SAFE_MACROS + n = PyTuple_GET_SIZE(bases); #else -#if PY_MAJOR_VERSION < 3 - PyObject* owned_ref = NULL; + n = PyTuple_Size(bases); + if (n < 0) return -1; #endif - int s1_is_unicode, s2_is_unicode; - if (s1 == s2) { - goto return_eq; - } - s1_is_unicode = PyUnicode_CheckExact(s1); - s2_is_unicode = PyUnicode_CheckExact(s2); + for (i = 1; i < n; i++) + { +#if CYTHON_AVOID_BORROWED_REFS + PyObject *b0 = PySequence_GetItem(bases, i); + if (!b0) return -1; +#elif CYTHON_ASSUME_SAFE_MACROS + PyObject *b0 = PyTuple_GET_ITEM(bases, i); +#else + PyObject *b0 = PyTuple_GetItem(bases, i); + if (!b0) return -1; +#endif + PyTypeObject *b; #if PY_MAJOR_VERSION < 3 - if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { - owned_ref = PyUnicode_FromObject(s2); - if (unlikely(!owned_ref)) - return -1; - s2 = owned_ref; - s2_is_unicode = 1; - } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { - owned_ref = PyUnicode_FromObject(s1); - if (unlikely(!owned_ref)) + if (PyClass_Check(b0)) + { + PyErr_Format(PyExc_TypeError, "base class '%.200s' is an old-style class", + PyString_AS_STRING(((PyClassObject*)b0)->cl_name)); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif return -1; - s1 = owned_ref; - s1_is_unicode = 1; - } else if (((!s2_is_unicode) & (!s1_is_unicode))) { - return __Pyx_PyBytes_Equals(s1, s2, equals); - } + } +#endif + b = (PyTypeObject*) b0; + if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE)) + { + __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); + PyErr_Format(PyExc_TypeError, + "base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name); + __Pyx_DECREF_TypeName(b_name); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); #endif - if (s1_is_unicode & s2_is_unicode) { - Py_ssize_t length; - int kind; - void *data1, *data2; - if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) return -1; - length = __Pyx_PyUnicode_GET_LENGTH(s1); - if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { - goto return_ne; } -#if CYTHON_USE_UNICODE_INTERNALS + if (dictoffset == 0) { - Py_hash_t hash1, hash2; - #if CYTHON_PEP393_ENABLED - hash1 = ((PyASCIIObject*)s1)->hash; - hash2 = ((PyASCIIObject*)s2)->hash; - #else - hash1 = ((PyUnicodeObject*)s1)->hash; - hash2 = ((PyUnicodeObject*)s2)->hash; - #endif - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - goto return_ne; + Py_ssize_t b_dictoffset = 0; +#if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + b_dictoffset = b->tp_dictoffset; +#else + PyObject *py_b_dictoffset = PyObject_GetAttrString((PyObject*)b, "__dictoffset__"); + if (!py_b_dictoffset) goto dictoffset_return; + b_dictoffset = PyLong_AsSsize_t(py_b_dictoffset); + Py_DECREF(py_b_dictoffset); + if (b_dictoffset == -1 && PyErr_Occurred()) goto dictoffset_return; +#endif + if (b_dictoffset) { + { + __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); + PyErr_Format(PyExc_TypeError, + "extension type '%.200s' has no __dict__ slot, " + "but base type '" __Pyx_FMT_TYPENAME "' has: " + "either add 'cdef dict __dict__' to the extension type " + "or add '__slots__ = [...]' to the base type", + type_name, b_name); + __Pyx_DECREF_TypeName(b_name); + } +#if !(CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY) + dictoffset_return: +#endif +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; } } +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); #endif - kind = __Pyx_PyUnicode_KIND(s1); - if (kind != __Pyx_PyUnicode_KIND(s2)) { - goto return_ne; - } - data1 = __Pyx_PyUnicode_DATA(s1); - data2 = __Pyx_PyUnicode_DATA(s2); - if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { - goto return_ne; - } else if (length == 1) { - goto return_eq; - } else { - int result = memcmp(data1, data2, (size_t)(length * kind)); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & s2_is_unicode) { - goto return_ne; - } else if ((s2 == Py_None) & s1_is_unicode) { - goto return_ne; - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); + } + return 0; +} +#endif + +/* PyType_Ready */ + static int __Pyx_PyType_Ready(PyTypeObject *t) { +#if CYTHON_USE_TYPE_SPECS || !(CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API) || defined(PYSTON_MAJOR_VERSION) + (void)__Pyx_PyObject_CallMethod0; +#if CYTHON_USE_TYPE_SPECS + (void)__Pyx_validate_bases_tuple; +#endif + return PyType_Ready(t); +#else + int r; + PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*); + if (bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, bases) == -1)) + return -1; +#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) + { + int gc_was_enabled; + #if PY_VERSION_HEX >= 0x030A00b1 + gc_was_enabled = PyGC_Disable(); + (void)__Pyx_PyObject_CallMethod0; + #else + PyObject *ret, *py_status; + PyObject *gc = NULL; + #if PY_VERSION_HEX >= 0x030700a1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM+0 >= 0x07030400) + gc = PyImport_GetModule(__pyx_kp_u_gc); #endif - if (!py_result) + if (unlikely(!gc)) gc = PyImport_Import(__pyx_kp_u_gc); + if (unlikely(!gc)) return -1; + py_status = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_isenabled); + if (unlikely(!py_status)) { + Py_DECREF(gc); return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -return_eq: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); + } + gc_was_enabled = __Pyx_PyObject_IsTrue(py_status); + Py_DECREF(py_status); + if (gc_was_enabled > 0) { + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_disable); + if (unlikely(!ret)) { + Py_DECREF(gc); + return -1; + } + Py_DECREF(ret); + } else if (unlikely(gc_was_enabled == -1)) { + Py_DECREF(gc); + return -1; + } #endif - return (equals == Py_EQ); -return_ne: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); + t->tp_flags |= Py_TPFLAGS_HEAPTYPE; +#if PY_VERSION_HEX >= 0x030A0000 + t->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; +#endif +#else + (void)__Pyx_PyObject_CallMethod0; +#endif + r = PyType_Ready(t); +#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) + t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; + #if PY_VERSION_HEX >= 0x030A00b1 + if (gc_was_enabled) + PyGC_Enable(); + #else + if (gc_was_enabled) { + PyObject *tp, *v, *tb; + PyErr_Fetch(&tp, &v, &tb); + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_enable); + if (likely(ret || r == -1)) { + Py_XDECREF(ret); + PyErr_Restore(tp, v, tb); + } else { + Py_XDECREF(tp); + Py_XDECREF(v); + Py_XDECREF(tb); + r = -1; + } + } + Py_DECREF(gc); #endif - return (equals == Py_NE); + } +#endif + return r; #endif } -/* DivInt[Py_ssize_t] */ - static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) { - Py_ssize_t q = a / b; - Py_ssize_t r = a - q*b; - q -= ((r != 0) & ((r ^ b) < 0)); - return q; +/* SetVTable */ + static int __Pyx_SetVtable(PyTypeObject *type, void *vtable) { + PyObject *ob = PyCapsule_New(vtable, 0, 0); + if (unlikely(!ob)) + goto bad; +#if CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(PyObject_SetAttr((PyObject *) type, __pyx_n_s_pyx_vtable, ob) < 0)) +#else + if (unlikely(PyDict_SetItem(type->tp_dict, __pyx_n_s_pyx_vtable, ob) < 0)) +#endif + goto bad; + Py_DECREF(ob); + return 0; +bad: + Py_XDECREF(ob); + return -1; } -/* GetAttr */ - static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { -#if CYTHON_USE_TYPE_SLOTS -#if PY_MAJOR_VERSION >= 3 - if (likely(PyUnicode_Check(n))) +/* GetVTable */ + static void* __Pyx_GetVtable(PyTypeObject *type) { + void* ptr; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *ob = PyObject_GetAttr((PyObject *)type, __pyx_n_s_pyx_vtable); #else - if (likely(PyString_Check(n))) -#endif - return __Pyx_PyObject_GetAttrStr(o, n); + PyObject *ob = PyObject_GetItem(type->tp_dict, __pyx_n_s_pyx_vtable); #endif - return PyObject_GetAttr(o, n); + if (!ob) + goto bad; + ptr = PyCapsule_GetPointer(ob, 0); + if (!ptr && !PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type"); + Py_DECREF(ob); + return ptr; +bad: + Py_XDECREF(ob); + return NULL; } -/* GetItemInt */ - static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (!j) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); +/* MergeVTables */ + #if !CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_MergeVtables(PyTypeObject *type) { + int i; + void** base_vtables; + __Pyx_TypeName tp_base_name; + __Pyx_TypeName base_name; + void* unknown = (void*)-1; + PyObject* bases = type->tp_bases; + int base_depth = 0; + { + PyTypeObject* base = type->tp_base; + while (base) { + base_depth += 1; + base = base->tp_base; + } } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; + base_vtables = (void**) malloc(sizeof(void*) * (size_t)(base_depth + 1)); + base_vtables[0] = unknown; + for (i = 1; i < PyTuple_GET_SIZE(bases); i++) { + void* base_vtable = __Pyx_GetVtable(((PyTypeObject*)PyTuple_GET_ITEM(bases, i))); + if (base_vtable != NULL) { + int j; + PyTypeObject* base = type->tp_base; + for (j = 0; j < base_depth; j++) { + if (base_vtables[j] == unknown) { + base_vtables[j] = __Pyx_GetVtable(base); + base_vtables[j + 1] = unknown; + } + if (base_vtables[j] == base_vtable) { + break; + } else if (base_vtables[j] == NULL) { + goto bad; + } + base = base->tp_base; + } + } } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); + PyErr_Clear(); + free(base_vtables); + return 0; +bad: + tp_base_name = __Pyx_PyType_GetName(type->tp_base); + base_name = __Pyx_PyType_GetName((PyTypeObject*)PyTuple_GET_ITEM(bases, i)); + PyErr_Format(PyExc_TypeError, + "multiple bases have vtable conflict: '" __Pyx_FMT_TYPENAME "' and '" __Pyx_FMT_TYPENAME "'", tp_base_name, base_name); + __Pyx_DECREF_TypeName(tp_base_name); + __Pyx_DECREF_TypeName(base_name); + free(base_vtables); + return -1; +} #endif + +/* SetupReduce */ + #if !CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { + int ret; + PyObject *name_attr; + name_attr = __Pyx_PyObject_GetAttrStrNoError(meth, __pyx_n_s_name_2); + if (likely(name_attr)) { + ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); + } else { + ret = -1; + } + if (unlikely(ret < 0)) { + PyErr_Clear(); + ret = 0; + } + Py_XDECREF(name_attr); + return ret; } -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; +static int __Pyx_setup_reduce(PyObject* type_obj) { + int ret = 0; + PyObject *object_reduce = NULL; + PyObject *object_getstate = NULL; + PyObject *object_reduce_ex = NULL; + PyObject *reduce = NULL; + PyObject *reduce_ex = NULL; + PyObject *reduce_cython = NULL; + PyObject *setstate = NULL; + PyObject *setstate_cython = NULL; + PyObject *getstate = NULL; +#if CYTHON_USE_PYTYPE_LOOKUP + getstate = _PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate); +#else + getstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_getstate); + if (!getstate && PyErr_Occurred()) { + goto __PYX_BAD; } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#endif + if (getstate) { +#if CYTHON_USE_PYTYPE_LOOKUP + object_getstate = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_getstate); #else - return PySequence_GetItem(o, i); + object_getstate = __Pyx_PyObject_GetAttrStrNoError((PyObject*)&PyBaseObject_Type, __pyx_n_s_getstate); + if (!object_getstate && PyErr_Occurred()) { + goto __PYX_BAD; + } #endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; + if (object_getstate != getstate) { + goto __PYX_GOOD; } } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#else + object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#endif + reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; + if (reduce_ex == object_reduce_ex) { +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#else + object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#endif + reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; + if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { + reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); + if (likely(reduce_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (reduce == object_reduce || PyErr_Occurred()) { + goto __PYX_BAD; + } + setstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate); + if (!setstate) PyErr_Clear(); + if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { + setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); + if (likely(setstate_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (!setstate || PyErr_Occurred()) { + goto __PYX_BAD; } } - return m->sq_item(o, i); + PyType_Modified((PyTypeObject*)type_obj); } } -#else - if (is_list || PySequence_Check(o)) { - return PySequence_GetItem(o, i); + goto __PYX_GOOD; +__PYX_BAD: + if (!PyErr_Occurred()) { + __Pyx_TypeName type_obj_name = + __Pyx_PyType_GetName((PyTypeObject*)type_obj); + PyErr_Format(PyExc_RuntimeError, + "Unable to initialize pickling for " __Pyx_FMT_TYPENAME, type_obj_name); + __Pyx_DECREF_TypeName(type_obj_name); } + ret = -1; +__PYX_GOOD: +#if !CYTHON_USE_PYTYPE_LOOKUP + Py_XDECREF(object_reduce); + Py_XDECREF(object_reduce_ex); + Py_XDECREF(object_getstate); + Py_XDECREF(getstate); #endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* ObjectGetItem */ - #if CYTHON_USE_TYPE_SLOTS -static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) { - PyObject *runerr = NULL; - Py_ssize_t key_value; - PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence; - if (unlikely(!(m && m->sq_item))) { - PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name); - return NULL; - } - key_value = __Pyx_PyIndex_AsSsize_t(index); - if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { - return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); - } - if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { - PyErr_Clear(); - PyErr_Format(PyExc_IndexError, "cannot fit '%.200s' into an index-sized integer", Py_TYPE(index)->tp_name); - } - return NULL; -} -static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { - PyMappingMethods *m = Py_TYPE(obj)->tp_as_mapping; - if (likely(m && m->mp_subscript)) { - return m->mp_subscript(obj, key); - } - return __Pyx_PyObject_GetIndex(obj, key); + Py_XDECREF(reduce); + Py_XDECREF(reduce_ex); + Py_XDECREF(reduce_cython); + Py_XDECREF(setstate); + Py_XDECREF(setstate_cython); + return ret; } #endif -/* decode_c_string */ - static CYTHON_INLINE PyObject* __Pyx_decode_c_string( - const char* cstring, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { - Py_ssize_t length; - if (unlikely((start < 0) | (stop < 0))) { - size_t slen = strlen(cstring); - if (unlikely(slen > (size_t) PY_SSIZE_T_MAX)) { - PyErr_SetString(PyExc_OverflowError, - "c-string too long to convert to Python"); - return NULL; - } - length = (Py_ssize_t) slen; - if (start < 0) { - start += length; - if (start < 0) - start = 0; - } - if (stop < 0) - stop += length; - } - if (unlikely(stop <= start)) - return __Pyx_NewRef(__pyx_empty_unicode); - length = stop - start; - cstring += start; - if (decode_func) { - return decode_func(cstring, length, errors); - } else { - return PyUnicode_Decode(cstring, length, encoding, errors); - } -} - -/* GetAttr3 */ - static PyObject *__Pyx_GetAttr3Default(PyObject *d) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - return NULL; - __Pyx_PyErr_Clear(); - Py_INCREF(d); - return d; -} -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { - PyObject *r = __Pyx_GetAttr(o, n); - return (likely(r)) ? r : __Pyx_GetAttr3Default(d); -} - -/* RaiseTooManyValuesToUnpack */ - static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); -} - -/* RaiseNeedMoreValuesToUnpack */ - static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { - PyErr_Format(PyExc_ValueError, - "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", - index, (index == 1) ? "" : "s"); -} - -/* RaiseNoneIterError */ - static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); -} - -/* ExtTypeTest */ - static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - if (likely(__Pyx_TypeCheck(obj, type))) - return 1; - PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", - Py_TYPE(obj)->tp_name, type->tp_name); - return 0; -} - -/* SwapException */ - #if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = *type; - exc_info->exc_value = *value; - exc_info->exc_traceback = *tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = *type; - tstate->exc_value = *value; - tstate->exc_traceback = *tb; - #endif - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); - PyErr_SetExcInfo(*type, *value, *tb); - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} +/* TypeImport */ + #ifndef __PYX_HAVE_RT_ImportType_3_0_10 +#define __PYX_HAVE_RT_ImportType_3_0_10 +static PyTypeObject *__Pyx_ImportType_3_0_10(PyObject *module, const char *module_name, const char *class_name, + size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_3_0_10 check_size) +{ + PyObject *result = 0; + char warning[200]; + Py_ssize_t basicsize; + Py_ssize_t itemsize; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + PyObject *py_itemsize; #endif - -/* Import */ - static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *empty_list = 0; - PyObject *module = 0; - PyObject *global_dict = 0; - PyObject *empty_dict = 0; - PyObject *list; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (!py_import) + result = PyObject_GetAttrString(module, class_name); + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); goto bad; - #endif - if (from_list) - list = from_list; - else { - empty_list = PyList_New(0); - if (!empty_list) - goto bad; - list = empty_list; } - global_dict = PyModule_GetDict(__pyx_m); - if (!global_dict) +#if !CYTHON_COMPILING_IN_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; + itemsize = ((PyTypeObject *)result)->tp_itemsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) goto bad; - empty_dict = PyDict_New(); - if (!empty_dict) + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, 1); - if (!module) { - if (!PyErr_ExceptionMatches(PyExc_ImportError)) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (!py_level) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, level); - #endif + py_itemsize = PyObject_GetAttrString(result, "__itemsize__"); + if (!py_itemsize) + goto bad; + itemsize = PyLong_AsSsize_t(py_itemsize); + Py_DECREF(py_itemsize); + py_itemsize = 0; + if (itemsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if (itemsize) { + if (size % alignment) { + alignment = size % alignment; } + if (itemsize < (Py_ssize_t)alignment) + itemsize = (Py_ssize_t)alignment; + } + if ((size_t)(basicsize + itemsize) < size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize+itemsize); + goto bad; + } + if (check_size == __Pyx_ImportType_CheckSize_Error_3_0_10 && + ((size_t)basicsize > size || (size_t)(basicsize + itemsize) < size)) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd-%zd from PyObject", + module_name, class_name, size, basicsize, basicsize+itemsize); + goto bad; + } + else if (check_size == __Pyx_ImportType_CheckSize_Warn_3_0_10 && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; } + return (PyTypeObject *)result; bad: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - Py_XDECREF(empty_list); - Py_XDECREF(empty_dict); - return module; + Py_XDECREF(result); + return NULL; } +#endif -/* FastTypeChecks */ - #if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); +/* FetchSharedCythonModule */ + static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef((char*) __PYX_ABI_MODULE_NAME); } -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; + +/* FetchCommonType */ + static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t basicsize, + Py_ssize_t expected_basicsize) { + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { + PyObject* abi_module; + const char* object_name; + PyTypeObject *cached_type = NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + object_name = strrchr(type->tp_name, '.'); + object_name = object_name ? object_name+1 : type->tp_name; + cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + if (__Pyx_VerifyCachedType( + (PyObject *)cached_type, + object_name, + cached_type->tp_basicsize, + type->tp_basicsize) < 0) { + goto bad; } + goto done; } - __Pyx_ErrRestore(exception, value, tb); - return res; + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + if (PyType_Ready(type) < 0) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0) + goto bad; + Py_INCREF(type); + cached_type = type; +done: + Py_DECREF(abi_module); + return cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; } #else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module, *cached_type = NULL; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + cached_type = PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + Py_ssize_t basicsize; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; +#else + basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1; +#endif + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + basicsize, + spec->basicsize) < 0) { + goto bad; + } + goto done; } - return res; + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + CYTHON_UNUSED_VAR(module); + cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad; +done: + Py_DECREF(abi_module); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; } #endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; itp_flags; + Py_INCREF(key); + Py_INCREF(value); + PyTuple_SET_ITEM(kwnames, i, key); + kwvalues[i] = value; + i++; } - return PyErr_GivenExceptionMatches(err, exc_type); + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; } -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *exc_type1, PyObject *exc_type2) { - assert(PyExceptionClass_Check(exc_type1)); - assert(PyExceptionClass_Check(exc_type2)); - if (likely(err == exc_type1 || err == exc_type2)) return 1; - if (likely(PyExceptionClass_Check(err))) { - return __Pyx_inner_PyErr_GivenExceptionMatches2(err, exc_type1, exc_type2); +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) { + return vc(func, args, nargs, NULL); } - return (PyErr_GivenExceptionMatches(err, exc_type1) || PyErr_GivenExceptionMatches(err, exc_type2)); + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); } #endif -/* PyIntBinop */ - #if !CYTHON_COMPILING_IN_PYPY -static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, int inplace, int zerodivision_check) { - (void)inplace; - (void)zerodivision_check; - #if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(op1))) { - const long b = intval; - long x; - long a = PyInt_AS_LONG(op1); - x = (long)((unsigned long)a + b); - if (likely((x^a) >= 0 || (x^b) >= 0)) - return PyInt_FromLong(x); - return PyLong_Type.tp_as_number->nb_add(op1, op2); +/* CythonFunctionShared */ + #if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; } - #endif - #if CYTHON_USE_PYLONG_INTERNALS - if (likely(PyLong_CheckExact(op1))) { - const long b = intval; - long a, x; -#ifdef HAVE_LONG_LONG - const PY_LONG_LONG llb = intval; - PY_LONG_LONG lla, llx; -#endif - const digit* digits = ((PyLongObject*)op1)->ob_digit; - const Py_ssize_t size = Py_SIZE(op1); - if (likely(__Pyx_sst_abs(size) <= 1)) { - a = likely(size) ? digits[0] : 0; - if (size == -1) a = -a; - } else { - switch (size) { - case -2: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 2: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case -3: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 3: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; + return 0; +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} #endif - } - CYTHON_FALLTHROUGH; - case -4: - if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); #endif - } - CYTHON_FALLTHROUGH; - case 4: - if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) +{ + CYTHON_UNUSED_VAR(closure); + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { +#if PY_MAJOR_VERSION >= 3 + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#else + op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); #endif - } - CYTHON_FALLTHROUGH; - default: return PyLong_Type.tp_as_number->nb_add(op1, op2); - } + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; } - x = a + b; - return PyLong_FromLong(x); -#ifdef HAVE_LONG_LONG - long_long: - llx = lla + llb; - return PyLong_FromLongLong(llx); #endif - - } - #endif - if (PyFloat_CheckExact(op1)) { - const long b = intval; - double a = PyFloat_AS_DOUBLE(op1); - double result; - PyFPE_START_PROTECT("add", return NULL) - result = ((double)a) + (double)b; - PyFPE_END_PROTECT(result) - return PyFloat_FromDouble(result); + Py_INCREF(op->func_doc); + return op->func_doc; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; } - return (inplace ? PyNumber_InPlaceAdd : PyNumber_Add)(op1, op2); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + return 0; } +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#elif PY_MAJOR_VERSION >= 3 + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#else + op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); #endif - -/* None */ - static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) { - PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname); -} - -/* DivInt[long] */ - static CYTHON_INLINE long __Pyx_div_long(long a, long b) { - long q = a / b; - long r = a - q*b; - q -= ((r != 0) & ((r ^ b) < 0)); - return q; -} - -/* ImportFrom */ - static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { - PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); - if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_ImportError, - #if PY_MAJOR_VERSION < 3 - "cannot import name %.230s", PyString_AS_STRING(name)); - #else - "cannot import name %S", name); - #endif + if (unlikely(op->func_name == NULL)) + return NULL; } - return value; + Py_INCREF(op->func_name); + return op->func_name; } - -/* HasAttr */ - static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { - PyObject *r; - if (unlikely(!__Pyx_PyBaseString_Check(n))) { +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { PyErr_SetString(PyExc_TypeError, - "hasattr(): attribute name must be string"); + "__name__ must be set to a string object"); return -1; } - r = __Pyx_GetAttr(o, n); - if (unlikely(!r)) { - PyErr_Clear(); - return 0; - } else { - Py_DECREF(r); - return 1; - } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_name, value); + return 0; } - -/* PyObject_GenericGetAttrNoDict */ - #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { - PyErr_Format(PyExc_AttributeError, +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_qualname); + return op->func_qualname; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); #if PY_MAJOR_VERSION >= 3 - "'%.50s' object has no attribute '%U'", - tp->tp_name, attr_name); + if (unlikely(value == NULL || !PyUnicode_Check(value))) #else - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(attr_name)); + if (unlikely(value == NULL || !PyString_Check(value))) #endif - return NULL; + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + return 0; } -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { - PyObject *descr; - PyTypeObject *tp = Py_TYPE(obj); - if (unlikely(!PyString_Check(attr_name))) { - return PyObject_GenericGetAttr(obj, attr_name); +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; } - assert(!tp->tp_dictoffset); - descr = _PyType_Lookup(tp, attr_name); - if (unlikely(!descr)) { - return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); + Py_INCREF(op->func_dict); + return op->func_dict; +} +static int +__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL)) { + PyErr_SetString(PyExc_TypeError, + "function's dictionary may not be deleted"); + return -1; + } + if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "setting function's dictionary to a non-dict"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_dict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; } - Py_INCREF(descr); - #if PY_MAJOR_VERSION < 3 - if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) #endif - { - descrgetfunc f = Py_TYPE(descr)->tp_descr_get; - if (unlikely(f)) { - PyObject *res = f(descr, obj, (PyObject *)tp); - Py_DECREF(descr); - return res; + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_tuple; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; } } - return descr; + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_kwdict; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->func_annotations; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; } +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + int is_coroutine; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; +#if PY_VERSION_HEX >= 0x03050000 + if (is_coroutine) { + PyObject *module, *fromlist, *marker = __pyx_n_s_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(marker); + Py_DECREF(fromlist); + return NULL; + } #endif - -/* PyObject_GenericGetAttr */ - #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { - if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { - return PyObject_GenericGetAttr(obj, attr_name); + module = PyImport_ImportModuleLevelObject(__pyx_n_s_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + op->func_is_coroutine = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(op->func_is_coroutine)) { + return __Pyx_NewRef(op->func_is_coroutine); + } +ignore: + PyErr_Clear(); } - return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); +#endif + op->func_is_coroutine = __Pyx_PyBool_FromLong(is_coroutine); + return __Pyx_NewRef(op->func_is_coroutine); +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); } +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, + {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {(char *) "_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if CYTHON_USE_TYPE_SPECS + {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#if CYTHON_METH_FASTCALL +#if CYTHON_BACKPORT_VECTORCALL + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, #endif - -/* SetVTable */ - static int __Pyx_SetVtable(PyObject *dict, void *vtable) { -#if PY_VERSION_HEX >= 0x02070000 - PyObject *ob = PyCapsule_New(vtable, 0, 0); +#endif +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, #else - PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + CYTHON_UNUSED_VAR(args); +#if PY_MAJOR_VERSION >= 3 + Py_INCREF(m->func_qualname); + return m->func_qualname; +#else + return PyString_FromString(((PyCFunctionObject*)m)->m_ml->ml_name); #endif - if (!ob) - goto bad; - if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0) - goto bad; - Py_DECREF(ob); - return 0; -bad: - Py_XDECREF(ob); - return -1; } - -/* PyObjectGetAttrStrNoError */ - static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - __Pyx_PyErr_Clear(); +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif + op->func_dict = NULL; + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults_pyobjects = 0; + op->defaults_size = 0; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; } -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { - PyObject *result; -#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { - return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif + Py_CLEAR(m->func_dict); + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API +#if PY_VERSION_HEX < 0x030900B1 + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); } #endif - result = __Pyx_PyObject_GetAttrStr(obj, attr_name); - if (unlikely(!result)) { - __Pyx_PyObject_GetAttrStr_ClearAttributeError(); +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_XDECREF(pydefaults[i]); + PyObject_Free(m->defaults); + m->defaults = NULL; } - return result; + return 0; } - -/* SetupReduce */ - static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { - int ret; - PyObject *name_attr; - name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name_2); - if (likely(name_attr)) { - ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); - } else { - ret = -1; - } - if (unlikely(ret < 0)) { - PyErr_Clear(); - ret = 0; - } - Py_XDECREF(name_attr); - return ret; +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); } -static int __Pyx_setup_reduce(PyObject* type_obj) { - int ret = 0; - PyObject *object_reduce = NULL; - PyObject *object_getstate = NULL; - PyObject *object_reduce_ex = NULL; - PyObject *reduce = NULL; - PyObject *reduce_ex = NULL; - PyObject *reduce_cython = NULL; - PyObject *setstate = NULL; - PyObject *setstate_cython = NULL; - PyObject *getstate = NULL; -#if CYTHON_USE_PYTYPE_LOOKUP - getstate = _PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate); +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); #else - getstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_getstate); - if (!getstate && PyErr_Occurred()) { - goto __PYX_BAD; + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif + Py_VISIT(m->func_dict); + Py_VISIT(m->func_name); + Py_VISIT(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + Py_VISIT(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); +#endif + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_VISIT(pydefaults[i]); } -#endif - if (getstate) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_getstate = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_getstate); + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromFormat("", + op->func_qualname, (void *)op); #else - object_getstate = __Pyx_PyObject_GetAttrStrNoError((PyObject*)&PyBaseObject_Type, __pyx_n_s_getstate); - if (!object_getstate && PyErr_Occurred()) { - goto __PYX_BAD; + return PyString_FromFormat("", + PyString_AsString(op->func_qualname), (void *)op); +#endif +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyObject *py_name = NULL; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); #endif - if (object_getstate != getstate) { - goto __PYX_GOOD; + return NULL; } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; } -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, "%.200S() takes no keyword arguments", + py_name); + Py_DECREF(py_name); #else - object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + f->m_ml->ml_name); #endif - reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; - if (reduce_ex == object_reduce_ex) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; #else - object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); #endif - reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; - if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { - reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); - if (likely(reduce_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (reduce == object_reduce || PyErr_Occurred()) { - goto __PYX_BAD; - } - setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); - if (!setstate) PyErr_Clear(); - if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { - setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); - if (likely(setstate_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (!setstate || PyErr_Occurred()) { - goto __PYX_BAD; - } - } - PyType_Modified((PyTypeObject*)type_obj); - } } - goto __PYX_GOOD; -__PYX_BAD: - if (!PyErr_Occurred()) - PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); - ret = -1; -__PYX_GOOD: -#if !CYTHON_USE_PYTYPE_LOOKUP - Py_XDECREF(object_reduce); - Py_XDECREF(object_reduce_ex); - Py_XDECREF(object_getstate); - Py_XDECREF(getstate); #endif - Py_XDECREF(reduce); - Py_XDECREF(reduce_ex); - Py_XDECREF(reduce_cython); - Py_XDECREF(setstate); - Py_XDECREF(setstate_cython); + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_MACROS + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(!argc) < 0) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); +#if PY_MAJOR_VERSION > 2 + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); +#else + PyErr_SetString(PyExc_TypeError, + "unbound method needs an argument"); +#endif + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + PyErr_Format(PyExc_TypeError, "%.200s() needs an argument", + ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } return ret; } - -/* TypeImport */ - #ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, - size_t size, enum __Pyx_ImportType_CheckSize check_size) +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - PyObject *result = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - result = PyObject_GetAttrString(module, class_name); - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; + return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, (size_t)nargs, kwnames); +} +#endif +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if (defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; #else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; +static PyTypeObject __pyx_CyFunctionType_type = { + PyVarObject_HEAD_INIT(0, 0) + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, + (destructor) __Pyx_CyFunction_dealloc, +#if !CYTHON_METH_FASTCALL + 0, +#elif CYTHON_BACKPORT_VECTORCALL + (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), +#else + offsetof(PyCFunctionObject, vectorcall), #endif - if ((size_t)basicsize < size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; + 0, + 0, +#if PY_MAJOR_VERSION < 3 + 0, +#else + 0, +#endif + (reprfunc) __Pyx_CyFunction_repr, + 0, + 0, + 0, + 0, + __Pyx_CyFunction_CallAsMethod, + 0, + 0, + 0, + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + 0, + (traverseproc) __Pyx_CyFunction_traverse, + (inquiry) __Pyx_CyFunction_clear, + 0, +#if PY_VERSION_HEX < 0x030500A0 + offsetof(__pyx_CyFunctionObject, func_weakreflist), +#else + offsetof(PyCFunctionObject, m_weakreflist), +#endif + 0, + 0, + __pyx_CyFunction_methods, + __pyx_CyFunction_members, + __pyx_CyFunction_getsets, + 0, + 0, + __Pyx_PyMethod_New, + 0, + offsetof(__pyx_CyFunctionObject, func_dict), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if __PYX_NEED_TP_PRINT_SLOT + 0, +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, +#endif +}; +#endif +static int __pyx_CyFunction_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL); +#else + CYTHON_UNUSED_VAR(module); + __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); +#endif + if (unlikely(__pyx_CyFunctionType == NULL)) { + return -1; } - else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + return 0; +} +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_Malloc(size); + if (unlikely(!m->defaults)) + return PyErr_NoMemory(); + memset(m->defaults, 0, size); + m->defaults_pyobjects = pyobjects; + m->defaults_size = size; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ + static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); } - return (PyTypeObject *)result; -bad: - Py_XDECREF(result); - return NULL; + return op; } -#endif /* CLineInTraceback */ #ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) { +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { PyObject *use_cline; PyObject *ptype, *pvalue, *ptraceback; #if CYTHON_COMPILING_IN_CPYTHON PyObject **cython_runtime_dict; #endif + CYTHON_MAYBE_UNUSED_VAR(tstate); if (unlikely(!__pyx_cython_runtime)) { return c_line; } @@ -21765,7 +27392,7 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li } else #endif { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); if (use_cline_obj) { use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; Py_DECREF(use_cline_obj); @@ -21787,7 +27414,8 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li #endif /* CodeObjectCache */ - static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + #if !CYTHON_COMPILING_IN_LIMITED_API +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { int start = 0, mid = 0, end = count - 1; if (end >= 0 && code_line > entries[end].code_line) { return count; @@ -21865,17 +27493,101 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { __pyx_code_cache.count++; Py_INCREF(code_object); } +#endif /* AddTraceback */ #include "compile.h" #include "frameobject.h" #include "traceback.h" -#if PY_VERSION_HEX >= 0x030b00a6 +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API #ifndef Py_BUILD_CORE #define Py_BUILD_CORE 1 #endif #include "internal/pycore_frame.h" #endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result; + result = PyObject_Call(replace, __pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + #if __PYX_LIMITED_VERSION_HEX < 0x030780000 + { + PyObject *compiled = NULL, *result = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "code", code))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "type", (PyObject*)(&PyType_Type)))) return NULL; + compiled = Py_CompileString( + "out = type(code)(\n" + " code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize,\n" + " code.co_flags, code.co_code, code.co_consts, code.co_names,\n" + " code.co_varnames, code.co_filename, co_name, co_firstlineno,\n" + " code.co_lnotab)\n", "", Py_file_input); + if (!compiled) return NULL; + result = PyEval_EvalCode(compiled, scratch_dict, scratch_dict); + Py_DECREF(compiled); + if (!result) PyErr_Print(); + Py_DECREF(result); + result = PyDict_GetItemString(scratch_dict, "out"); + if (result) Py_INCREF(result); + return result; + } + #else + return NULL; + #endif +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + (void) __pyx_cfilenm; + (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + py_funcname = PyUnicode_FromString(funcname); + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( const char *funcname, int c_line, int py_line, const char *filename) { @@ -21910,6 +27622,7 @@ static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( 0, 0, 0, + 0, __pyx_empty_bytes, /*PyObject *code,*/ __pyx_empty_tuple, /*PyObject *consts,*/ __pyx_empty_tuple, /*PyObject *names,*/ @@ -21925,7 +27638,7 @@ static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( #else py_code = PyCode_NewEmpty(filename, funcname, py_line); #endif - Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline + Py_XDECREF(py_funcname); return py_code; bad: Py_XDECREF(py_funcname); @@ -21972,13 +27685,19 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line, Py_XDECREF(py_code); Py_XDECREF(py_frame); } +#endif #if PY_MAJOR_VERSION < 3 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { + __Pyx_TypeName obj_type_name; if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); if (__Pyx_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags); if (__Pyx_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags); - PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "'" __Pyx_FMT_TYPENAME "' does not have the buffer interface", + obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); return -1; } static void __Pyx_ReleaseBuffer(Py_buffer *view) { @@ -22053,19 +27772,6 @@ __pyx_slices_overlap(__Pyx_memviewslice *slice1, return (start1 < end2) && (start2 < end1); } -/* Capsule */ - static CYTHON_INLINE PyObject * -__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig) -{ - PyObject *cobj; -#if PY_VERSION_HEX >= 0x02070000 - cobj = PyCapsule_New(p, sig, NULL); -#else - cobj = PyCObject_FromVoidPtr(p, NULL); -#endif - return cobj; -} - /* TypeInfoCompare */ static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b) @@ -22162,8 +27868,9 @@ __pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec) return 0; } static int -__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec) +__pyx_check_suboffsets(Py_buffer *buf, int dim, int ndim, int spec) { + CYTHON_UNUSED_VAR(ndim); if (spec & __Pyx_MEMVIEW_DIRECT) { if (unlikely(buf->suboffsets && buf->suboffsets[dim] >= 0)) { PyErr_Format(PyExc_ValueError, @@ -22357,7 +28064,7 @@ static int __Pyx_ValidateAndInit_memviewslice( } /* Declarations */ - #if CYTHON_CCOMPLEX + #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) #ifdef __cplusplus static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { return ::std::complex< float >(x, y); @@ -22377,7 +28084,7 @@ static int __Pyx_ValidateAndInit_memviewslice( #endif /* Arithmetic */ - #if CYTHON_CCOMPLEX + #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) #else static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { return (a.real == b.real) && (a.imag == b.imag); @@ -22511,7 +28218,7 @@ static int __Pyx_ValidateAndInit_memviewslice( #endif /* Declarations */ - #if CYTHON_CCOMPLEX + #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) #ifdef __cplusplus static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { return ::std::complex< double >(x, y); @@ -22531,7 +28238,7 @@ static int __Pyx_ValidateAndInit_memviewslice( #endif /* Arithmetic */ - #if CYTHON_CCOMPLEX + #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) #else static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { return (a.real == b.real) && (a.imag == b.imag); @@ -22731,6 +28438,141 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, return new_mvs; } +/* MemviewSliceInit */ + static int +__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview, + int ndim, + __Pyx_memviewslice *memviewslice, + int memview_is_new_reference) +{ + __Pyx_RefNannyDeclarations + int i, retval=-1; + Py_buffer *buf = &memview->view; + __Pyx_RefNannySetupContext("init_memviewslice", 0); + if (unlikely(memviewslice->memview || memviewslice->data)) { + PyErr_SetString(PyExc_ValueError, + "memviewslice is already initialized!"); + goto fail; + } + if (buf->strides) { + for (i = 0; i < ndim; i++) { + memviewslice->strides[i] = buf->strides[i]; + } + } else { + Py_ssize_t stride = buf->itemsize; + for (i = ndim - 1; i >= 0; i--) { + memviewslice->strides[i] = stride; + stride *= buf->shape[i]; + } + } + for (i = 0; i < ndim; i++) { + memviewslice->shape[i] = buf->shape[i]; + if (buf->suboffsets) { + memviewslice->suboffsets[i] = buf->suboffsets[i]; + } else { + memviewslice->suboffsets[i] = -1; + } + } + memviewslice->memview = memview; + memviewslice->data = (char *)buf->buf; + if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) { + Py_INCREF(memview); + } + retval = 0; + goto no_fail; +fail: + memviewslice->memview = 0; + memviewslice->data = 0; + retval = -1; +no_fail: + __Pyx_RefNannyFinishContext(); + return retval; +} +#ifndef Py_NO_RETURN +#define Py_NO_RETURN +#endif +static void __pyx_fatalerror(const char *fmt, ...) Py_NO_RETURN { + va_list vargs; + char msg[200]; +#if PY_VERSION_HEX >= 0x030A0000 || defined(HAVE_STDARG_PROTOTYPES) + va_start(vargs, fmt); +#else + va_start(vargs); +#endif + vsnprintf(msg, 200, fmt, vargs); + va_end(vargs); + Py_FatalError(msg); +} +static CYTHON_INLINE int +__pyx_add_acquisition_count_locked(__pyx_atomic_int_type *acquisition_count, + PyThread_type_lock lock) +{ + int result; + PyThread_acquire_lock(lock, 1); + result = (*acquisition_count)++; + PyThread_release_lock(lock); + return result; +} +static CYTHON_INLINE int +__pyx_sub_acquisition_count_locked(__pyx_atomic_int_type *acquisition_count, + PyThread_type_lock lock) +{ + int result; + PyThread_acquire_lock(lock, 1); + result = (*acquisition_count)--; + PyThread_release_lock(lock); + return result; +} +static CYTHON_INLINE void +__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno) +{ + __pyx_nonatomic_int_type old_acquisition_count; + struct __pyx_memoryview_obj *memview = memslice->memview; + if (unlikely(!memview || (PyObject *) memview == Py_None)) { + return; + } + old_acquisition_count = __pyx_add_acquisition_count(memview); + if (unlikely(old_acquisition_count <= 0)) { + if (likely(old_acquisition_count == 0)) { + if (have_gil) { + Py_INCREF((PyObject *) memview); + } else { + PyGILState_STATE _gilstate = PyGILState_Ensure(); + Py_INCREF((PyObject *) memview); + PyGILState_Release(_gilstate); + } + } else { + __pyx_fatalerror("Acquisition count is %d (line %d)", + old_acquisition_count+1, lineno); + } + } +} +static CYTHON_INLINE void __Pyx_XCLEAR_MEMVIEW(__Pyx_memviewslice *memslice, + int have_gil, int lineno) { + __pyx_nonatomic_int_type old_acquisition_count; + struct __pyx_memoryview_obj *memview = memslice->memview; + if (unlikely(!memview || (PyObject *) memview == Py_None)) { + memslice->memview = NULL; + return; + } + old_acquisition_count = __pyx_sub_acquisition_count(memview); + memslice->data = NULL; + if (likely(old_acquisition_count > 1)) { + memslice->memview = NULL; + } else if (likely(old_acquisition_count == 1)) { + if (have_gil) { + Py_CLEAR(memslice->memview); + } else { + PyGILState_STATE _gilstate = PyGILState_Ensure(); + Py_CLEAR(memslice->memview); + PyGILState_Release(_gilstate); + } + } else { + __pyx_fatalerror("Acquisition count is %d (line %d)", + old_acquisition_count-1, lineno); + } +} + /* CIntToPy */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_npy_int64(npy_int64 value) { #ifdef __Pyx_HAS_GCC_DIAGNOSTIC @@ -22764,8 +28606,34 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 return _PyLong_FromByteArray(bytes, sizeof(npy_int64), little, !is_unsigned); +#else + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(npy_int64)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif } } @@ -22782,7 +28650,7 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { - if (sizeof(npy_int64) < sizeof(long)) { + if ((sizeof(npy_int64) < sizeof(long))) { __PYX_VERIFY_RETURN_INT(npy_int64, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); @@ -22796,40 +28664,45 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (npy_int64) 0; - case 1: __PYX_VERIFY_RETURN_INT(npy_int64, digit, digits[0]) - case 2: - if (8 * sizeof(npy_int64) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(npy_int64) >= 2 * PyLong_SHIFT) { - return (npy_int64) (((((npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0])); + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(npy_int64, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(npy_int64) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(npy_int64) >= 2 * PyLong_SHIFT)) { + return (npy_int64) (((((npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0])); + } } - } - break; - case 3: - if (8 * sizeof(npy_int64) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(npy_int64) >= 3 * PyLong_SHIFT) { - return (npy_int64) (((((((npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0])); + break; + case 3: + if ((8 * sizeof(npy_int64) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(npy_int64) >= 3 * PyLong_SHIFT)) { + return (npy_int64) (((((((npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0])); + } } - } - break; - case 4: - if (8 * sizeof(npy_int64) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(npy_int64) >= 4 * PyLong_SHIFT) { - return (npy_int64) (((((((((npy_int64)digits[3]) << PyLong_SHIFT) | (npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0])); + break; + case 4: + if ((8 * sizeof(npy_int64) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(npy_int64) >= 4 * PyLong_SHIFT)) { + return (npy_int64) (((((((((npy_int64)digits[3]) << PyLong_SHIFT) | (npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0])); + } } - } - break; + break; + } } #endif -#if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } @@ -22842,109 +28715,181 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, goto raise_neg_overflow; } #endif - if (sizeof(npy_int64) <= sizeof(unsigned long)) { + if ((sizeof(npy_int64) <= sizeof(unsigned long))) { __PYX_VERIFY_RETURN_INT_EXC(npy_int64, unsigned long, PyLong_AsUnsignedLong(x)) #ifdef HAVE_LONG_LONG - } else if (sizeof(npy_int64) <= sizeof(unsigned PY_LONG_LONG)) { + } else if ((sizeof(npy_int64) <= sizeof(unsigned PY_LONG_LONG))) { __PYX_VERIFY_RETURN_INT_EXC(npy_int64, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) #endif } } else { #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (npy_int64) 0; - case -1: __PYX_VERIFY_RETURN_INT(npy_int64, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(npy_int64, digit, +digits[0]) - case -2: - if (8 * sizeof(npy_int64) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(npy_int64, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(npy_int64) - 1 > 2 * PyLong_SHIFT) { - return (npy_int64) (((npy_int64)-1)*(((((npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(npy_int64, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(npy_int64) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(npy_int64, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(npy_int64) - 1 > 2 * PyLong_SHIFT)) { + return (npy_int64) (((npy_int64)-1)*(((((npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + } } - } - break; - case 2: - if (8 * sizeof(npy_int64) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(npy_int64) - 1 > 2 * PyLong_SHIFT) { - return (npy_int64) ((((((npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + break; + case 2: + if ((8 * sizeof(npy_int64) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(npy_int64) - 1 > 2 * PyLong_SHIFT)) { + return (npy_int64) ((((((npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + } } - } - break; - case -3: - if (8 * sizeof(npy_int64) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(npy_int64, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(npy_int64) - 1 > 3 * PyLong_SHIFT) { - return (npy_int64) (((npy_int64)-1)*(((((((npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + break; + case -3: + if ((8 * sizeof(npy_int64) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(npy_int64, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(npy_int64) - 1 > 3 * PyLong_SHIFT)) { + return (npy_int64) (((npy_int64)-1)*(((((((npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + } } - } - break; - case 3: - if (8 * sizeof(npy_int64) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(npy_int64) - 1 > 3 * PyLong_SHIFT) { - return (npy_int64) ((((((((npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + break; + case 3: + if ((8 * sizeof(npy_int64) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(npy_int64) - 1 > 3 * PyLong_SHIFT)) { + return (npy_int64) ((((((((npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + } } - } - break; - case -4: - if (8 * sizeof(npy_int64) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(npy_int64, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(npy_int64) - 1 > 4 * PyLong_SHIFT) { - return (npy_int64) (((npy_int64)-1)*(((((((((npy_int64)digits[3]) << PyLong_SHIFT) | (npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + break; + case -4: + if ((8 * sizeof(npy_int64) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(npy_int64, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(npy_int64) - 1 > 4 * PyLong_SHIFT)) { + return (npy_int64) (((npy_int64)-1)*(((((((((npy_int64)digits[3]) << PyLong_SHIFT) | (npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + } } - } - break; - case 4: - if (8 * sizeof(npy_int64) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(npy_int64) - 1 > 4 * PyLong_SHIFT) { - return (npy_int64) ((((((((((npy_int64)digits[3]) << PyLong_SHIFT) | (npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + break; + case 4: + if ((8 * sizeof(npy_int64) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(npy_int64) - 1 > 4 * PyLong_SHIFT)) { + return (npy_int64) ((((((((((npy_int64)digits[3]) << PyLong_SHIFT) | (npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); + } } - } - break; + break; + } } #endif - if (sizeof(npy_int64) <= sizeof(long)) { + if ((sizeof(npy_int64) <= sizeof(long))) { __PYX_VERIFY_RETURN_INT_EXC(npy_int64, long, PyLong_AsLong(x)) #ifdef HAVE_LONG_LONG - } else if (sizeof(npy_int64) <= sizeof(PY_LONG_LONG)) { + } else if ((sizeof(npy_int64) <= sizeof(PY_LONG_LONG))) { __PYX_VERIFY_RETURN_INT_EXC(npy_int64, PY_LONG_LONG, PyLong_AsLongLong(x)) #endif } } { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else npy_int64 val; PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 +#if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } - #endif +#endif if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (npy_int64) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (npy_int64) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (npy_int64) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (npy_int64) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (npy_int64) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(npy_int64) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((npy_int64) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(npy_int64) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((npy_int64) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((npy_int64) 1) << (sizeof(npy_int64) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif Py_DECREF(v); if (likely(!ret)) return val; } -#endif return (npy_int64) -1; } } else { @@ -22978,7 +28923,7 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { + if ((sizeof(int) < sizeof(long))) { __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); @@ -22992,40 +28937,45 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } } - } - break; + break; + } } #endif -#if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } @@ -23038,109 +28988,181 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, goto raise_neg_overflow; } #endif - if (sizeof(int) <= sizeof(unsigned long)) { + if ((sizeof(int) <= sizeof(unsigned long))) { __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) #ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) #endif } } else { #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } } - } - break; + break; + } } #endif - if (sizeof(int) <= sizeof(long)) { + if ((sizeof(int) <= sizeof(long))) { __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) #ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) #endif } } { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else int val; PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 +#if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } - #endif +#endif if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (int) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (int) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif Py_DECREF(v); if (likely(!ret)) return val; } -#endif return (int) -1; } } else { @@ -23174,7 +29196,7 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { + if ((sizeof(long) < sizeof(long))) { __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); @@ -23188,40 +29210,45 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } } - } - break; + break; + } } #endif -#if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } @@ -23234,109 +29261,181 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, goto raise_neg_overflow; } #endif - if (sizeof(long) <= sizeof(unsigned long)) { + if ((sizeof(long) <= sizeof(unsigned long))) { __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) #ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) #endif } } else { #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } } - } - break; + break; + } } #endif - if (sizeof(long) <= sizeof(long)) { + if ((sizeof(long) <= sizeof(long))) { __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) #ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) #endif } } { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else long val; PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 +#if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } - #endif +#endif if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (long) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (long) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif Py_DECREF(v); if (likely(!ret)) return val; } -#endif return (long) -1; } } else { @@ -23390,8 +29489,34 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 return _PyLong_FromByteArray(bytes, sizeof(int), little, !is_unsigned); +#else + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(int)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif } } @@ -23428,8 +29553,34 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 return _PyLong_FromByteArray(bytes, sizeof(long), little, !is_unsigned); +#else + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif } } @@ -23446,7 +29597,7 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { - if (sizeof(char) < sizeof(long)) { + if ((sizeof(char) < sizeof(long))) { __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); @@ -23460,40 +29611,45 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (char) 0; - case 1: __PYX_VERIFY_RETURN_INT(char, digit, digits[0]) - case 2: - if (8 * sizeof(char) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) >= 2 * PyLong_SHIFT) { - return (char) (((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(char, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(char) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(char) >= 2 * PyLong_SHIFT)) { + return (char) (((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); + } } - } - break; - case 3: - if (8 * sizeof(char) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) >= 3 * PyLong_SHIFT) { - return (char) (((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); + break; + case 3: + if ((8 * sizeof(char) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(char) >= 3 * PyLong_SHIFT)) { + return (char) (((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); + } } - } - break; - case 4: - if (8 * sizeof(char) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) >= 4 * PyLong_SHIFT) { - return (char) (((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); + break; + case 4: + if ((8 * sizeof(char) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(char) >= 4 * PyLong_SHIFT)) { + return (char) (((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); + } } - } - break; + break; + } } #endif -#if CYTHON_COMPILING_IN_CPYTHON +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } @@ -23506,109 +29662,181 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, goto raise_neg_overflow; } #endif - if (sizeof(char) <= sizeof(unsigned long)) { + if ((sizeof(char) <= sizeof(unsigned long))) { __PYX_VERIFY_RETURN_INT_EXC(char, unsigned long, PyLong_AsUnsignedLong(x)) #ifdef HAVE_LONG_LONG - } else if (sizeof(char) <= sizeof(unsigned PY_LONG_LONG)) { + } else if ((sizeof(char) <= sizeof(unsigned PY_LONG_LONG))) { __PYX_VERIFY_RETURN_INT_EXC(char, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) #endif } } else { #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (char) 0; - case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(char, digit, +digits[0]) - case -2: - if (8 * sizeof(char) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 2 * PyLong_SHIFT) { - return (char) (((char)-1)*(((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(char, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(char) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(char) - 1 > 2 * PyLong_SHIFT)) { + return (char) (((char)-1)*(((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + } } - } - break; - case 2: - if (8 * sizeof(char) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 2 * PyLong_SHIFT) { - return (char) ((((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + break; + case 2: + if ((8 * sizeof(char) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(char) - 1 > 2 * PyLong_SHIFT)) { + return (char) ((((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + } } - } - break; - case -3: - if (8 * sizeof(char) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 3 * PyLong_SHIFT) { - return (char) (((char)-1)*(((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + break; + case -3: + if ((8 * sizeof(char) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(char) - 1 > 3 * PyLong_SHIFT)) { + return (char) (((char)-1)*(((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + } } - } - break; - case 3: - if (8 * sizeof(char) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 3 * PyLong_SHIFT) { - return (char) ((((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + break; + case 3: + if ((8 * sizeof(char) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(char) - 1 > 3 * PyLong_SHIFT)) { + return (char) ((((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + } } - } - break; - case -4: - if (8 * sizeof(char) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 4 * PyLong_SHIFT) { - return (char) (((char)-1)*(((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + break; + case -4: + if ((8 * sizeof(char) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(char) - 1 > 4 * PyLong_SHIFT)) { + return (char) (((char)-1)*(((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + } } - } - break; - case 4: - if (8 * sizeof(char) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 4 * PyLong_SHIFT) { - return (char) ((((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + break; + case 4: + if ((8 * sizeof(char) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(char) - 1 > 4 * PyLong_SHIFT)) { + return (char) ((((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); + } } - } - break; + break; + } } #endif - if (sizeof(char) <= sizeof(long)) { + if ((sizeof(char) <= sizeof(long))) { __PYX_VERIFY_RETURN_INT_EXC(char, long, PyLong_AsLong(x)) #ifdef HAVE_LONG_LONG - } else if (sizeof(char) <= sizeof(PY_LONG_LONG)) { + } else if ((sizeof(char) <= sizeof(PY_LONG_LONG))) { __PYX_VERIFY_RETURN_INT_EXC(char, PY_LONG_LONG, PyLong_AsLongLong(x)) #endif } } { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else char val; PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 +#if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } - #endif +#endif if (likely(v)) { + int ret = -1; +#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); + ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + long idigit; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (unlikely(!PyLong_CheckExact(v))) { + PyObject *tmp = v; + v = PyNumber_Long(v); + assert(PyLong_CheckExact(v)); + Py_DECREF(tmp); + if (unlikely(!v)) return (char) -1; + } +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(x) == 0) + return (char) 0; + is_negative = Py_SIZE(x) < 0; +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (char) -1; + is_negative = result == 1; + } +#endif + if (is_unsigned && unlikely(is_negative)) { + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + if (unlikely(!stepval)) + return (char) -1; + } else { + stepval = __Pyx_NewRef(v); + } + val = (char) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(char) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + val |= ((char) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + if (Py_SIZE(stepval) == 0) + goto unpacking_done; + #endif + } + idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(char) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((char) idigit) << bits; + #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 + unpacking_done: + #endif + if (!is_unsigned) { + if (unlikely(val & (((char) 1) << (sizeof(char) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif Py_DECREF(v); if (likely(!ret)) return val; } -#endif return (char) -1; } } else { @@ -23629,48 +29857,73 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, return (char) -1; } +/* FormatTypeName */ + #if CYTHON_COMPILING_IN_LIMITED_API +static __Pyx_TypeName +__Pyx_PyType_GetName(PyTypeObject* tp) +{ + PyObject *name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_n_s_name_2); + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) { + PyErr_Clear(); + Py_XDECREF(name); + name = __Pyx_NewRef(__pyx_n_s__24); + } + return name; +} +#endif + /* CheckBinaryVersion */ - static int __Pyx_check_binary_version(void) { - char ctversion[5]; - int same=1, i, found_dot; - const char* rt_from_call = Py_GetVersion(); - PyOS_snprintf(ctversion, 5, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); - found_dot = 0; - for (i = 0; i < 4; i++) { - if (!ctversion[i]) { - same = (rt_from_call[i] < '0' || rt_from_call[i] > '9'); - break; + static unsigned long __Pyx_get_runtime_version(void) { +#if __PYX_LIMITED_VERSION_HEX >= 0x030B00A4 + return Py_Version & ~0xFFUL; +#else + const char* rt_version = Py_GetVersion(); + unsigned long version = 0; + unsigned long factor = 0x01000000UL; + unsigned int digit = 0; + int i = 0; + while (factor) { + while ('0' <= rt_version[i] && rt_version[i] <= '9') { + digit = digit * 10 + (unsigned int) (rt_version[i] - '0'); + ++i; } - if (rt_from_call[i] != ctversion[i]) { - same = 0; + version += factor * digit; + if (rt_version[i] != '.') break; - } + digit = 0; + factor >>= 8; + ++i; } - if (!same) { - char rtversion[5] = {'\0'}; + return version; +#endif +} +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { char message[200]; - for (i=0; i<4; ++i) { - if (rt_from_call[i] == '.') { - if (found_dot) break; - found_dot = 1; - } else if (rt_from_call[i] < '0' || rt_from_call[i] > '9') { - break; - } - rtversion[i] = rt_from_call[i]; - } PyOS_snprintf(message, sizeof(message), - "compiletime version %s of module '%.100s' " - "does not match runtime version %s", - ctversion, __Pyx_MODULE_NAME, rtversion); + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); return PyErr_WarnEx(NULL, message, 1); } - return 0; } /* FunctionImport */ - #ifndef __PYX_HAVE_RT_ImportFunction -#define __PYX_HAVE_RT_ImportFunction -static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) { + #ifndef __PYX_HAVE_RT_ImportFunction_3_0_10 +#define __PYX_HAVE_RT_ImportFunction_3_0_10 +static int __Pyx_ImportFunction_3_0_10(PyObject *module, const char *funcname, void (**f)(void), const char *sig) { PyObject *d = 0; PyObject *cobj = 0; union { @@ -23687,7 +29940,6 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (** PyModule_GetName(module), funcname); goto bad; } -#if PY_VERSION_HEX >= 0x02070000 if (!PyCapsule_IsValid(cobj, sig)) { PyErr_Format(PyExc_TypeError, "C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)", @@ -23695,21 +29947,6 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (** goto bad; } tmp.p = PyCapsule_GetPointer(cobj, sig); -#else - {const char *desc, *s1, *s2; - desc = (const char *)PyCObject_GetDesc(cobj); - if (!desc) - goto bad; - s1 = desc; s2 = sig; - while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } - if (*s1 != *s2) { - PyErr_Format(PyExc_TypeError, - "C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)", - PyModule_GetName(module), funcname, sig, desc); - goto bad; - } - tmp.p = PyCObject_AsVoidPtr(cobj);} -#endif *f = tmp.fp; if (!(*f)) goto bad; @@ -23722,9 +29959,31 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (** #endif /* InitStrings */ - static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + #if PY_MAJOR_VERSION >= 3 +static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) { + if (t.is_unicode | t.is_str) { + if (t.intern) { + *str = PyUnicode_InternFromString(t.s); + } else if (t.encoding) { + *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL); + } else { + *str = PyUnicode_FromStringAndSize(t.s, t.n - 1); + } + } else { + *str = PyBytes_FromStringAndSize(t.s, t.n - 1); + } + if (!*str) + return -1; + if (PyObject_Hash(*str) == -1) + return -1; + return 0; +} +#endif +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { - #if PY_MAJOR_VERSION < 3 + #if PY_MAJOR_VERSION >= 3 + __Pyx_InitString(*t, t->p); + #else if (t->is_unicode) { *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); } else if (t->intern) { @@ -23732,30 +29991,34 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (** } else { *t->p = PyString_FromStringAndSize(t->s, t->n - 1); } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif if (!*t->p) return -1; if (PyObject_Hash(*t->p) == -1) return -1; + #endif ++t; } return 0; } +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); } static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { Py_ssize_t ignore; @@ -23810,7 +30073,7 @@ static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ return __Pyx_PyUnicode_AsStringAndSize(o, length); } else #endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) +#if (!CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_LIMITED_API) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) if (PyByteArray_Check(o)) { *length = PyByteArray_GET_SIZE(o); return PyByteArray_AS_STRING(o); @@ -23839,22 +30102,26 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { return retval; } static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetName(Py_TYPE(result)); #if PY_MAJOR_VERSION >= 3 if (PyLong_Check(result)) { if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); Py_DECREF(result); return NULL; } + __Pyx_DECREF_TypeName(result_type_name); return result; } #endif PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); + "__%.4s__ returned non-%.4s (type " __Pyx_FMT_TYPENAME ")", + type_name, type_name, result_type_name); + __Pyx_DECREF_TypeName(result_type_name); Py_DECREF(result); return NULL; } @@ -23920,13 +30187,11 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { #endif if (likely(PyLong_CheckExact(b))) { #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); switch (size) { case 2: if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { @@ -23994,4 +30259,12 @@ static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { } +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ #endif /* Py_PYTHON_H */ From 07143ac5e6b6fb549d1735379340195c2a00684b Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 4 Jun 2024 14:57:41 +0100 Subject: [PATCH 015/123] Remove redundant doc folder --- doc/Makefile | 89 ---- doc/README.rst | 36 -- doc/doc_to_sort/bvpSimple.rst | 187 -------- doc/doc_to_sort/common_models.rst | 26 -- doc/doc_to_sort/common_models/FitzHugh.rst | 43 -- .../common_models/Legrand_Ebola_SEIHFR.rst | 93 ---- doc/doc_to_sort/common_models/Lorenz.rst | 37 -- .../common_models/Lotka_Volterra.rst | 91 ---- .../common_models/Lotka_Volterra_4State.rst | 52 --- doc/doc_to_sort/common_models/Robertson.rst | 75 --- doc/doc_to_sort/common_models/SEIR.rst | 36 -- .../common_models/SEIR_Birth_Death.rst | 36 -- .../SEIR_Birth_Death_Periodic.rst | 69 --- .../common_models/SEIR_Multiple.rst | 49 -- doc/doc_to_sort/common_models/SIR.rst | 47 -- .../common_models/SIR_Birth_Death.rst | 37 -- doc/doc_to_sort/common_models/SIS.rst | 34 -- .../common_models/SIS_Periodic.rst | 33 -- doc/doc_to_sort/common_models/vanDelPol.rst | 78 ---- doc/doc_to_sort/epi.rst | 54 --- doc/doc_to_sort/epijson.rst | 42 -- doc/doc_to_sort/estimate1.rst | 115 ----- doc/doc_to_sort/estimate2.rst | 285 ------------ doc/doc_to_sort/faq.rst | 60 --- doc/doc_to_sort/fh.rst | 133 ------ doc/doc_to_sort/gradient.rst | 302 ------------ doc/doc_to_sort/initialGuess.rst | 47 -- doc/doc_to_sort/mod/common_models.rst | 8 - doc/doc_to_sort/mod/confidence_interval.rst | 7 - doc/doc_to_sort/mod/deterministic.rst | 7 - doc/doc_to_sort/mod/epi_analysis.rst | 7 - doc/doc_to_sort/mod/get_init.rst | 7 - doc/doc_to_sort/mod/index.rst | 30 -- doc/doc_to_sort/mod/losstype.rst | 7 - doc/doc_to_sort/mod/odeloss.rst | 17 - doc/doc_to_sort/mod/odeutils.rst | 7 - doc/doc_to_sort/mod/simulate.rst | 8 - doc/doc_to_sort/mod/transition.rst | 8 - doc/doc_to_sort/profile.rst | 433 ------------------ doc/doc_to_sort/ref.rst | 76 --- doc/doc_to_sort/stochastic.rst | 269 ----------- doc/doc_to_sort/transition.rst | 183 -------- doc/doc_to_sort/unroll/unrollBD.rst | 66 --- doc/doc_to_sort/unroll/unrollHard.rst | 73 --- doc/doc_to_sort/unroll/unrollSimple.rst | 54 --- doc/doc_to_sort/unrollOde.rst | 13 - doc/make.bat | 113 ----- doc/requirements.txt | 13 - doc/source/_static/.gitignore | 0 doc/source/conf.py | 264 ----------- doc/source/getting_started.rst | 87 ---- doc/source/index.rst | 63 --- doc/source/sir.rst | 281 ------------ 53 files changed, 4287 deletions(-) delete mode 100644 doc/Makefile delete mode 100644 doc/README.rst delete mode 100644 doc/doc_to_sort/bvpSimple.rst delete mode 100644 doc/doc_to_sort/common_models.rst delete mode 100644 doc/doc_to_sort/common_models/FitzHugh.rst delete mode 100644 doc/doc_to_sort/common_models/Legrand_Ebola_SEIHFR.rst delete mode 100644 doc/doc_to_sort/common_models/Lorenz.rst delete mode 100644 doc/doc_to_sort/common_models/Lotka_Volterra.rst delete mode 100644 doc/doc_to_sort/common_models/Lotka_Volterra_4State.rst delete mode 100644 doc/doc_to_sort/common_models/Robertson.rst delete mode 100644 doc/doc_to_sort/common_models/SEIR.rst delete mode 100644 doc/doc_to_sort/common_models/SEIR_Birth_Death.rst delete mode 100644 doc/doc_to_sort/common_models/SEIR_Birth_Death_Periodic.rst delete mode 100644 doc/doc_to_sort/common_models/SEIR_Multiple.rst delete mode 100644 doc/doc_to_sort/common_models/SIR.rst delete mode 100644 doc/doc_to_sort/common_models/SIR_Birth_Death.rst delete mode 100644 doc/doc_to_sort/common_models/SIS.rst delete mode 100644 doc/doc_to_sort/common_models/SIS_Periodic.rst delete mode 100644 doc/doc_to_sort/common_models/vanDelPol.rst delete mode 100644 doc/doc_to_sort/epi.rst delete mode 100644 doc/doc_to_sort/epijson.rst delete mode 100644 doc/doc_to_sort/estimate1.rst delete mode 100644 doc/doc_to_sort/estimate2.rst delete mode 100644 doc/doc_to_sort/faq.rst delete mode 100644 doc/doc_to_sort/fh.rst delete mode 100644 doc/doc_to_sort/gradient.rst delete mode 100644 doc/doc_to_sort/initialGuess.rst delete mode 100644 doc/doc_to_sort/mod/common_models.rst delete mode 100644 doc/doc_to_sort/mod/confidence_interval.rst delete mode 100644 doc/doc_to_sort/mod/deterministic.rst delete mode 100644 doc/doc_to_sort/mod/epi_analysis.rst delete mode 100644 doc/doc_to_sort/mod/get_init.rst delete mode 100644 doc/doc_to_sort/mod/index.rst delete mode 100644 doc/doc_to_sort/mod/losstype.rst delete mode 100644 doc/doc_to_sort/mod/odeloss.rst delete mode 100644 doc/doc_to_sort/mod/odeutils.rst delete mode 100644 doc/doc_to_sort/mod/simulate.rst delete mode 100644 doc/doc_to_sort/mod/transition.rst delete mode 100644 doc/doc_to_sort/profile.rst delete mode 100644 doc/doc_to_sort/ref.rst delete mode 100644 doc/doc_to_sort/stochastic.rst delete mode 100644 doc/doc_to_sort/transition.rst delete mode 100644 doc/doc_to_sort/unroll/unrollBD.rst delete mode 100644 doc/doc_to_sort/unroll/unrollHard.rst delete mode 100644 doc/doc_to_sort/unroll/unrollSimple.rst delete mode 100644 doc/doc_to_sort/unrollOde.rst delete mode 100644 doc/make.bat delete mode 100644 doc/requirements.txt delete mode 100644 doc/source/_static/.gitignore delete mode 100644 doc/source/conf.py delete mode 100644 doc/source/getting_started.rst delete mode 100644 doc/source/index.rst delete mode 100644 doc/source/sir.rst diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 41dbaa98..00000000 --- a/doc/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pyGenericOdeModelDoc.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pyGenericOdeModelDoc.qhc" - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/doc/README.rst b/doc/README.rst deleted file mode 100644 index a5143c74..00000000 --- a/doc/README.rst +++ /dev/null @@ -1,36 +0,0 @@ -======================= -Documentation for pygom -======================= - -This documentation is written in `sphinx` style. The starting point (about the -package) can be found at:: - - $ doc/_build/html/index.html - -which is the main page in html format. - -If you wish to build the documentation. Go to the document directory and type -the following line in the terminal:: - - doc$ make html - -It is assumed here that the pyGenericOdeModel package has already -been installed, else, the code demonstration will throw out errors -as it cannot find the required modules. Most likely, building the -documentation will require the following packages if not already installed:: - - numpydoc - sphinx - ipython - - -There may be cases that `ipython` require extra packages, install the full -version using `$ pip install ipython[all]` - -============================ -Installation of requirements -============================ - -If you are using `conda` the requirements to build the docs can be installed -by `$ conda install --file requirements.txt` or similarly for those using `pip` -you may `$pip install -r requirements.txt` from the root of the docs directory. \ No newline at end of file diff --git a/doc/doc_to_sort/bvpSimple.rst b/doc/doc_to_sort/bvpSimple.rst deleted file mode 100644 index e5de0d61..00000000 --- a/doc/doc_to_sort/bvpSimple.rst +++ /dev/null @@ -1,187 +0,0 @@ -.. _bvpSimple: - -******************************* -Solving Boundary Value Problems -******************************* - -In addition to finding solutions for an IVP and estimate the unknown parameters, this package also allows you to solve BVP with a little bit of imagination. Here, we are going to show how a BVP can be solved by treating it as a parameter estimation problem. Essentially, a shooting method where the first boundary condition defines the initial condition of an IVP and the second boundary condition is an observation. Two examples, both from MATLAB [1]_, will be shown here. - -Simple model 1 -============== - -We are trying to find the solution to the second order differential equation - -.. math:: - \nabla^{2} y + |y| = 0 - -subject to the boundary conditions :math:`y(0) = 0` and :math:`y(4) = -2`. Convert this into a set of first order ODE - -.. math:: - - \frac{d y_{0}}{dt} &= y_{1} \\ - \frac{d y_{1}}{dt} &= -|y_{0}| - -using an auxiliary variable :math:`y_{1} = \nabla y` and :math:`y_{0} = y`. Setting up the system below - -.. ipython:: - - In [1]: from pygom import Transition, TransitionType, DeterministicOde, SquareLoss - - In [1]: import matplotlib.pyplot as plt - - In [2]: stateList = ['y0', 'y1'] - - In [3]: paramList = [] - - In [4]: ode1 = Transition(origin='y0', - ...: equation='y1', - ...: transition_type=TransitionType.ODE) - - In [5]: ode2 = Transition(origin='y1', - ...: equation='-abs(y0)', - ...: transition_type=TransitionType.ODE) - - In [6]: model = DeterministicOde(stateList, - ...: paramList, - ...: ode=[ode1, ode2]) - - In [7]: model.get_ode_eqn() - -We check that the equations are correct before proceeding to set up our loss function. - -.. ipython:: - - In [1]: import numpy - - In [2]: from scipy.optimize import minimize - - In [3]: initialState = [0.0, 1.0] - - In [4]: t = numpy.linspace(0, 4, 100) - - In [5]: model.initial_values = (initialState, t[0]) - - In [6]: solution = model.integrate(t[1::]) - - In [7]: f = plt.figure() - - @savefig bvp1_random_guess_plot.png - In [8]: model.plot() - - In [9]: plt.close() - -Setting up the second boundary condition :math:`y(4) = -2` is easy, because that -is just a single observation attached to the state :math:`y_{1}`. Enforcing the -first boundary condition requires us to set it as the initial condition. -Because the condition only states that :math:`y(0) = 0`, the starting value of -the other state :math:`y_1` is free. We let our loss object know that it is -free through the targetState input argument. - -.. ipython:: - - In [10]: theta = [0.0] - - In [11]: obj = SquareLoss(theta=theta, - ....: ode=model, - ....: x0=initialState, - ....: t0=t[0], - ....: t=t[-1], - ....: y=[-2], - ....: state_name=['y0'], - ....: target_state=['y1']) - - In [12]: thetaHat = minimize(fun=obj.costIV, x0=[0.0]) - - In [13]: print(thetaHat) - - In [14]: model.initial_values = ([0.0] + thetaHat['x'].tolist(), t[0]) - - In [15]: solution = model.integrate(t[1::]) - - In [16]: f = plt.figure() - - @savefig bvp1_solution_plot.png - In [17]: model.plot() - - In [18]: plt.close() - -We are going to visualize the solution, and also check the boundary condition. The first became our initial condition, so it is always satisfied and only the latter is of concern, which is zero (subject to numerical error) from thetaHat. - -Simple model 2 -============== - -Our second example is different as it involves an actual parameter and also time. We have the Mathieu's Equation - -.. math:: - - \nabla^{2} y + \left(p - 2q \cos(2x)\right)y = 0 - -and the aim is to compute the fourth eigenvalue :math:`q=5`. There are three boundary conditions - -.. math:: - - \nabla y(0) = 0, \quad \nabla y(\pi) = 0, \quad y(0) = 1 - -and we aim to solve it by converting it to a first order ODE and tackle it as an IVP. As our model object does not allow the use of the time component in the equations, we introduce a anxiliary state :math:`\tau` that replaces time :math:`t`. Rewrite the equations using :math:`y_{0} = y, y_{1} = \nabla y` and define our model as - -.. ipython:: - - In [1]: stateList = ['y0', 'y1', 'tau'] - - In [2]: paramList = ['p'] - - In [3]: ode1 = Transition('y0', 'y1', TransitionType.ODE) - - In [4]: ode2 = Transition('y1', '-(p - 2*5*cos(2*tau))*y0', TransitionType.ODE) - - In [5]: ode3 = Transition('tau', '1', TransitionType.ODE) - - In [6]: model = DeterministicOde(stateList, paramList, ode=[ode1, ode2, ode3]) - - In [7]: theta = [1.0, 1.0, 0.0] - - In [8]: p = 15.0 - - In [9]: t = numpy.linspace(0, numpy.pi) - - In [10]: model.parameters = [('p',p)] - - In [11]: model.initial_values = (theta, t[0]) - - In [12]: solution = model.integrate(t[1::]) - - In [13]: f = plt.figure() - - @savefig bvp2_random_guess_plot.png - In [14]: model.plot() - - In [15]: plt.close() - -Now we are ready to setup the estimation. Like before, we setup the second boundary condition by pretending that it is an observation. We have all the initial conditions defined by the first boundary condition - -.. ipython:: - - In [1]: obj = SquareLoss(15.0, model, x0=[1.0, 0.0, 0.0], t0=0.0, t=numpy.pi, y=0.0, state_name='y1') - - In [2]: xhatObj = minimize(obj.cost,[15]) - - In [3]: print(xhatObj) - - In [4]: model.parameters = [('p', xhatObj['x'][0])] - - In [5]: model.initial_values = ([1.0, 0.0, 0.0], t[0]) - - In [5]: solution = model.integrate(t[1::]) - - In [6]: f = plt.figure() - - @savefig bvp2_solution_plot.png - In [7]: model.plot() - - In [8]: plt.close() - -The plot of the solution shows the path that satisfies all boundary condition. The last subplot is time which obvious is redundant here but the :meth:`DeterministicOde.plot` method is not yet able to recognize the time component. Possible speed up can be achieved through the use of derivative information or via root finding method that tackles the gradient directly, instead of the cost function. - -**Reference** - -.. [1] http://uk.mathworks.com/help/matlab/ref/bvp4c.html diff --git a/doc/doc_to_sort/common_models.rst b/doc/doc_to_sort/common_models.rst deleted file mode 100644 index 01dfe8dd..00000000 --- a/doc/doc_to_sort/common_models.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. _common_models: - -********************************* -Pre-defined Example common_models -********************************* - -We have defined a set of models :mod:`common_models`, most of them commonly used in epidemiology. They are there as examples and also save time for end users. Most of them are of the compartmental type, and we use standard naming conventions i.e. **S** = Susceptible, **E** = Exposed, **I** = Infectious, **R** = Recovered. Extra state symbol will be introduced when required. - -.. toctree:: - - common_models/SIS.rst - common_models/SIS_Periodic.rst - common_models/SIR.rst - common_models/SIR_Birth_Death.rst - common_models/SEIR.rst - common_models/SEIR_Multiple.rst - common_models/SEIR_Birth_Death.rst - common_models/SEIR_Birth_Death_Periodic.rst - common_models/Legrand_Ebola_SEIHFR.rst - common_models/Lotka_Volterra.rst - common_models/Lotka_Volterra_4State.rst - common_models/FitzHugh.rst - common_models/Lorenz.rst - common_models/vanDelPol.rst - common_models/Robertson.rst - diff --git a/doc/doc_to_sort/common_models/FitzHugh.rst b/doc/doc_to_sort/common_models/FitzHugh.rst deleted file mode 100644 index 517a8a55..00000000 --- a/doc/doc_to_sort/common_models/FitzHugh.rst +++ /dev/null @@ -1,43 +0,0 @@ -:func:`.FitzHugh` ------------------ - -The FitzHugh model [FitzHugh1961]_ without external external stimulus. This is a commonly used model when developing new methodology with regard to ode's, see [Ramsay2007]_ and [Girolami2011]_ and reference therein. - -.. math:: - - \frac{dV}{dt} &= c ( V - \frac{V^{3}}{3} + R) \\ - \frac{dR}{dt} &= -\frac{1}{c}(V - a + bR). - -An example would be - -.. ipython:: - - In [1]: import numpy - - In [1]: from pygom import common_models - - In [1]: import matplotlib.pyplot as plt - - In [1]: ode = common_models.FitzHugh({'a':0.2, 'b':0.2, 'c':3.0}) - - In [1]: t = numpy.linspace(0, 20, 101) - - In [1]: x0 = [1.0, -1.0] - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - @savefig common_models_fh_1.png - In [1]: ode.plot() - - In [1]: plt.close() - - In [1]: fig = plt.figure() - - In [1]: plt.plot(solution[:,0], solution[:,1], 'b') - - @savefig common_models_fh_2.png - In [1]: plt.show() - - In [1]: plt.close() \ No newline at end of file diff --git a/doc/doc_to_sort/common_models/Legrand_Ebola_SEIHFR.rst b/doc/doc_to_sort/common_models/Legrand_Ebola_SEIHFR.rst deleted file mode 100644 index 0b0ab4d9..00000000 --- a/doc/doc_to_sort/common_models/Legrand_Ebola_SEIHFR.rst +++ /dev/null @@ -1,93 +0,0 @@ -:func:`.Legrand_Ebola_SEIHFR` -============================= - -A commonly used model in the literature to model Ebola outbreaks is the SEIHFR model proposed by [Legrand2007]_. There are two extra compartments on top of the standard SEIR, :math:`H` for hospitialization and :math:`F` for funeral. A total of ten parameters (with some describing the inverse) are required for the model, they are: - -================== ============================================ - Symbol Process -================== ============================================ -:math:`\beta_{I}` Transmission rate in community -:math:`\beta_{H}` Transmission rate in hospital -:math:`\beta_{F}` Transmission rate in funeral -:math:`\gamma_{I}` (inverse) Onset to end of infectious -:math:`\gamma_{D}` (inverse) Onset to death -:math:`\gamma_{H}` (inverse) Onset of hospitilization -:math:`\gamma_{F}` (inverse) Death to burial -:math:`\alpha` (inverse) Duration of the incubation period -:math:`\theta` Proportional of cases hospitalized -:math:`\delta` Case--ftality ratio -================== ============================================ - -The **(inverse)** denotes the parameter should be inverted to make epidemiological sense. We use the parameters in their more natural from in :func:`.Legrand_Ebola_SEIHFR` and replace all the :math:`\gamma`'s with :math:`\omega`'s, i.e. :math:`\omega_{i} = \gamma_{i}^{-1}` for :math:`i \in \{I,D,H,F\}`. We also used :math:`\alpha^{-1}` in our model instead of :math:`\alpha` so that reading the parameters directly gives a more intuitive meaning. There arw five additional parameters that is derived. The two derived case fatality ratio as - -.. math:: - - \delta_{1} &= \frac{\delta \gamma_{I}}{\delta \gamma_{I} + (1-\delta)\gamma_{D}} \\ - \delta_{2} &= \frac{\delta \gamma_{IH}}{\delta \gamma_{IH} + (1-\delta)\gamma_{DH}}, - -with an adjusted hospitalization parameter - -.. math:: - - \theta_{1} = \frac{\theta(\gamma_{I}(1-\delta_{1}) + \gamma_{D}\delta_{1})}{\theta(\gamma_{I}(1-\delta_{1}) + \gamma_{D}\delta_{1}) + (1-\theta)\gamma_{H}}, - -and the derived infectious period - -.. math:: - - \gamma_{IH} &= (\gamma_{I}^{-1} - \gamma_{H}^{-1})^{-1} \\ - \gamma_{DH} &= (\gamma_{D}^{-1} - \gamma_{H}^{-1})^{-1}. - -Now we are ready to state the full set of ode's, - -.. math:: - - \frac{dS}{dt} &= -N^{-1} (\beta_{I}SI + \beta_{H}SH + \beta_{F}(t) SF) \\ - \frac{dE}{dt} &= N^{-1} (\beta_{I}SI + \beta_{H}SH + \beta_{F}(t) SF) - \alpha E \\ - \frac{dI}{dt} &= \alpha E - (\gamma_{H} \theta_{1} + \gamma_{I}(1-\theta_{1})(1-\delta_{1}) + \gamma_{D}(1-\theta_{1})\delta_{1})I \\ - \frac{dH}{dt} &= \gamma_{H}\theta_{1}I - (\gamma_{DH}\delta_{2} + \gamma_{IH}(1-\delta_{2}))H \\ - \frac{dF}{dt} &= \gamma_{D}(1-\theta_{1})\delta_{1}I + \gamma_{DH}\delta_{2}H - \gamma_{F}F \\ - \frac{dR}{dt} &= \gamma_{I}(1-\theta_{1})(1-\delta_{1})I + \gamma_{IH}(1-\delta_{2})H + \gamma_{F}F. - -with :math:`\beta_{F}(t) = \beta_{F}` if :math:`t > c` and :math:`0` otherwise. We use a slightly modified version by replacing the delta function with a sigmoid function namely, the logistic function - -.. math:: - - \beta_{F}(t) = \beta_{F} \left(1 - \frac{1}{1 + \exp(-\kappa (t - c))} \right) - -A brief example (from [3]) is given here with a slightly more in depth example in :ref:`estimate2`. - -.. ipython:: - - In [1]: import numpy - - In [1]: from pygom import common_models - - In [1]: x0 = [1.0, 3.0/200000.0, 0.0, 0.0, 0.0, 0.0, 0.0] - - In [1]: t = numpy.linspace(1, 25, 100) - - In [1]: ode = common_models.Legrand_Ebola_SEIHFR([ - ...: ('beta_I',0.588), - ...: ('beta_H',0.794), - ...: ('beta_F',7.653), - ...: ('omega_I',10.0/7.0), - ...: ('omega_D',9.6/7.0), - ...: ('omega_H',5.0/7.0), - ...: ('omega_F',2.0/7.0), - ...: ('alphaInv',7.0/7.0), - ...: ('delta',0.81), - ...: ('theta',0.80), - ...: ('kappa',300.0), - ...: ('interventionTime',7.0) - ...: ]) - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: solution = ode.integrate(t) - - @savefig common_models_seihfr.png - In [1]: ode.plot() - -Note also that we have again standardized so that the number of susceptible is 1 and equal to the whole population, i.e. :math:`N` does not exist in our set of ode's as defined in :mod:`.common_models`. - diff --git a/doc/doc_to_sort/common_models/Lorenz.rst b/doc/doc_to_sort/common_models/Lorenz.rst deleted file mode 100644 index cc03eac3..00000000 --- a/doc/doc_to_sort/common_models/Lorenz.rst +++ /dev/null @@ -1,37 +0,0 @@ -:func:`.Lorenz` -=============== - -The Lorenz attractor [Lorenz1963]_ defined by the equations - -.. math:: - - \frac{dx}{dt} &= \sigma (y-x) \\ - \frac{dy}{dt} &= x (\rho - z) - y \\ - \frac{dz}{dt} &= xy - \beta z - -A classic example is - -.. ipython:: - - In [1]: from pygom import common_models - - In [1]: import numpy - - In [1]: import matplotlib.pyplot as plt - - In [1]: t = numpy.linspace(0, 100, 20000) - - In [1]: ode = common_models.Lorenz({'beta':8.0/3.0, 'sigma':10.0, 'rho':28.0}) - - In [1]: ode.initial_values = ([1., 1., 1.], t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - In [1]: f = plt.figure() - - In [1]: plt.plot(solution[:,0], solution[:,2]); - - @savefig common_models_Lorenz.png - In [1]: plt.show() - - diff --git a/doc/doc_to_sort/common_models/Lotka_Volterra.rst b/doc/doc_to_sort/common_models/Lotka_Volterra.rst deleted file mode 100644 index fbf65c4b..00000000 --- a/doc/doc_to_sort/common_models/Lotka_Volterra.rst +++ /dev/null @@ -1,91 +0,0 @@ -:func:`.Lotka_Volterra` -======================= - -A standard Lotka-Volterra (preditor and prey) model with two states and four parameters [Lotka1920]_. - -.. math:: - - \frac{dx}{dt} &= \alpha x - cxy \\ - \frac{dy}{dt} &= -\delta y + \gamma xy - -with both birth and death processes. - -.. ipython:: - - In [1]: from pygom import common_models - - In [1]: import numpy - - In [1]: import matplotlib.pyplot as plt - - In [1]: x0 = [2.0, 6.0] - - In [1]: ode = common_models.Lotka_Volterra({'alpha':1, 'delta':3, 'c':2, 'gamma':6}) - - In [1]: ode.initial_values = (x0, 0) - - In [1]: t = numpy.linspace(0.1, 100, 10000) - - In [1]: solution = ode.integrate(t) - - @savefig common_models_Lotka_Volterra.png - In [1]: ode.plot() - - In [1]: plt.close() - -Then we generate the graph at `Wolfram Alpha `_ with varying initial conditions. - -.. ipython:: - - In [1]: x1List = numpy.linspace(0.2, 2.0, 5) - - In [1]: x2List = numpy.linspace(0.6, 6.0, 5) - - In [1]: fig = plt.figure() - - In [1]: solutionList = list() - - In [1]: ode = common_models.Lotka_Volterra({'alpha':1, 'delta':3, 'c':2, 'gamma':6}) - - In [1]: for i in range(len(x1List)): - ...: ode.initial_values = ([x1List[i], x2List[i]], 0) - ...: solutionList += [ode.integrate(t)] - - In [1]: for i in range(len(x1List)): plt.plot(solutionList[i][100::,0], solutionList[i][100::,1], 'b') - - In [1]: plt.xlabel('x') - - In [1]: plt.ylabel('y') - - @savefig common_models_Lotka_Volterra_initial_condition.png - In [1]: plt.show() - - In [1]: plt.close() - -We also know that the system has the critical points at :math:`x = \delta / \gamma` and :math:`y=\alpha / c`. If we changes the parameters in such a way that the ration between :math:`x` and :math:`y` remains the same, then we get a figure as below - -.. ipython:: - - In [1]: cList = numpy.linspace(0.1, 2.0, 5) - - In [1]: gammaList = numpy.linspace(0.6, 6.0, 5) - - In [1]: fig = plt.figure() - - In [1]: for i in range(len(x1List)): - ...: ode = common_models.Lotka_Volterra({'alpha':1, 'delta':3, 'c':cList[i], 'gamma':gammaList[i]}) - ...: ode.initial_values = (x0, 0) - ...: solutionList += [ode.integrate(t)] - - In [1]: for i in range(len(cList)): plt.plot(solutionList[i][100::,0], solutionList[i][100::,1]) - - In [1]: plt.xlabel('x') - - In [1]: plt.ylabel('y') - - @savefig common_models_Lotka_Volterra_critical_point.png - In [1]: plt.show() - - In [1]: plt.close() - -where all the cycles goes through the same points. diff --git a/doc/doc_to_sort/common_models/Lotka_Volterra_4State.rst b/doc/doc_to_sort/common_models/Lotka_Volterra_4State.rst deleted file mode 100644 index 33b75b76..00000000 --- a/doc/doc_to_sort/common_models/Lotka_Volterra_4State.rst +++ /dev/null @@ -1,52 +0,0 @@ -:func:`.Lotka_Volterra_4State` -============================== - -The Lotka-Volterra model with four states and three parameters [Lotka1920]_, explained by the following three transitions - -.. math:: - - \frac{da}{dt} &= k_{0} a x \\ - \frac{dx}{dt} &= k_{0} a x - k_{1} x y \\ - \frac{dy}{dt} &= k_{1} x y - k_{2} y \\ - \frac{db}{dt} &= k_{2} y. - -First, we show the deterministic approach. Then we also show the different process path using the parameters from [Press2007]_. Note that although the model is defined in :mod:`common_models`, it is based on outputting an :class:`OperateOdeModel` rather than :class:`SimulateOdeModel`. - -.. ipython:: - - In [1]: import matplotlib.pyplot as plt - - In [1]: from pygom import Transition, TransitionType, ode_utils, SimulateOde - - In [1]: import numpy - - In [1]: stateList = ['a', 'x', 'y', 'b'] - - In [1]: paramList = ['k0', 'k1', 'k2'] - - In [1]: transitionList = [ - ...: Transition(origin='a', destination='x', equation='k0*a*x', transition_type=TransitionType.T), - ...: Transition(origin='x', destination='y', equation='k1*x*y', transition_type=TransitionType.T), - ...: Transition(origin='y', destination='b', equation='k2*y', transition_type=TransitionType.T) - ...: ] - - In [1]: ode = SimulateOde(stateList, paramList, transition=transitionList) - - In [1]: x0 = [150.0, 10.0, 10.0, 0.0] - - In [1]: t = numpy.linspace(0, 15, 100) - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: ode.parameters = [0.01, 0.1, 1.0] - - In [1]: solution = ode.integrate(t[1::]) - - @savefig common_models_Lotka_Volterra_4State.png - In [1]: ode.plot() - - In [1]: simX, simT = ode.simulate_jump(t[1::], 5, full_output=True) - - @savefig common_models_Lotka_Volterra_Sim.png - In [1]: ode.plot(simX, simT) - diff --git a/doc/doc_to_sort/common_models/Robertson.rst b/doc/doc_to_sort/common_models/Robertson.rst deleted file mode 100644 index 0e90755b..00000000 --- a/doc/doc_to_sort/common_models/Robertson.rst +++ /dev/null @@ -1,75 +0,0 @@ -:func:`.Robertson` -================== - -The Robertson problem [Robertson1966]_ - -.. math:: - - \frac{dy_{1}}{dt} &= -0.04 y_{1} + 1 \cdot 10^{4} y_{2} y_{3} \\ - \frac{dy_{2}}{dt} &= 0.04 y_{1} - 1 \cdot 10^{4} y_{2} y_{3} + 3 \cdot 10^{7} y_{2}^{2} \\ - \frac{dy_{3}}{dt} &= 3 \cdot 10^{7} y_{2}^{2}. - -This is a problem that describes an autocatalytic reaction. One of those commonly used to test stiff ode solvers. As the parameters in the literature is fixed, we show here how to define the states in a slightly more compact format - -.. ipython:: - - In [1]: from pygom import DeterministicOde, Transition, TransitionType - - In [1]: import numpy - - In [1]: import matplotlib.pyplot as plt - - In [1]: t = numpy.append(0, 4*numpy.logspace(-6, 6, 1000)) - - In [1]: # note how we define the states - - In [1]: stateList = ['y1:4'] - - In [1]: paramList = [] - - In [1]: transitionList = [ - ...: Transition(origin='y1', destination='y2', equation='0.04*y1', transition_type=TransitionType.T), - ...: Transition(origin='y2', destination='y1', equation='1e4*y2*y3', transition_type=TransitionType.T), - ...: Transition(origin='y2', destination='y3', equation='3e7*y2*y2', transition_type=TransitionType.T) - ...: ] - - In [1]: ode = DeterministicOde(stateList, paramList, transition=transitionList) - - In [1]: ode.initial_values = ([1.0, 0.0, 0.0], t[0]) - - In [1]: solution, output = ode.integrate(t[1::], full_output=True) - - In [1]: f, axarr = plt.subplots(1, 3) - - In [1]: for i in range(3): - ...: axarr[i].plot(t, solution[:,i]) - ...: axarr[i].set_xscale('log') - - In [1]: f.tight_layout(); - - @savefig common_models_Robertson_1.png - In [1]: plt.show() - - In [1]: plt.close() - -To simplify even further, we can use `y` with the corresponding subscript directly instead of `y1,y2,y3`. Again, we do not have any parameters as they are hard coded into our models. - -.. ipython:: - - In [1]: stateList = ['y1:4'] - - In [1]: transitionList = [ - ...: Transition(origin='y[0]', destination='y[1]', equation='0.04*y[0]', transition_type=TransitionType.T), - ...: Transition(origin='y[1]', destination='y[0]', equation='1e4*y[1]*y[2]', transition_type=TransitionType.T), - ...: Transition(origin='y[1]', destination='y[2]', equation='3e7*y[1]*y[1]', transition_type=TransitionType.T) - ...: ] - - In [1]: ode = DeterministicOde(stateList, paramList, transition=transitionList) - - In [1]: ode.initial_values =([1.0, 0.0, 0.0], t[0]) - - In [1]: solution2 = ode.integrate(t[1::]) - - In [1]: numpy.max(solution - solution2) - -and we have the identical solution as shown in the last line above. diff --git a/doc/doc_to_sort/common_models/SEIR.rst b/doc/doc_to_sort/common_models/SEIR.rst deleted file mode 100644 index 0cb5f9cc..00000000 --- a/doc/doc_to_sort/common_models/SEIR.rst +++ /dev/null @@ -1,36 +0,0 @@ -:func:`.SEIR` -============= - -A natural extension to the SIR is the SEIR model. An extra parameter :math:`\alpha`, which is the inverse of the incubation period is introduced. - -.. math:: - - \frac{dS}{dt} &= -\beta SI \\ - - \frac{dE}{dt} &= \beta SI - \alpha E \\ - - \frac{dI}{dt} &= \alpha E - \gamma I \\ - - \frac{dR}{dt} &= \gamma I - -We use the parameters from [Aron1984] here to generate our plots, which does not yield a *nice* and *sensible* epidemic curve as the birth and death processes are missing. - -.. ipython:: - - In [1]: from pygom import common_models - - In [1]: import numpy - - In [1]: ode = common_models.SEIR({'beta':1800, 'gamma':100, 'alpha':35.84}) - - In [1]: t = numpy.linspace(0, 50, 1001) - - In [1]: x0 = [0.0658, 0.0007, 0.0002, 0.0] - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - @savefig common_models_seir.png - In [1]: ode.plot() - diff --git a/doc/doc_to_sort/common_models/SEIR_Birth_Death.rst b/doc/doc_to_sort/common_models/SEIR_Birth_Death.rst deleted file mode 100644 index 970231aa..00000000 --- a/doc/doc_to_sort/common_models/SEIR_Birth_Death.rst +++ /dev/null @@ -1,36 +0,0 @@ -:func:`.SEIR_Birth_Death` -========================= - -Extending it to also include birth death process with equal rate :math:`\mu` - -.. math:: - - \frac{dS}{dt} &= \mu - \beta SI - \mu S \\ - \frac{dE}{dt} &= \beta SI - (\mu + \alpha) E \\ - \frac{dI}{dt} &= \alpha E - (\mu + \gamma) I \\ - \frac{dR}{dt} &= \gamma I - -Same parameters value taken from [Aron1984]_ as the SEIR example above is used here. Observe how the introduction of a birth and a death process changes the graph even though the rest of the parameters remains the same. - -.. ipython:: - - In [1]: from pygom import common_models - - In [1]: import matplotlib.pyplot as plt - - In [1]: import numpy - - In [1]: ode = common_models.SEIR_Birth_Death({'beta':1800, 'gamma':100, 'alpha':35.84, 'mu':0.02}) - - In [1]: t = numpy.linspace(0, 50, 1001) - - In [1]: x0 = [0.0658, 0.0007, 0.0002, 0.0] - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: solution = ode.integrate(t[1::], full_output=True) - - @savefig common_models_seir_bd.png - In [1]: ode.plot() - - In [1]: plt.close() \ No newline at end of file diff --git a/doc/doc_to_sort/common_models/SEIR_Birth_Death_Periodic.rst b/doc/doc_to_sort/common_models/SEIR_Birth_Death_Periodic.rst deleted file mode 100644 index 1f40f887..00000000 --- a/doc/doc_to_sort/common_models/SEIR_Birth_Death_Periodic.rst +++ /dev/null @@ -1,69 +0,0 @@ -:func:`.SEIR_Birth_Death_Periodic` -================================== - -Now extending the SEIR to also have periodic contact, as in [Aron1984]_. - -.. math:: - - \frac{dS}{dt} &= \mu - \beta(t)SI - \mu S \\ - \frac{dE}{dt} &= \beta(t)SI - (\mu + \alpha) E \\ - \frac{dI}{dt} &= \alpha E - (\mu + \gamma) I \\ - \frac{dR}{dt} &= \gamma I. - -.. ipython:: - - In [1]: from pygom import common_models - - In [1]: import numpy - - In [1]: import matplotlib.pyplot as plt - - In [1]: ode = common_models.SEIR_Birth_Death_Periodic({'beta_0':1800, 'beta_1':0.2, 'gamma':100, 'alpha':35.84, 'mu':0.02}) - - In [1]: t = numpy.linspace(0, 50, 1001) - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: x0 = [0.0658, 0.0007, 0.0002, 0.0] - - In [1]: solution = ode.integrate(t[1::]) - - @savefig common_models_seir_bd_periodic1.png - In [1]: ode.plot() - - In [1]: plt.close() - -The periodicity is obvious when looking at the the plot between states :math:`S` and :math:`E`, in logarithmic scale. - -.. ipython:: - - In [1]: fig = plt.figure(); - - In [1]: plt.plot(numpy.log(solution[:,0]), numpy.log(solution[:,1])); - - In [1]: plt.xlabel('log of S'); - - In [1]: plt.ylabel('log of E'); - - @savefig common_models_seir_bd_periodic2.png - In [1]: plt.show() - - In [1]: plt.close() - -Similarly, we can see the same thing between the states :math:`E` and :math:`I`. - -.. ipython:: - - In [1]: fig = plt.figure(); - - In [1]: plt.plot(numpy.log(solution[:,1]), numpy.log(solution[:,2])); - - In [1]: plt.xlabel('log of E'); - - In [1]: plt.ylabel('log of I'); - - @savefig common_models_seir_bd_periodic3.png - In [1]: plt.show() - - In [1]: plt.close() - diff --git a/doc/doc_to_sort/common_models/SEIR_Multiple.rst b/doc/doc_to_sort/common_models/SEIR_Multiple.rst deleted file mode 100644 index 2c1daa3c..00000000 --- a/doc/doc_to_sort/common_models/SEIR_Multiple.rst +++ /dev/null @@ -1,49 +0,0 @@ -:func:`.SEIR_Multiple` -====================== - -Multiple SEIR coupled together, without any birth death process. - -.. math:: - - \frac{dS_{i}}{dt} &= dN_{i} - dS_{i} - \lambda_{i}S_{i} \\ - \frac{dE_{i}}{dt} &= \lambda_{i}S_{i} - (d+\epsilon)E_{i} \\ - \frac{dI_{i}}{dt} &= \epsilon E_{i} - (d+\gamma) I_{i} \\ - \frac{dR_{i}}{dt} &= \gamma I_{i} - dR_{i} - -where - -.. math:: - - \lambda_{i} = \sum_{j=1}^{n} \beta_{i,j} I_{j} (1\{i\neq j\} p) - -with :math:`n` being the number of patch and :math:`p` the coupled factor. - -.. ipython:: - - In [1]: from pygom import common_models - - In [2]: import numpy - - In [3]: paramEval = {'beta_00':0.0010107,'beta_01':0.0010107,'beta_10':0.0010107, - ...: 'beta_11':0.0010107,'d':0.02,'epsilon':45.6,'gamma':73.0, - ...: 'N_0':10**6,'N_1':10**6,'p':0.01} - - In [4]: x0 = [36139.3224081278, 422.560577637822, 263.883351688369, 963174.233662546] - - In [5]: ode = common_models.SEIR_Multiple(param=paramEval) - - In [6]: t = numpy.linspace(0, 40, 100) - - In [7]: x01 = [] - - In [8]: for s in x0: - ...: x01 += 2*[s] - - In [9]: ode.initial_values = (numpy.array(x01, float),t[0]) - - In [10]: solution, output = ode.integrate(t[1::], full_output=True) - - @savefig common_models_seir_multiple.png - In [11]: ode.plot() - -The initial conditions are those derived by using the stability condition as stated in [Lloyd1996]_ while the notations is taken from [Brauer2008]_. diff --git a/doc/doc_to_sort/common_models/SIR.rst b/doc/doc_to_sort/common_models/SIR.rst deleted file mode 100644 index 77cef848..00000000 --- a/doc/doc_to_sort/common_models/SIR.rst +++ /dev/null @@ -1,47 +0,0 @@ -:func:`.SIR` -============ - -A standard SIR model defined by the equations - -.. math:: - - \frac{dS}{dt} &= -\beta SI \\ - \frac{dI}{dt} &= \beta SI - \gamma I \\ - \frac{dR}{dt} &= \gamma I - -Note that the examples and parameters are taken from [Brauer2008]_, namely Figure 1.4. Hence, the first one below may not appear to make much sense. - -.. ipython:: - - In [1]: from pygom import common_models - - In [1]: import numpy - - In [1]: ode = common_models.SIR({'beta':3.6, 'gamma':0.2}) - - In [1]: t = numpy.linspace(0, 730, 1001) - - In [1]: N = 7781984.0 - - In [1]: x0 = [1.0, 10.0/N, 0.0] - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - @savefig common_models_sir.png - In [1]: ode.plot() - -Now we have the more sensible plot, where the initial susceptibles is only a fraction of 1. - -.. ipython:: - - In [1]: x0 = [0.065, 123*(5.0/30.0)/N, 0.0] - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - @savefig common_models_sir_realistic.png - In [1]: ode.plot() - diff --git a/doc/doc_to_sort/common_models/SIR_Birth_Death.rst b/doc/doc_to_sort/common_models/SIR_Birth_Death.rst deleted file mode 100644 index 5ddc9cf9..00000000 --- a/doc/doc_to_sort/common_models/SIR_Birth_Death.rst +++ /dev/null @@ -1,37 +0,0 @@ -:func:`.SIR_Birth_Death` -======================== - -Next, we look at an SIR model with birth death - -.. math:: - - \frac{dS}{dt} &= B -\beta SI - \mu S \\ - \frac{dI}{dt} &= \beta SI - \gamma I - \mu I \\ - \frac{dR}{dt} &= \gamma I - - -Continuing from the example above, but now with a much longer time frame. Note that the birth and death rate are the same. - -.. ipython:: - - In [1]: from pygom import common_models - - In [1]: import numpy - - In [1]: B = 126372.0/365.0 - - In [1]: N = 7781984.0 - - In [1]: ode = common_models.SIR_Birth_Death({'beta':3.6, 'gamma':0.2, 'B':B/N, 'mu':B/N}) - - In [1]: t = numpy.linspace(0, 35*365, 10001) - - In [1]: x0 = [0.065, 123.0*(5.0/30.0)/N, 0.0] - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - @savefig common_models_sir_bd.png - In [1]: ode.plot() - diff --git a/doc/doc_to_sort/common_models/SIS.rst b/doc/doc_to_sort/common_models/SIS.rst deleted file mode 100644 index cb1cbe70..00000000 --- a/doc/doc_to_sort/common_models/SIS.rst +++ /dev/null @@ -1,34 +0,0 @@ -:func:`.SIS` -============ - -A standard SIS model without the total population :math:`N`. We assume here that :math:`S + I = N` so we can always normalize to 1. Evidently, the state :math:`S` is not required for understanding the model because it is a deterministic function of state :math:`I`. - -.. math:: - - \frac{dS}{dt} &= -\beta S I + \gamma I \\ - \frac{dI}{dt} &= \beta S I - \gamma I. - -An example would be - -.. ipython:: - - In [1]: from pygom import common_models - - In [1]: import matplotlib.pyplot as plt - - In [1]: import numpy - - In [1]: ode = common_models.SIS({'beta':0.5,'gamma':0.2}) - - In [1]: t = numpy.linspace(0, 20, 101) - - In [1]: x0 = [1.0, 0.1] - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - @savefig common_models_sis.png - In [1]: ode.plot() - - In [1]: plt.close() \ No newline at end of file diff --git a/doc/doc_to_sort/common_models/SIS_Periodic.rst b/doc/doc_to_sort/common_models/SIS_Periodic.rst deleted file mode 100644 index 513fbe73..00000000 --- a/doc/doc_to_sort/common_models/SIS_Periodic.rst +++ /dev/null @@ -1,33 +0,0 @@ -:func:`.SIS_Periodic` -===================== - -Now we look at an extension of the SIS model by incorporating periodic contact rate. Note how our equation is defined by a single ode for state **I**. - -.. math:: - - \frac{dI}{dt} = (\beta(t)N - \alpha) I - \beta(t)I^{2} - -where :math:`\beta(t) = 2 - 1.8 \cos(5t)`. As the name suggests, it achieves a (stable) periodic solution. Note how the plots have two sub-graphs, where :math:`\tau` is in fact our time component which we have taken out of the original equation when converting it to a automonous system. - -.. ipython:: - - In [1]: from pygom import common_models - - In [1]: import matplotlib.pyplot as plt - - In [1]: import numpy - - In [1]: ode = common_models.SIS_Periodic({'alpha':1.0}) - - In [1]: t = numpy.linspace(0, 10, 101) - - In [1]: x0 = [0.1,0.] - - In [1]: ode.initial_values = (x0, t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - @savefig common_models_sis_periodic.png - In [1]: ode.plot() - - In [1]: plt.close() \ No newline at end of file diff --git a/doc/doc_to_sort/common_models/vanDelPol.rst b/doc/doc_to_sort/common_models/vanDelPol.rst deleted file mode 100644 index 0934b43c..00000000 --- a/doc/doc_to_sort/common_models/vanDelPol.rst +++ /dev/null @@ -1,78 +0,0 @@ -:func:`.vanDelPol` -================== - -The van Del Pol oscillator [vanderpol1926]_ - -.. math:: - - \frac{dx}{dt} &= \sigma (y-x) \\ - \frac{dy}{dt} &= x (\rho - z) - y \\ - \frac{dz}{dt} &= xy - \beta z - -A classic example is - -.. ipython:: - - In [1]: from pygom import common_models - - In [1]: import numpy - - In [1]: import matplotlib.pyplot as plt - - In [1]: t = numpy.linspace(0, 20, 1000) - - In [1]: ode = common_models.vanDelPol({'mu':1.0}) - - In [1]: ode.initial_values = ([2.0, 0.0], t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - @savefig common_models_vanDelPol.png - In [1]: ode.plot() - - In [1]: plt.close() - - In [1]: f = plt.figure() - - In [1]: plt.plot(solution[:,0], solution[:,1]); - - @savefig common_models_vanDelPol_yprime_y_1.png - In [1]: plt.show() - - In [1]: plt.close() - -When we change the value, as per `Wolfram `_ - -.. ipython:: - - In [1]: t = numpy.linspace(0, 100, 1000) - - In [1]: ode.parameters = {'mu':1.0} - - In [1]: ode.initial_values = ([0.0, 0.2], t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - In [1]: f = plt.figure() - - In [1]: plt.plot(solution[:,0],solution[:,1]); - - @savefig common_models_vanDelPol_yprime_y_2.png - In [1]: plt.show() - - In [1]: plt.close() - - In [1]: ode.parameters = {'mu':0.2} - - In [1]: ode.initial_values = ([0.0, 0.2], t[0]) - - In [1]: solution = ode.integrate(t[1::]) - - In [1]: f = plt.figure() - - In [1]: plt.plot(solution[:,0], solution[:,1]); - - @savefig common_models_vanDelPol_yprime_y_3.png - In [1]: plt.show() - - In [1]: plt.close() diff --git a/doc/doc_to_sort/epi.rst b/doc/doc_to_sort/epi.rst deleted file mode 100644 index 757c0db5..00000000 --- a/doc/doc_to_sort/epi.rst +++ /dev/null @@ -1,54 +0,0 @@ -.. _epi: - -************************ -Simple Epidemic Analysis -************************ - -A common application of ordinary differential equations is in the field of epidemiology modeling. More concretely, compartmental models that is used to describe disease progression. We demonstrate some of the simple algebraic analysis one may wish to take when given a compartment model. Our use one of the simplest model, an SIR model with birth and death processes, which is an extension of the one in :ref:`sir`. First, we initialize the model below. - -.. ipython:: - - In [1]: from pygom import common_models - - In [2]: ode = common_models.SIR_Birth_Death() - - In [3]: print(ode.get_ode_eqn()) - - -Obtaining the R0 -================ - -The reproduction number, also known as the :math:`R_{0}`, is the single most powerful piece and reduced piece of information available from a compartmental model. In a nutshell, it provides a single number - if the parameters are known - which can the intuitive interpretation where :math:`R_{0} = 1` defines the tipping point of an outbreak. A :math:`R_{0}` value of more than one signifies an potential outbreak where less than one indicates that the disease will stop spreading naturally. - -To obtain the :math:`R_{0}`, we simply have to tell the function which states represent the *disease state*, which in this case is the state **I**. - -.. ipython:: - - In [1]: from pygom.model.epi_analysis import * - - In [2]: print(R0(ode, 'I')) - -Algebraic R0 -============ - -We may also wish to get the :math:`R_{0}` in pure algebraic term. This can be achieved by the following few lines. Note that the result below is slightly different from the one above. The difference is due to the internal working of the functions, where :func:`getR0` computes the disease-free equilibrium value for the states and substitute them back into the equation. - -.. ipython:: - - In [1]: F, V = disease_progression_matrices(ode, 'I') - - In [2]: e = R0_from_matrix(F, V) - - In [3]: print(e) - - -To replicate the output before, we have to find the values where the disease-free equilibrium will be achieved. Substitution can then be performed to retrieve :math:`R_{0}` in pure parameters. - -.. ipython:: - - In [1]: dfe = DFE(ode, ['I']) - - In [2]: print(dfe) - - In [3]: print(e[0].subs(dfe)) - diff --git a/doc/doc_to_sort/epijson.rst b/doc/doc_to_sort/epijson.rst deleted file mode 100644 index e1ce9cf3..00000000 --- a/doc/doc_to_sort/epijson.rst +++ /dev/null @@ -1,42 +0,0 @@ -.. _epijson: - -****************************** -Reading and using EpiJSON data -****************************** - -Epidemiology data is complicated due to the many different stages a patient can go through and whether a modeling technique is applicable depends heavily on the recording of data. EpiJSON is a framework whih tries to captures all the information [Finnie2016]_, in a JSON format as the name suggests. - -This package provides the functionality to process EpiJSON data. Due to the nature of this package, modeling of ode, it processes the data file with this in mind. The output is therefore in the cumulative form as default, shown below, in a :class:`pandas.DataFrame` format. The input can be in a string format, a file or already a :class:`dict`. - -.. ipython:: - - In [1]: from pygom.loss.read_epijson import epijson_to_data_frame - - In [2]: import pkgutil - - In [3]: data = pkgutil.get_data('pygom', 'data/eg1.json') - - In [3]: df = epijson_to_data_frame(data) - - In [4]: print(df) - -Given that the aim of loading the data is usually for model fitting, we allow EpiJSON as input directly to the loss class :class:`pygom.loss.EpijsonLoss` which uses the Poisson loss under the hood. - -.. ipython:: - - In [1]: from pygom.model import common_models - - In [2]: from pygom.loss.epijson_loss import EpijsonLoss - - In [3]: ode = common_models.SIR([0.5, 0.3]) - - In [4]: obj = EpijsonLoss([0.005, 0.03], ode, data, 'Death', 'R', [300, 2, 0]) - - In [5]: print(obj.cost()) - - In [6]: print(obj._df) - -Given an initialized object, all the operations are inherited from :class:`pygom.loss.BaseLoss`. We demonstrated above how to calculate the cost and the rest will not be shown for brevity. The data frame is stored inside of the loss object and can be retrieved for inspection at any time point. - -Rather unfortunately, initial values for the states is still required, but the time is not. When the time is not supplied, then the first time point in the data will be treated as :math:`t0`. The input `Death` indicate which column of the data is used and :math:`R` the corresponding state the data belongs to. - diff --git a/doc/doc_to_sort/estimate1.rst b/doc/doc_to_sort/estimate1.rst deleted file mode 100644 index 4382142c..00000000 --- a/doc/doc_to_sort/estimate1.rst +++ /dev/null @@ -1,115 +0,0 @@ -.. _estimate1: - -******************************* -Example: Parameter Estimation 1 -******************************* - -Estimation under square loss -============================ - -To ease the estimation process when given data, a separate module :mod:`ode_loss` has been constructed for observations coming from a single state. We demonstrate how to do it via two examples, first, a standard SIR model, then the Legrand SEIHFR model from [Legrand2007]_ used for Ebola in :ref:`estimate2`. - -SIR Model ---------- - -We set up an SIR model as seen previously in :ref:`sir`. - -.. ipython:: - - In [176]: from pygom import SquareLoss, common_models - - In [179]: import numpy - - In [180]: import scipy.integrate - - In [184]: import matplotlib.pyplot - - In [185]: # Again, standard SIR model with 2 parameter. See the first script! - - In [191]: # define the parameters - - In [192]: paramEval = [('beta',0.5), ('gamma',1.0/3.0)] - - In [189]: # initialize the model - - In [190]: ode = common_models.SIR(paramEval) - - -and we assume that we have perfect information about the :math:`R` compartment. - -.. ipython:: - - In [196]: x0 = [1, 1.27e-6, 0] - - In [197]: # Time, including the initial time t0 at t=0 - - In [198]: t = numpy.linspace(0, 150, 1000) - - In [200]: # Standard. Find the solution. - - In [201]: solution = scipy.integrate.odeint(ode.ode, x0, t) - - In [202]: y = solution[:,1:3].copy() - -Initialize the class with some initial guess - -.. ipython:: - - In [209]: # our initial guess - - In [210]: theta = [0.2, 0.2] - - In [176]: objSIR = SquareLoss(theta, ode, x0, t[0], t[1::], y[1::,:], ['I','R']) - -Note that we need to provide the initial values, :math:`x_{0}` and :math:`t_{0}` differently to the observations :math:`y` and the corresponding time :math:`t`. Additionally, the state which the observation lies needs to be specified. Either a single state, or multiple states are allowed, as seen above. - -Difference in gradient ----------------------- - -We have provided two different ways of obtaining the gradient, these are explained in :ref:`gradient` in a bit more detail. First, lets see how similar the output of the two methods are - -.. ipython:: - - In [22]: objSIR.sensitivity() - - In [25]: objSIR.adjoint() - -and the time required to obtain the gradient for the SIR model under :math:`\theta = (0.2,0.2)`, previously entered. - -.. ipython:: - - In [22]: %timeit objSIR.sensitivity() - - In [25]: %timeit objSIR.adjoint() - -Obviously, the amount of time taken for both method is dependent on the number of observations as well as the number of states. The effect on the adjoint method as the number of observations differs can be quite evident. This is because the adjoint method is under a discretization which loops in Python where as the forward sensitivity equations are solved simply via an integration. As the number of observation gets larger, the affect of the Python loop becomes more obvious. - -Difference in gradient is larger when there are less observations. This is because the adjoint method use interpolations on the output of the ode between each consecutive time points. Given solution over the same length of time, fewer discretization naturally leads to a less accurate interpolation. Note that the interpolation is currently performed using univaraite spline, due to the limitation of python packages. Ideally, one would prefer to use an (adaptive) Hermite or Chebyshev interpolation. Note how we ran the two gradient functions once before timing it, that is because we only find the properties (Jacobian, gradient) of the ode during runtime. - -Optimized result ----------------- - -Then standard optimization procedures with some suitable initial guess should yield the correct result. It is important to set the boundaries for compartmental models as we know that all the parameters are strictly positive. We put a less restrictive inequality here for demonstration purpose. - -.. ipython:: - - In [211]: # what we think the bounds are - - In [212]: boxBounds = [(0.0,2.0),(0.0,2.0)] - -Then using the optimization routines in :mod:`scipy.optimize`, for example, the *SLSQP* method with the gradient obtained by forward sensitivity. - -.. ipython:: - - In [208]: from scipy.optimize import minimize - - In [213]: res = minimize(fun=objSIR.cost, - .....: jac=objSIR.sensitivity, - .....: x0=theta, - .....: bounds=boxBounds, - .....: method='SLSQP') - - In [214]: print(res) - -Other methods available in :func:`scipy.optimize.minimize` can also be used, such as the *L-BFGS-B* and *TNC*. We can also use methods that accepts the exact Hessian such as *trust-ncg* but that should not be necessary most of the time. - diff --git a/doc/doc_to_sort/estimate2.rst b/doc/doc_to_sort/estimate2.rst deleted file mode 100644 index 10d27b23..00000000 --- a/doc/doc_to_sort/estimate2.rst +++ /dev/null @@ -1,285 +0,0 @@ -.. _estimate2: - -******************************* -Example: Parameter Estimation 2 -******************************* - -Continuing from the :ref:`estimate1`, we show why estimating the parameters for ode's are hard. This is especially true if there is a lack of data or when there are too much flexibility in the model. Note that for reproducibility purposes, only deterministic models are used here and a fixed seed whenever a stochastic algorithm is needed. - -Standard SEIR model -=================== - -We demonstrate the estimation on the recent Ebola outbreak in West Africa. We use the number of deaths in Guinea and its corresponding time the data was recorded. These data are publicly available and they can be obtained easily on the internet such as https://github.com/cmrivers/ebola. It is stated out here for simplicity. - -.. ipython:: - - In [34]: # the number of deaths and cases in Guinea - - In [35]: yDeath = [29.0, 59.0, 60.0, 62.0, 66.0, 70.0, 70.0, 80.0, 83.0, 86.0, 95.0, 101.0, 106.0, 108.0, - ....: 122.0, 129.0, 136.0, 141.0, 143.0, 149.0, 155.0, 157.0, 158.0, 157.0, 171.0, 174.0, - ....: 186.0, 193.0, 208.0, 215.0, 226.0, 264.0, 267.0, 270.0, 303.0, 305.0, 307.0, 309.0, - ....: 304.0, 310.0, 310.0, 314.0, 319.0, 339.0, 346.0, 358.0, 363.0, 367.0, 373.0, 377.0, - ....: 380.0, 394.0, 396.0, 406.0, 430.0, 494.0, 517.0, 557.0, 568.0, 595.0, 601.0, 632.0, - ....: 635.0, 648.0, 710.0, 739.0, 768.0, 778.0, 843.0, 862.0, 904.0, 926.0, 997.0] - - In [35]: yCase = [49.0, 86.0, 86.0, 86.0, 103.0, 112.0, 112.0, 122.0, 127.0, 143.0, 151.0, 158.0, - ....: 159.0, 168.0, 197.0, 203.0, 208.0, 218.0, 224.0, 226.0, 231.0, 235.0, 236.0, - ....: 233.0, 248.0, 258.0, 281.0, 291.0, 328.0, 344.0, 351.0, 398.0, 390.0, 390.0, - ....: 413.0, 412.0, 408.0, 409.0, 406.0, 411.0, 410.0, 415.0, 427.0, 460.0, 472.0, - ....: 485.0, 495.0, 495.0, 506.0, 510.0, 519.0, 543.0, 579.0, 607.0, 648.0, 771.0, - ....: 812.0, 861.0, 899.0, 936.0, 942.0, 1008.0, 1022.0, 1074.0, 1157.0, 1199.0, 1298.0, - ....: 1350.0, 1472.0, 1519.0, 1540.0, 1553.0, 1906.0] - - In [36]: # the corresponding time - - In [37]: t = [0.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 9.0, 10.0, 13.0, 16.0, 18.0, 20.0, 23.0, 25.0, 26.0, 29.0, - ....: 32.0, 35.0, 40.0, 42.0, 44.0, 46.0, 49.0, 51.0, 62.0, 66.0, 67.0, 71.0, 73.0, 80.0, 86.0, 88.0, - ....: 90.0, 100.0, 102.0, 106.0, 108.0, 112.0, 114.0, 117.0, 120.0, 123.0, 126.0, 129.0, 132.0, 135.0, - ....: 137.0, 140.0, 142.0, 144.0, 147.0, 149.0, 151.0, 157.0, 162.0, 167.0, 169.0, 172.0, 175.0, 176.0, - ....: 181.0, 183.0, 185.0, 190.0, 193.0, 197.0, 199.0, 204.0, 206.0, 211.0, 213.0, 218.0] - -Simple estimation ------------------ - -First ,we are going to fit a standard **SEIR** model to the data. Details of the models can be found in :mod:`common_models` Defining the model as usual with some random guess on what the parameters might be, here, we choose the values to be the mid point of our feasible region (defined by our box constraints later) - -.. ipython:: - - In [1]: from pygom import SquareLoss, common_models - - In [1]: import numpy, scipy.optimize - - In [1]: import matplotlib.pyplot as plt - - In [1]: theta = numpy.array([5.0, 5.0, 5.0]) - - In [2]: ode = common_models.SEIR(theta) - - In [3]: population = 1175e4 - - In [4]: y = numpy.reshape(numpy.append(numpy.array(yCase), numpy.array(yDeath)), (len(yCase),2), 'F')/population - - In [5]: x0 = [1., 0., 49.0/population, 29.0/population] - - In [6]: t0 = t[0] - - In [7]: objLegrand = SquareLoss(theta, ode, x0, t0, t[1::], y[1::,:], ['I','R'], numpy.sqrt([population]*2)) - -Then we optimize, first, assuming that the initial conditions are accurate. Some relatively large bounds are used for this particular problem. - -.. ipython:: - - In [8]: boxBounds = [ (0.0,10.0), (0.0,10.0), (0.0,10.0) ] - - In [9]: res = scipy.optimize.minimize(fun=objLegrand.cost, - ...: jac=objLegrand.sensitivity, - ...: x0=theta, - ...: bounds=boxBounds, - ...: method='l-bfgs-b') - - In [10]: print(res) - - In [11]: f = plt.figure() - - @savefig ebola_seir_straight.png - In [12]: objLegrand.plot() - - In [13]: plt.close() - -We can see from our visual confirmation that the estimated parameters are not exactly ideal. This is confirmed by the information returned from the :func:`scipy.optimize.minimize` routine, and probably caused by the poor starting point. An attempt to find a more suitable value can be done by some form of parameter space exploration. Given that the evaluation of the objective function is not expensive here, we have plenty of options to choose from. To reduce the number of packages required to build this documentation, routines from :mod:`scipy.optimize` remains our preferred option. - -Improved initial guess ----------------------- - -.. ipython:: - - In [8]: resDE = scipy.optimize.differential_evolution(objLegrand.cost, bounds=boxBounds, polish=False, seed=20921391) - - In [9]: print(objLegrand.sensitivity(resDE['x'])) - - In [10]: f = plt.figure() - - @savefig ebola_seir_de.png - In [11]: objLegrand.plot() - - In [12]: plt.close() - -Looking at the output of the estimates (below this paragraph), we can see our inference on Ebola is wrong when compared to the *known* values (from field observation) even though the graphs looks *``reasonable"*. Namely, :math:`\gamma^{-1}` the third element in the vector below, our time from infectious to death, is within the expected range but :math:`\alpha^{-1}` (second element), the incubation period, is a lot higher than expected. - -.. ipython:: - - In [1]: 1/resDE['x'] - -Multimodal surface ------------------- - -A reason for this type of behavior is that we simply lack the information/data to make proper inference. Without data on the state :math:`E`, the parameters :math:`\beta,\alpha` for the two states :math:`I` and :math:`E` are dependent only on observations on :math:`I`. Hence, some other random combination of :math:`\beta,\alpha` that is capable of generating realization close to observations in :math:`I` is feasible. In such cases, the only requirement is that there exist some :math:`\gamma` in the feasible region that can compensate for the ill suited :math:`\beta,\alpha`. For example, we know (obtained elsewhere and not shown here) that there is another set of parameters capable of generating a similar looking curves as before. Note the reversal of magnitude in :math:`\beta` and :math:`\alpha`. - -.. ipython:: - - In [11]: objLegrand.cost([3.26106524e+00, 2.24798702e-04, 1.23660721e-02]) - - In [12]: ## objLegrand.cost([ 0.02701867, 9.00004776, 0.01031861]) # similar graph - - @savefig ebola_seir_prior.png - In [13]: objLegrand.plot() - - In [14]: plt.close() - -With initial values as parameters ---------------------------------- - -Obviously, the assumption that the whole population being susceptible is an overestimate. We now try to estimate the initial conditions of the ode as well. Given previous estimates of the parameters :math:`\hat{\beta}, \hat{\alpha}, \hat{\gamma}` it is appropriate to start our initial guess there. - -Furthermore, given that we now estimate the initial values for all the states, we can use the first time point as our observation. So our time begins at :math:`t = -1` where our observations include the previous initial condition, i.e. 49 and 29 for the number of cases and death at :math:`t = 0` respectively. The following code block demonstrates how we would do that; feel free to try it out yourself to see the much improved result. - -.. ipython:: - :verbatim: - - In [1]: thetaIV = theta.tolist() + x0 - - In [2]: thetaIV[3] -= 1e-8 # to make sure that the initial guess satisfy the constraints - - In [3]: boxBoundsIV = boxBounds + [(0.,1.), (0.,1.), (0.,1.), (0.,1.)] - - In [4]: objLegrand = SquareLoss(theta, ode, x0, -1, t, y, ['I','R'], numpy.sqrt([population]*2)) - - In [5]: resDEIV = scipy.optimize.differential_evolution(objLegrand.costIV, bounds=boxBoundsIV, polish=False, seed=20921391) - - In [6]: print(resDEIV) - - In [7]: f = plt.figure() - - In [8]: objLegrand.plot() - - In [9]: plt.close() - - -Legrand Ebola SEIHFR Model -========================== - -Next, we demonstrate the estimation on a model that is widely used in the recent Ebola outbreak in west Africa. Again, the model has been defined in :mod:`.common_models` already. - -.. ipython:: - - In [1]: ode = common_models.Legrand_Ebola_SEIHFR() - - In [27]: # initial guess from the paper that studied the outbreak in Congo - - In [28]: theta = numpy.array([0.588,0.794,7.653, ### the beta - ....: 10.0,9.6,5.0,2.0, ### the omega - ....: 7.0,0.81,0.80, ### alpha, delta, theta - ....: 100.,1.0]) ### kappa,intervention time - - In [29]: # initial conditions, note that we have a 0.0 at the end because the model is a non-automonous ode which we have converted the time component out - - In [30]: x0 = numpy.array([population, 0.0, 49.0, 0.0, 0.0, 29.0, 0.0])/population - - In [30]: ode.parameters = theta - - In [31]: ode.initial_values = (x0, t[0]) - - In [32]: objLegrand = SquareLoss(theta, ode, x0, t[0], t[1::], y[1::,:], ['I','R'], numpy.sqrt([population]*2)) - -Now, it is important to set additional constraints accurately because a simply box constraint is much larger than the feasible set. Namely, :math:`\omega_{I}, \omega_{D}` are the time taken from onset until end of infectious/death, which has to be bigger than :math:`\omega_{H}`, onset to hospitalization given the nature of the disease. Therefore, we create extra inequality constraints in addition to the box constraints - -.. ipython:: - - In [549]: boxBounds = [ - .....: (0.001, 100.), # \beta_I - .....: (0.001, 100.), # \beta_H - .....: (0.001, 100.), # \beta_F - .....: (0.001, 100.), # \omega_I - .....: (0.001, 100.), # \omega_D - .....: (0.001, 100.), # \omega_H - .....: (0.001, 100.), # \omega_F - .....: (0.001, 100.), # \alpha^{-1} - .....: (0.0001, 1.), # \delta - .....: (0.0001, 1.), # \theta - .....: (0.001, 1000.), # \kappa - .....: (0.,218.) # intervention tine - .....: ] - - In [550]: cons = ({'type': 'ineq', 'fun' : lambda x: numpy.array([x[3]-x[5], x[4]-x[5]])}) - -We can now try to find the optimal values, but because this is a difficult problem that can take a very long time without guarantee on the quality of solution - -.. ipython:: - :okexcept: - :okwarning: - - In [213]: res = scipy.optimize.minimize(fun=objLegrand.cost, - .....: jac=objLegrand.sensitivity, - .....: x0=theta, - .....: constraints=cons, - .....: bounds=boxBounds, - .....: method='SLSQP') - - In [214]: print(res) - - In [215]: f = plt.figure() - - @savefig ebola_legrand_runtime.png - In [216]: objLegrand.plot() - - In [217]: plt.close() - -Evidently, the estimated parameters are very much unrealistic given that a lot of them are near the boundaries. It is also known from other sources that some of the epidemiology properties of Ebola, with incubation period of around 2 weeks and a mortality rate of around 80 percent. - -As the estimate does not appear to provide anything sensible, we also provide a set of values previously obtained (that looks semi-reasonable) here plot the epidemic curve with the observations layered on top - -.. ipython:: - :okexcept: - :okwarning: - - In [1]: theta = numpy.array([3.96915071e-02, 1.72302620e+01, 1.99749990e+01, - ...: 2.67759445e+01, 4.99999990e+01, 5.56122691e+00, - ...: 4.99999990e+01, 8.51599523e+00, 9.99999000e-01, - ...: 1.00000000e-06, 3.85807562e+00, 1.88385318e+00]) - - In [2]: print(objLegrand.cost(theta)) - - In [2]: solution = ode.integrate(t[1::]) - - In [3]: f, axarr = plt.subplots(2,3) - - In [4]: axarr[0,0].plot(t, solution[:,0]); - - In [5]: axarr[0,0].set_title('Susceptible'); - - In [6]: axarr[0,1].plot(t, solution[:,1]); - - In [7]: axarr[0,1].set_title('Exposed'); - - In [8]: axarr[0,2].plot(t, solution[:,2]); - - In [9]: axarr[0,2].plot(t, y[:,0], 'r'); - - In [10]: axarr[0,2].set_title('Infectious'); - - In [11]: axarr[1,0].plot(t, solution[:,3]); - - In [12]: axarr[1,0].set_title('Hospitalised'); - - In [13]: axarr[1,1].plot(t, solution[:,4]); - - In [14]: axarr[1,1].set_title('Awaiting Burial'); - - In [15]: axarr[1,2].plot(t, solution[:,5]); - - In [16]: axarr[1,2].plot(t, y[:,1], 'r'); - - In [17]: axarr[1,2].set_title('Removed'); - - In [18]: f.text(0.5, 0.04, 'Days from outbreak', ha='center'); - - In [19]: f.text(0.01, 0.5, 'Population', va='center', rotation='vertical'); - - In [20]: f.tight_layout(); - - @savefig ebola_seihfr_straight_prior.png - In [21]: plt.show() - - In [22]: plt.close() - - diff --git a/doc/doc_to_sort/faq.rst b/doc/doc_to_sort/faq.rst deleted file mode 100644 index a57c2675..00000000 --- a/doc/doc_to_sort/faq.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. _faq: - -************************ -Frequent asked questions -************************ - -Code runs slowly -================ - -This is because the package is not optimized for speed. Although the some of the main functions are lambdified using :mod:`sympy` or compiled against :mod:`cython` when available, there are many more optimization that can be done. One example is the lines: - -.. python: - - J = self.Jacobian(state,t) - G = self.Grad(state,t) - A = numpy.dot(J,S) + G - -in :func:`.DeterministicOde.evalSensitivity`. The first two operations can be inlined into the third and the third line itself can be rewritten as: - -.. python: - - G += numpy.dot(J,S) - -and save the explicit copy operation by :mod:`numpy` when making A. If desired, we could have also made used of the :mod:`numexpr` package that provides further speed up on elementwise operations in place of numpy. - -Why not compile the numeric computation form sympy against Theano -================================================================= - -Setup of the package has been simplified as much as possible. If you look closely enough, you will realize that the current code generation only uses :mod:`cython` and not :mod:`f2py`. This is because we are not prepared to do all the system checks, i.e. does a fortran compiler exist, is gcc installed, was python built as a shared library etc. We are very much aware of the benefit, especially considering the possibility of GPU computation in :mod:`theano`. - -Why not use mpmath library throughout? -====================================== - -This is because we have a fair number of operations that depends on :mod:`scipy`. Obviously, we can solve ode using :mod:`mpmath` and do standard linear algebra. Unfortunately, optimization and statistics packages and routine are mostly based on :mod:`numpy`. - -Computing the gradient using :class:`.SquareLoss` is slow -========================================================= - -It will always be slow on the first operation. This is due to the design where the initialization of the class is fast and only find derivative information/compile function during runtime. After the first calculation, things should be significantly faster. - -**Why some of my code is not a fortran object?** - -When we detec either a :math:`\exp` or a :math:`\log` in the equations, we automatically force the compile to use mpmath to ensure that we obtain the highest precision. To turn this on/off will be considered as a feature in the future. - -Can you not convert a non-autonumous system to an autonomous system for me automatically -======================================================================================== - -Although we can do that, it is not, and will not be implemented. This is to ensure that the end user such as yourself are fully aware of the equations being defined. - -Getting the sensitivities from :class:`.SquareLoss` did not get a speed up when I used a restricted set of parameters -===================================================================================================================== - -This is because we currently evaluate the full set of sensitivities before extracting them out. Speeding this up for a restrictive set is being considered. A main reason that stopped us from implementing is that we find the symbolic gradient of the ode before compiling it. Which means that one function call to the compiled file will return the full set of sensitivities and we would only be extracting the appropriate elements from the matrix. This only amounts to a small speed up. The best method would be to compile only the necessary elements of the gradient matrix, but this would require much more work both within the code, and later on when variables are being added/deleted as all these compilation are perfromed in runtime. - -Why do not have the option to obtain gradient via complex differencing -====================================================================== - -It is currently not implemented. Feature under consideration. - - diff --git a/doc/doc_to_sort/fh.rst b/doc/doc_to_sort/fh.rst deleted file mode 100644 index 065f3285..00000000 --- a/doc/doc_to_sort/fh.rst +++ /dev/null @@ -1,133 +0,0 @@ -.. _fh: - -****************** -Example: Fitz Hugh -****************** - -Defining the model -================== - -We are going to investigate another classic model here, the FitzHugh-Nagumo, or simply FitzHugh here. The model has already been defined in :mod:`common_models` so we can load it easily - -.. ipython:: - - In [1]: from pygom import SquareLoss, common_models - - In [2]: import numpy - - In [3]: import scipy.integrate, scipy.optimize - - In [4]: import math,time,copy - - In [5]: import matplotlib.pyplot as plt - - In [1]: x0 = [-1.0, 1.0] - - In [2]: t0 = 0 - - In [3]: # params - - In [4]: paramEval = [('a',0.2), ('b',0.2), ('c',3.0)] - - In [5]: ode = common_models.FitzHugh(paramEval) - - In [5]: ode.initial_values = (x0, t0) - -Define a set of time points and lets see how the two states :math:`V` and :math:`R` are suppose to behave. - -.. ipython:: - - In [6]: t = numpy.linspace(1, 20, 30).astype('float64') - - In [7]: solution = ode.integrate(t) - - @savefig fh_plot.png - In [8]: ode.plot() - -Estimate the parameters -======================= - -Obtaining the correct parameters for the FitzHugh model is well known to be difficult, this is because the surface is multimodal. Although this has been shown many times in the literature, so we will omit the details. Regardless, we give it a go with some initial guess. with some luck, we will be able to recover the original parameters. First, we try it out with only one target state - -.. ipython:: - - In [26]: theta = [0.5, 0.5, 0.5] - - In [27]: objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::,1], 'R') - - In [28]: boxBounds = [ - ....: (0.0,5.0), - ....: (0.0,5.0), - ....: (0.0,5.0) - ....: ] - - In [29]: res = scipy.optimize.minimize(fun=objFH.cost, - ....: jac=objFH.sensitivity, - ....: x0=theta, - ....: bounds=boxBounds, - ....: method='L-BFGS-B') - - In [30]: print(res) - -Then we try the same again but with both state as our target. Now we won't look at the iterations because they are pretty pointless. - -.. ipython:: - - In [30]: objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::,:], ['V','R']) - - In [31]: res = scipy.optimize.minimize(fun=objFH.cost, - ....: jac=objFH.sensitivity, - ....: x0=theta, - ....: bounds=boxBounds, - ....: method='L-BFGS-B') - - In [32]: print(res) - -Note how the estimates are the same, unlike other models. - -Estimate initial value -====================== - -We can further assume that we have no idea about the initial values for :math:`V` and :math:`R` as well. We also provide guesstimate to set off the optimization. The input vector :math:`\theta` must have the parameters first, then the initial values, along with the corresponding bounds. - -First, only a single target state, i.e. we only have observations for one of states which is :math:`R` in this case - -.. ipython:: - - In [35]: objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::,1], 'R') - - In [35]: boxBounds = [ - ....: (0.0,5.0), - ....: (0.0,5.0), - ....: (0.0,5.0), - ....: (None,None), - ....: (None,None) - ....: ] - - In [36]: res = scipy.optimize.minimize(fun=objFH.costIV, - ....: jac=objFH.sensitivityIV, - ....: x0=theta + [-0.5,0.5], - ....: bounds=boxBounds, - ....: method='L-BFGS-B') - - In [37]: print(res) - -then both state as target at the same time - -.. ipython:: - - In [38]: objFH = SquareLoss(theta, ode, x0, t0, t, solution[1::,:], ['V','R']) - - In [38]: res = scipy.optimize.minimize(fun=objFH.costIV, - ....: jac=objFH.sensitivityIV, - ....: x0=theta + [-0.5, 0.5], - ....: bounds=boxBounds, - ....: method='L-BFGS-B') - - In [39]: print(res) - -See the difference between the two estimate with the latter, both state were used, yielding superior estimates. Note that only the forward sensitivity method is implemented when estimating the initial value, and it is assumed that the starting condition for all the states are unknown. - -The choice of algorithm here is the **L-BFGS-B** which is a better choice because the parameter space of the FitzHugh is rough (i.e. large second derivative) as well as being multimodal. This means that the Hessian is not guaranteed to be positive definite and approximation using :math:`J^{\top}J` is poor, with :math:`J` being the Jacobian of the objective function. - - diff --git a/doc/doc_to_sort/gradient.rst b/doc/doc_to_sort/gradient.rst deleted file mode 100644 index 121bb6c3..00000000 --- a/doc/doc_to_sort/gradient.rst +++ /dev/null @@ -1,302 +0,0 @@ -.. _gradient: - -************************************* -Gradient estimation under square loss -************************************* - -Assuming that we have a set of :math:`N` observations :math:`y_{i}` at specific time points :math:`t_{i}`, :math:`i = 1,\ldots,N`, we may wish to test out a set of ode to see whether it fits to the data. The most natural way to test such *fit* is to minimize the sum of squares between our observations :math:`y` and see whether the resulting solution of the ode and the estimationed parameters makes sense. - -We assume that this estimation process will be tackled through a non-linear optimization point of view. However, it should be noted that such estimates can also be performed via MCMC or from a global optimization perspective. A key element in non-linear optimization is the gradient, which is the focus of this page. - -Multiple ways of obtaining the gradient have been implemented. All of them serve a certain purpose and may not be a viable/appropriate options depending on the type of ode. More generally, let :math:`d,p` be the number of states and paramters respectively. Then finite difference methods have a run order of :math:`O(p+1)` of the original ode, forward sensitivity require an integration of an ode of size :math:`(d+1)p` rather than :math:`d`. The adjoint method require two run of size :math:`d` in principle, but actual run time is dependent on the number of observations. - -For the details of the classes and methods, please refer to :ref:`mod`. - -Notation -======== - -We introduce the notations that will be used in the rest of the page, some of which may be slightly unconventional but necessary due to the complexity of the problem. Let :math:`x \in \mathbb{R}^{d}` and :math:`\theta \in \mathbb{R}^{p}` be the states and parameters respectively. The term *state* or *simulation* are used interchangeably, even though strictly speaking a state is :math:`x` whereas :math:`x(t)` is the simulation. An ode is defined as - -.. math:: - - f(x,\theta) = \dot{x} = \frac{\partial x}{\partial t} - -and usually comes with a set of initial conditions :math:`(x_0,t_0)` where :math:`t_0 \le t_{i} \forall i`. Let :math:`g(x,\theta)` be a function that maps the set of states to the observations, :math:`g : \mathbb{R}^{d} \rightarrow \mathbb{R}^{m}`. For compartmental problems, which is our focus, :math:`\nabla_{\theta}g(x,\theta)` is usually zero and :math:`\nabla_{x}g(x,\theta)` is an identity function for some or all of the states :math:`x`. Denote :math:`l(x_{0},\theta,x)` as our cost function :math:`l : \mathbb{R}^{m} \rightarrow \mathbb{R}` and :math:`L(x_{0},\theta,x)` be the sum of :math:`l(\cdot)`. Both :math:`x` and :math:`x_{0}` are usually dropped for simplicity. We will be dealing exclusively with square loss here, which means that - -.. math:: - - L(\theta) = \sum_{i=1}^{N} \left\| y_{i} - g(x(t_{i})) \right\|^{2} = \mathbf{e}^{\top} \mathbf{e} - -where :math:`\mathbf{e}` is the residual vector, with elements - -.. math:: - - e_{i} = y_{i} - x(t_{i}). - - -Model setup -=========== - -Again, we demonstrate the functionalities of our classes using an SIR model. - -.. ipython:: - - In [1]: from pygom import SquareLoss, common_models - - In [2]: import copy,time,numpy - - In [2]: ode = common_models.SIR() - - In [3]: paramEval = [('beta',0.5), ('gamma',1.0/3.0) ] - - In [7]: # the initial state, normalized to zero one - - In [8]: x0 = [1., 1.27e-6, 0.] - - In [5]: # initial time - - In [6]: t0 = 0 - - In [5]: ode.parameters = paramEval - - In [6]: ode.initial_values = (x0, t0) - - In [9]: # set the time sequence that we would like to observe - - In [10]: t = numpy.linspace(1, 150, 100) - - In [11]: numStep = len(t) - - In [11]: solution = ode.integrate(t) - - In [12]: y = solution[1::,2].copy() - - In [13]: y += numpy.random.normal(0, 0.1, y.shape) - -Now we have set up the model along with some observations, obtaining the gradient only requires the end user to put the appropriate information it into the class :class:`SquareLoss`. Given the initial guess :math:`\theta` - -.. ipython:: - - In [210]: theta = [0.2, 0.2] - -We initialize the :class:`SquareLoss` simply as - -.. ipython:: - - In [20]: objSIR = SquareLoss(theta, ode, x0, t0, t, y, 'R') - -where the we also have to specify the state our observations are from. Now, we demonstrate the different methods in obtaining the gradient and mathematics behind it. - -Forward sensitivity -=================== - -The forward sensitivity equations are derived by differentiating the states implicitly, which yields - -.. math:: - - \frac{d\dot{x}}{d\theta} = \frac{\partial f}{\partial x}\frac{dx}{d\theta} + \frac{\partial f}{\partial \theta}. - -So finding the sensitivies :math:`\frac{dx}{d\theta}` simply require another integration of a :math:`p` coupled ode of :math:`d` dimension, each with the same Jacobian as the original ode. This integration is performed along with the original ode because of possible non-linearity. - -A direct call to the method :meth:`sensitivity ` computed the gradient - -.. ipython:: - - In [33]: gradSens = objSIR.sensitivity() - -whereas :meth:`.jac` will allow the end user to obtain the Jacobian (of the objective function) and the residuals, the information required to get the gradient as we see next. - -.. ipython:: - - In [33]: objJac, output = objSIR.jac(full_output=True) - - -Gradient -======== - -Just the sensitivities alone are not enough to obtain the gradient, but we are :math:`90\%` there. Differentiating the loss function - -.. math:: - - \frac{dL}{d\theta} &= \nabla_{\theta} \sum_{i=1}^{N}\frac{dl}{dg} \\ - &= \sum_{i=1}^{N} \frac{\partial l}{\partial x}\frac{dx}{d\theta} + \frac{\partial l}{\partial \theta} \\ - &= \sum_{i=1}^{N} \frac{\partial l}{\partial g}\frac{\partial g}{\partial x}\frac{dx}{d\theta} + \frac{\partial l}{\partial g}\frac{\partial g}{\partial \theta} - -via chain rule. When :math:`\frac{\partial g}{\partial \theta} = 0`, the total gradient simplifies to - -.. math:: - - \frac{dL}{d\theta} = \sum_{i=1}^{N} \frac{\partial l}{\partial g}\frac{\partial g}{\partial x}\frac{dx}{d\theta} - -Obviously, the time indicies are dropped above but all the terms above are evaluated only at the observed time points. More concretely, this means that - -.. math:: - - \frac{\partial l(x(j),\theta)}{\partial g} = \left\{ \begin{array}{ll} -2(y_{i} - x(j)) & , \; j = t_{i} \\ 0 & \; \text{otherwise} \end{array} \right. - -When :math:`g(\cdot)` is an identity function (which is assumed to be the case in :class:`SquareLoss`) - -.. math:: - - \frac{\partial g(x(t_{i}),\theta)}{\partial x} = I_{d} - -then the gradient simplifies even further as it is simply - -.. math:: - - \frac{dL}{d\theta} = -2\mathbf{e}^{\top}\mathbf{S} - -where :math:`\mathbf{e}` is the vector of residuals and :math:`\mathbf{S} = \left[\mathbf{s}_{1},\mathbf{s}_{2},\ldots,\mathbf{s}_{n}\right]` with elements - -.. math:: - - \mathbf{s}_{i} = \frac{dx}{d\theta}(t_{i}), - -the solution of the forward sensitivies at time :math:`t_{i}`, obtained from solving the coupled ode as mentioned previously. - -Jacobian -======== - -Now note how the gradient simplifies to :math:`-2\mathbf{e}^{\top}\mathbf{S}`. Recall that a standard result in non-linear programming states that the gradient of a sum of sqaures objective function :math:`L(\theta,y,x)` is - -.. math:: - - \nabla_{\theta} L(\theta,y,x) = -2(\mathbf{J}^{T} \left[\mathbf{y} - \mathbf{f}(x,\boldsymbol{\theta}) \right] )^{\top} - -with :math:`f(x,\theta)` our non-linear function and :math:`J` our Jacobian with elements - -.. math:: - - J_{i} = \frac{\partial f(x_{i},\boldsymbol{\theta})}{\partial \boldsymbol{\theta}}. - -This is exactly what we have seen previously, substituting in reveals that :math:`J = \mathbf{S}`. Hence, the Jacobian is (a necessary)by product when we wish to obtain the gradient. In fact, this is exactly how we proceed in :func:`sensitivity ` where it makes an internal call to :func:`jac ` to obtain the Jacobian first. This allows the end user to have more options when choosing which type of algorithms to use, i.e. Gauss-Newton or Levenberg-Marquardt. - -To check that the output is in fact the same - -.. ipython:: - - In [1]: objJac.transpose().dot(-2*output['resid']) - gradSens - -Adjoint -======= - -When the number of parameters increases, the number of sensitivies also increases. The time required scales directly with the number of parameters. We describe another method which does not depend on the number of parameters, but rather, the number of states and observations. - -The full derivations will not be shown here, but we aim to provide enough information to work out the steps performed in the our code. Let write our optimization problem as - -.. math:: - - min_{\theta} \quad & \int_{t_{0}}^{T} l(x_{0},\theta,x(t)) dt \\ - s.t. \quad & \dot{x} = f(x,\theta) - -which is identical to the original problem but in a continuous setting. Now write the constrained problem in the Lagrangian form - -.. math:: - - min_{\theta} \; L(\theta) + \int_{t_{0}}^{T} \lambda^{\top}(\dot{x} - f(x,\theta)) - -with Lagrangian multiplier :math:`\lambda \ge 0`. After some algebraic manipulation, it can be shown that the total derivative of the Lagrangian function is - -.. math:: - - \frac{dL}{d\theta} = \int_{t_{0}}^{T} \left(\frac{\partial l}{\partial \theta} - \lambda^{\top}\frac{\partial f}{\partial \theta} \right) dt. - -Using previously defined loss functions (the identity), the first term is zero and evaluating :math:`\frac{\partial f}{\partial \theta}` is trivial. What remains is the calculation of :math:`\lambda(t)` for :math:`t \in \left[t_{0},T\right]`. - -Although this still seem to be ill-posed problem when Looking at the Lagrangian function, one can actually obtain the *adjoint equation*, after certain assumptions and - -.. math:: - - \frac{d\lambda^{\top}}{dt} = \frac{\partial l}{\partial x} - \lambda^{\top}\frac{\partial f}{\partial \theta}. - -which is again an integration. An unfortunate situation arise here for non-linear systems because we use the minus Jacobian in the adjoint equation. So if the eigenvalues of the Jacobian indicate that our original ode is stable, such as -1, the minus eigenvalues (now 1) implies that the adjoint equation is not stable. Therefore, one must integrate backward in time to solve the adjoint equation and it cannot be solved simultaneously as the ode, unlike the forward sensitivity equations. - -Given a non-linearity ode, we must store information about the states between :math:`t_{0}` and :math:`T` in order to perform the integration. There are two options, both require storing many evaluated :math:`x(j)` within the interval :math:`\left[t_{0},T\right]`. Unfortunately, only one is available; interpolation over all states and integrate using the interpolating functions. The alternative of using observed :math:`x(j)'s` at fixed points is not competitive because we are unable to use fortran routines for the integration - -The method of choice here to perform the adjoint calcuation is to run a forward integration, then perform an interpolation using splines with explicit knots at the observed time points. - -.. ipython:: - - In [326]: odeSIRAdjoint, outputAdjoint = objSIR.adjoint(full_output=True) - -This is because evaluating the Jacobian may be expensive and Runge-kutta method suffers as the complexity increases. In non-linear model such as those found in epidemiology, each element of the Jacobian may be the result of a complicated equation where linear step method will shine as it makes as little function evaluation as possible. -Note that derivations in the literature, the initial condition when evaluating the adjoint equation is :math:`\lambda(T)=0`. But in our code we used :math:`\lambda(T) = -2(y(T)-x(T))`. Recall that we have observation :math:`y(T)` and simulation :math:`x(T)`, so that the adjoint equation evaluated at time :math:`T` - -.. math:: - - \frac{\partial \lambda^{\top}}{\partial t} \Big|_{T} = -2(y-f(x,\theta))\Big|_{T} - \lambda(T)\frac{\partial f}{\partial \theta}\Big|_{T} - -with the second term equal to zero. Integration under step size :math:`h` implies that :math:`\lambda(T) \approx \lim_{h \to 0} \lambda(T-h) = -2(y(T)-x(T))`. - -Time Comparison -=============== - -A simple time comparison between the different methods reveals that the forward sensitivity method dominates the others by a wide margin. It will be tempting to conclude that it is the best and should be the default at all times but that is not true, due to the complexity of each method mentioned previously. We leave it to the end user to find out the best method for their specific problem. - -.. ipython:: - - In [319]: %timeit gradSens = objSIR.sensitivity() - - In [326]: %timeit odeSIRAdjoint,outputAdjoint = objSIR.adjoint(full_output=True) - - -Hessian -======= - -The Hessian is defined by - -.. math:: - - \frac{\partial^{2} l}{\partial \theta^{2}} = \left( \frac{\partial l}{\partial x} \otimes I_{p} \right) \frac{\partial^{2} x}{\partial \theta^{2}} + \frac{\partial x}{\partial \theta}^{\top}\frac{\partial^{2} l}{\partial x^{2}}\frac{\partial x}{\partial \theta} - -where :math:`\otimes` is the Kronecker product. Note that :math:`\nabla_{\theta} x` is the sensitivity and the second order sensitivities can be found again via the forward method, which involve another set of ode's, namely the forward-forward sensitivities - -.. math:: - - \frac{\partial}{\partial t}\left(\frac{\partial^{2} x}{\partial \theta^{2}}\right) = \left( \frac{\partial f}{\partial x} \otimes I_{p} \right) \frac{\partial^{2} x}{\partial \theta^{2}} + \left( I_{d} \otimes \frac{\partial x}{\partial \theta}^{\top} \right) \frac{\partial^{2} f}{\partial x^{2}} \frac{\partial x}{\partial \theta}. - -From before, we know that - -.. math:: - - \frac{\partial l}{\partial x} = (-2y+2x) \quad and \quad \frac{\partial^{2} l}{\partial x^{2}} = 2I_{d} - -so our Hessian reduces to - -.. math:: - - \frac{\partial^{2} l}{\partial \theta^{2}} = \left( \left(-2y+2x\right) \otimes I_{p} \right) \frac{\partial^{2} x}{\partial \theta^{2}} + 2S^{\top}S, - -where the second term is a good approximation to the Hessian as mentioned previously. This is the only implementation in place so far even though obtaining the estimate this way is relatively slow. - -Just to demonstate how it works, lets look at the Hessian at the optimal point. First, we obtain the optimal value - -.. ipython:: - - In [211]: import scipy.linalg,scipy.optimize - - In [212]: boxBounds = [(0.0, 2.0), (0.0, 2.0)] - - In [213]: res = scipy.optimize.minimize(fun=objSIR.cost, - .....: jac=objSIR.sensitivity, - .....: x0=theta, - .....: bounds=boxBounds, - .....: method='L-BFGS-B') - -Then compare again the least square estimate of the covariance matrix against our version - -.. ipython:: - - In [211]: resLS, cov_x, infodict, mesg, ier = scipy.optimize.leastsq(func=objSIR.residual, x0=res['x'], full_output=True) - - In [212]: HJTJ, outputHJTJ = objSIR.hessian(full_output=True) - - In [311]: print(scipy.linalg.inv(HJTJ)) - - In [312]: print(cov_x) - -also note the difference between the Hessian and the approximation using the Jacobian, which is in fact what the least squares routine uses. - -.. ipython:: - - In [313]: print(scipy.linalg.inv(outputHJTJ['JTJ'])) diff --git a/doc/doc_to_sort/initialGuess.rst b/doc/doc_to_sort/initialGuess.rst deleted file mode 100644 index 97e6a037..00000000 --- a/doc/doc_to_sort/initialGuess.rst +++ /dev/null @@ -1,47 +0,0 @@ -.. _initialGuess: - -******************************************* -Obtaining good initial value for parameters -******************************************* - -Function Interpolation -====================== - -When we want to fit the model to data, one of the necessary steps is to supply the optimization procedure a good set of initial guess for the parameters :math:`\theta`. This may be a challenge when we do have a good understanding of the process we are trying to model i.e. infectious disease may all follow the same SIR process but with vastly different incubation period. - -A method to obtain such initial guess based on the collocation is available in this package. A restriction is that data must be present for all states. We demonstrate this using the FitzHugh-Nagumo model. - - -.. ipython:: - - In [1]: from pygom import SquareLoss, common_models, get_init - - In [2]: import numpy - - In [3]: x0 = [-1.0, 1.0] - - In [4]: t0 = 0 - - In [5]: # params - - In [6]: paramEval = [('a',0.2), ('b',0.2), ('c',3.0)] - - In [7]: ode = common_models.FitzHugh(paramEval) - - In [8]: ode.initial_values = (x0, t0) - - In [8]: t = numpy.linspace(1, 20, 30).astype('float64') - - In [9]: solution = ode.integrate(t) - -Below, we try to find the initial guess without supplying any further information. The underlying method fits a cubic spline against the observation and tries to minimize the difference between the first derivative of the spline and the function of the ode. Varying degree of smoothness penalty is applied to the spline and the best set of parameters is the ones that yields the smallest total error, combining both the fit of the spline against data and the spline against the ode. - -.. ipython:: - - In [10]: theta, sInfo = get_init(solution[1::,:], t, ode, theta=None, full_output=True) - - In [11]: print(theta) - - In [12]: print(sInfo) - -As seen above, we have obtained a very good guess of the parameters, in fact almost the same as the generating process. The information regarding the smoothing factor shows that the amount of penalty used is small, which is expected given that we use the solution of the ode as observations. diff --git a/doc/doc_to_sort/mod/common_models.rst b/doc/doc_to_sort/mod/common_models.rst deleted file mode 100644 index e193a655..00000000 --- a/doc/doc_to_sort/mod/common_models.rst +++ /dev/null @@ -1,8 +0,0 @@ - -common_models -============= - -.. automodule:: pygom.model.common_models - :members: - :noindex: - diff --git a/doc/doc_to_sort/mod/confidence_interval.rst b/doc/doc_to_sort/mod/confidence_interval.rst deleted file mode 100644 index f0af3c3c..00000000 --- a/doc/doc_to_sort/mod/confidence_interval.rst +++ /dev/null @@ -1,7 +0,0 @@ - -loss_type -========= - -.. automodule:: pygom.loss.loss_type - :members: - :noindex: diff --git a/doc/doc_to_sort/mod/deterministic.rst b/doc/doc_to_sort/mod/deterministic.rst deleted file mode 100644 index fe10281e..00000000 --- a/doc/doc_to_sort/mod/deterministic.rst +++ /dev/null @@ -1,7 +0,0 @@ -deterministic -============= - -.. automodule:: pygom.model.deterministic - :members: - :noindex: - \ No newline at end of file diff --git a/doc/doc_to_sort/mod/epi_analysis.rst b/doc/doc_to_sort/mod/epi_analysis.rst deleted file mode 100644 index 751d846b..00000000 --- a/doc/doc_to_sort/mod/epi_analysis.rst +++ /dev/null @@ -1,7 +0,0 @@ -epi_analysis -============ - -.. automodule:: pygom.model.epi_analysis - :members: - :noindex: - \ No newline at end of file diff --git a/doc/doc_to_sort/mod/get_init.rst b/doc/doc_to_sort/mod/get_init.rst deleted file mode 100644 index df85fa99..00000000 --- a/doc/doc_to_sort/mod/get_init.rst +++ /dev/null @@ -1,7 +0,0 @@ -get_init -======== - -.. automodule:: pygom.loss.get_init - :members: - :noindex: - \ No newline at end of file diff --git a/doc/doc_to_sort/mod/index.rst b/doc/doc_to_sort/mod/index.rst deleted file mode 100644 index 5c5362ab..00000000 --- a/doc/doc_to_sort/mod/index.rst +++ /dev/null @@ -1,30 +0,0 @@ -.. _mod: - - -******************* -Code documentations -******************* - -===== -model -===== - -.. toctree:: - - common_models - transition - deterministic - simulate - epi_analysis - odeutils - -==== -loss -==== - -.. toctree:: - - odeloss - losstype - confidence_interval - get_init diff --git a/doc/doc_to_sort/mod/losstype.rst b/doc/doc_to_sort/mod/losstype.rst deleted file mode 100644 index 00cbf46c..00000000 --- a/doc/doc_to_sort/mod/losstype.rst +++ /dev/null @@ -1,7 +0,0 @@ - -confidence_interval -=================== - -.. automodule:: pygom.loss.confidence_interval - :members: - :noindex: diff --git a/doc/doc_to_sort/mod/odeloss.rst b/doc/doc_to_sort/mod/odeloss.rst deleted file mode 100644 index 65ceea3a..00000000 --- a/doc/doc_to_sort/mod/odeloss.rst +++ /dev/null @@ -1,17 +0,0 @@ -ode_loss -======== - -These are basically the interfaces for :class:`pygom.loss.BaseLoss` - -.. automodule:: pygom.loss.ode_loss - :members: - :noindex: - -calculations -============ - -The base class which contains has all the calculation implemented - -.. automodule:: pygom.loss.base_loss - :members: - :noindex: diff --git a/doc/doc_to_sort/mod/odeutils.rst b/doc/doc_to_sort/mod/odeutils.rst deleted file mode 100644 index 87d7b550..00000000 --- a/doc/doc_to_sort/mod/odeutils.rst +++ /dev/null @@ -1,7 +0,0 @@ - -ode_utils -========= - -.. automodule:: pygom.model.ode_utils - :members: - :noindex: diff --git a/doc/doc_to_sort/mod/simulate.rst b/doc/doc_to_sort/mod/simulate.rst deleted file mode 100644 index 7aaa9d01..00000000 --- a/doc/doc_to_sort/mod/simulate.rst +++ /dev/null @@ -1,8 +0,0 @@ - -stochastic -========== - -.. automodule:: pygom.model.simulate - :members: - :noindex: - diff --git a/doc/doc_to_sort/mod/transition.rst b/doc/doc_to_sort/mod/transition.rst deleted file mode 100644 index 2901c1e2..00000000 --- a/doc/doc_to_sort/mod/transition.rst +++ /dev/null @@ -1,8 +0,0 @@ - -transition -========== - -.. automodule:: pygom.model.transition - :members: - :noindex: - diff --git a/doc/doc_to_sort/profile.rst b/doc/doc_to_sort/profile.rst deleted file mode 100644 index dd8f0d77..00000000 --- a/doc/doc_to_sort/profile.rst +++ /dev/null @@ -1,433 +0,0 @@ -.. _profile: - -******************************************* -Confidence Interval of Estimated Parameters -******************************************* - -After obtaining the *best* fit, it is natural to report both the point estimate and the confidence level at the :math:`\alpha` level. The easiest way to do this is by invoking the normality argument and use Fisher information of the likelihood. As explained previously at the bottom of :ref:`gradient`, we can find the Hessian, :math:`\mathbf{H}`, or the approximated Hessian for the estimated parameters. The Cramer--Rao inequality, we know that - -.. math:: - Var(\hat{\theta}) \ge \frac{1}{I(\theta)}, - -where :math:`I(\theta)` is the Fisher information, which is the Hessian subject to regularity condition. Given the Hessian, computing the confidence intervals is trivial. Note that this is also known as the asymptotic confidence interval where the normality comes from invoking the CLT. There are other ways of obtaining a confidence intervals, we will the ones implemented in the package. First, we will set up a SIR model as seen in :ref:`sir` which will be used throughout this page. - -.. ipython:: - - In [1]: from pygom import NormalLoss, common_models - - In [2]: from pygom.utilR import qchisq - - In [3]: import numpy - - In [4]: import scipy.integrate - - In [5]: import matplotlib.pyplot as plt - - In [6]: import copy - - In [7]: ode = common_models.SIR([('beta', 0.5), ('gamma', 1.0/3.0)]) - -and we assume that we only have observed realization from the :math:`R` compartment - -.. ipython:: - - In [1]: x0 = [1, 1.27e-6, 0] - - In [2]: t = numpy.linspace(0, 150, 100).astype('float64') - - In [3]: ode.initial_values = (x0, t[0]) - - In [4]: solution = ode.integrate(t[1::]) - - In [5]: theta = [0.2, 0.2] - - In [6]: targetState = ['R'] - - In [7]: targetStateIndex = numpy.array(ode.get_state_index(targetState)) - - In [8]: y = solution[1::,targetStateIndex] + numpy.random.normal(0, 0.01, (len(solution[1::,targetStateIndex]), 1)) - - In [9]: yObv = y.copy() - - In [10]: objSIR = NormalLoss(theta, ode, x0, t[0], t[1::], y, targetState) - - In [11]: boxBounds = [(1e-8, 2.0), (1e-8, 2.0)] - - In [12]: boxBoundsArray = numpy.array(boxBounds) - - In [13]: xhat = objSIR.fit(theta, lb=boxBoundsArray[:,0], ub=boxBoundsArray[:,1]) - -Asymptotic -========== - -When the estimate is obtained say, under a square loss or a normal assumption, the corresponding likelihood can be written down easily. In such a case, likelihood ratio test under a Chi--squared distribution is - -.. math:: - - 2 (\mathcal{L}(\hat{\boldsymbol{\theta}}) - \mathcal{L}(\boldsymbol{\theta})) \le \chi_{1 - \alpha}^{2}(k) - -where :math:`1-\alpha` is the size of the confidence region and :math:`k` is the degree of freedom. The corresponding asymptotic confidence interval for parameter :math:`j` can be derived as - -.. math:: - - \hat{\theta}_{j} \pm \sqrt{\chi_{1 - \alpha}^{2}(k) H_{i,i}}. - -A pointwise confidence interval is obtained when :math:`k = 1`. We assume in our package that a pointwise confidence interval is desired. This can be obtained simply by - -.. ipython:: - - In [1]: from pygom import confidence_interval as ci - - In [2]: alpha = 0.05 - - In [3]: xL, xU = ci.asymptotic(objSIR, alpha, xhat, lb=boxBoundsArray[:,0], ub=boxBoundsArray[:,1]) - - In [4]: print(xL) - - In [5]: print(xU) - -Note that the set of bounds here is only used for check the validity of :math:`\hat{\mathbf{x}}` and not used in the calculation of the confidence intervals. Therefore the resulting output can be outside of the box constraints. - -Profile Likelihood -================== - -Another approach to calculate the confidence interval is to tackle one parameter at a time, treating the rest of them as nuisance parameters, hence the term *profile*. Let :math:`\mathcal{L}(\boldsymbol{\theta})` be our log--likelihood with parameter :math:`\boldsymbol{\theta}`. Element :math:`\theta_{j}` is our parameter of interest and :math:`\boldsymbol{\theta}_{-j}` represents the complement such that :math:`\boldsymbol{\theta} = \theta_{j} \cup \boldsymbol{\theta}_{-j}`. For simply models such as linear regression with only regression coefficients :math:`\boldsymbol{\beta}`, then :math:`\boldsymbol{\theta} = \boldsymbol{\beta}`. - -To shorten the notation, let - -.. math:: \mathcal{L}(\boldsymbol{\theta}_{-j} \mid \theta_{j}) = \max \mathcal{L}(\boldsymbol{\theta}_{-j} \mid \theta_{j}) - :label: nuisanceOptim - -which is the maxima of :math:`\boldsymbol{\theta}_{-j}` given :math:`\theta_{j}`. :math:`\hat{\boldsymbol{\theta}}` denotes the MLE of the parameters as usual. The profile--likelihood based confidence interval for :math:`\theta_{j}` is defined as - -.. math:: - - \theta_{j}^{U} &= \sup \left\{ \mathcal{L}(\hat{\boldsymbol{\theta}}) - \mathcal{L}(\boldsymbol{\theta} \mid \theta_{j}) \le \frac{1}{2} \chi_{1 - \alpha}^{2}(1) \right\} \\ - \theta_{j}^{L} &= \inf \left\{ \mathcal{L}(\hat{\boldsymbol{\theta}}) - \mathcal{L}(\boldsymbol{\theta} \mid \theta_{j}) \le \frac{1}{2} \chi_{1 - \alpha}^{2}(1) \right\} - -where again we have made use of the normal approximation, but without imposing symmetry. The set of equations above automatically implies that the interval width is :math:`\theta_{j}^{U} - \theta_{j}^{L}` and - -.. math:: - - \mathcal{L}(\hat{\boldsymbol{\theta}}) - \frac{1}{2} \chi_{1-\alpha}^{2}(1) - \mathcal{L}(\boldsymbol{\theta} \mid \theta_{j}) = 0. - -As mentioned previously, :math:`\boldsymbol{\theta}_{-j}` is the maximizer of the nuisance parameters, which has a gradient of zero. Combining this with the equation above yields a non--linear system of equations of size :math:`p`, - -.. math:: g(\boldsymbol{\theta}) = \left[ \begin{array}{c} \mathcal{L}(\boldsymbol{\theta} \mid \theta_{j}) - c \\ \frac{\partial \mathcal{L}(\boldsymbol{\theta} \mid \theta_{j})}{\partial \boldsymbol{\theta}_{-j}} \end{array} \right] = 0 - :label: obj - -where :math:`c = \mathcal{L}(\hat{\boldsymbol{\theta}}) + \frac{1}{2} \chi_{1-\alpha}^{2}(1)`. Solving this set of system of equations only need simple Newton like steps, possibly with correction terms as per [Venzon1988]_. We provide a function to obtain such estimate - -.. ipython:: - :verbatim: - - In [1]: xLProfile, xUProfile, xLProfileList, xUProfileList = ci.profile(objSIR, alpha, xhat, lb=boxBoundsArray[:,0], ub=boxBoundsArray[:,1], full_output=True) - -but unfortunately this is not accurate most of the time due to the complicated surface at locations not around :math:`\hat{\theta}`. This is a common scenario for non--linear least square problems because the Hessian is not guaranteed to be a PSD everywhere. Therefore, a safeguard is in place to obtain the :math:`\theta_{j}^{U},\theta_{j}^{L}` by iteratively by updating :math:`\theta_{j}` and find the solution to :eq:`nuisanceOptim`. - -Furthermore, we also provide the functions necessary to obtain the estimates such as the four below. - -.. ipython:: - - In [1]: i = 0 - - In [1]: funcF = ci._profileF(xhat, i, 0.05, objSIR) - - In [2]: funcG = ci._profileG(xhat, i, 0.05, objSIR) - - In [3]: funcGC = ci._profileGSecondOrderCorrection(xhat, i, alpha, objSIR) - - In [4]: funcH = ci._profileH(xhat, i, 0.05, objSIR) - -Where :math:`i` is the index of the parameter of interest. :func:`_profileF` is the squared norm of :eq:`obj`, which easy the optimization process for solvers which requires a converted form from system of equations to non-linear least squares. :func:`_profileG` is the systems of equations :eq:`obj`, :func:`_profileH` is the derivative of :eq:`obj` - -.. math:: - \nabla g(\boldsymbol{\theta}) = \left[ \begin{array}{c} \frac{\partial \mathcal{L}(\boldsymbol{\theta} \mid \theta_{j})}{\partial \theta_{j}} \\ \frac{\partial^{2} \mathcal{L}(\boldsymbol{\theta} \mid \theta_{j})}{\partial \boldsymbol{\beta}_{-j} \partial \theta_{j}} \end{array} \right] - -and :func:`_profileGSecondOrderCorrection` has the second order correction [Venzon1988]_. - -Geometric profile likelihood -============================ - -Due to the difficulty in obtain a profile likelihood via the standard Newton like steps, we also provide a way to generate a similar result using the geometric structure of the likelihood surface. We follow the method in [Moolgavkar1987]_, which involves solving a set of differential equations - -.. math:: - \frac{d\beta_{j}}{dt} &= k g^{-1/2} \\ - \frac{d\boldsymbol{\beta}_{-j}}{dt} &= \frac{d\boldsymbol{\beta}_{-j}}{d\beta_{j}} \frac{d\beta_{j}}{dt}, - -where :math:`k = \Phi(1-\alpha)` is the quantile we want to obtain under a normal distribution, and - -.. math:: - - g = J_{\beta_{j}}^{\top} I^{\boldsymbol{\beta}} J_{\beta_{j}}, \quad J_{\beta_{j}} = \left( \begin{array}{c} 1 \\ \frac{d\boldsymbol{\beta}_{-j}}{d\beta_{j}} \end{array} \right). - -Here, :math:`J_{\beta_{j}}` is the Jacobian between :math:`\beta_{j}` and :math:`\boldsymbol{\beta}_{-j}` with the term - -.. math:: - - \frac{d\boldsymbol{\beta}_{-j}}{d\beta_{j}} = -\left( \frac{\partial^{2} \mathcal{L}}{\partial \boldsymbol{\beta}_{-j}\partial \boldsymbol{\beta}_{-j}^{\top} } \right)^{-1} \frac{\partial^{2} \mathcal{L}}{\partial \beta_{j} \partial \beta_{-j}^{\top}} - -and hence the first element is :math:`1` (identity transformation). :math:`I^{\boldsymbol{\beta}}` is the Fisher information of :math:`\boldsymbol{\beta}`, which is - -.. math:: - - I^{\boldsymbol{\beta}} = \frac{\partial \boldsymbol{\theta}}{\partial \boldsymbol{\beta}^{\top}} \Sigma^{\boldsymbol{\theta}(\boldsymbol{\beta})} \frac{\partial \boldsymbol{\theta}}{\partial \boldsymbol{\beta}}. - -It is simply :math:`\Sigma^{\boldsymbol{\beta}}` if :math:`\boldsymbol{\theta} = \boldsymbol{\beta}`. Different Fisher information can be used for :math:`\Sigma^{\boldsymbol{\beta}}` such as the expected or observed, at :math:`\hat{\boldsymbol{\beta}}` or :math:`\boldsymbol{\beta}`. After some trivial algebraic manipulation, we can show that our ode boils downs to - -.. math:: - - \left[ \begin{array}{c} \frac{d\beta_{j}}{dt} \\ \frac{d\boldsymbol{\beta_{-j}}}{dt} \end{array} \right] = k \left[ \begin{array}{c} 1 \\ -A^{-1}w \end{array} \right] \left( v - w^{\top}A^{-1}w \right)^{-1/2} - -where the symbols on the RHS above correspond to partitions in the Fisher information - -.. math:: - - I^{\boldsymbol{\beta}} = \left[ \begin{array}{cc} v & w^{\top} \\ w & A \end{array} \right]. - -The integration is perform from :math:`t = 0` to :math:`1` and is all handled internally via :func:`geometric` - -.. ipython:: - - In [1]: xLGeometric, xUGeometric, xLList, xUList = ci.geometric(objSIR, alpha, xhat, full_output=True) - - In [2]: print(xLGeometric) - - In [3]: print(xUGeometric) - -Bootstrap -========= - -This is perhaps the favorite method to estimate confidence interval for a lot of people. Although there are many ways to implement bootstrap, semi-parametric is the only logical choice (even though the underlying assumptions may be violated at times). As we have only implemented OLS type loss functions in this package, the parametric approach seem to be inappropriate when there is no self--efficiency guarantee. Non-parametric approach requires at least a conditional independence assumption, something easily violated by our **ode**. Block bootstrap is an option but we are also aware that the errors of an **ode** can be rather rigid, and consistently over/under estimate at certain periods of time. - -When we say semi-parametric, we mean the exchange of errors between the observations. Let our raw error be - -.. math:: - - \varepsilon_{i} = y_{i} - \hat{y}_{i} - -where :math:`\hat{y}_{i}` will be the prediction under :math:`\hat{\boldsymbol{\theta}}` under our model. Then we construct a new set of observations via - -.. math:: - - y_{i}^{\ast} = \hat{y}_{i} + \varepsilon^{\ast}, \quad \varepsilon^{\ast} \sim \mathcal{F} - -with :math:`\mathcal{F}` being the empirical distribution of the raw errors. A new set of parameters :math:`\theta^{\ast}` are then found for the bootstrapped samples, and we obtain the :math:`\alpha` confidence interval by taking the :math:`\alpha/2` quantiles. Invoke the correspond python function yields our bootstrap estimates. Unlike :func:`asymptotic`, the bounds here are used when estimating the parameters of each bootstrap samples. An error may be returned if estimation failed for any of the bootstrap samples. - -.. ipython:: - - In [1]: xLBootstrap, xUBootstrap, setX = ci.bootstrap(objSIR, alpha, xhat, iteration=10, lb=boxBoundsArray[:,0], ub=boxBoundsArray[:,1], full_output=True) - - In [2]: print(xLBootstrap) - - In [3]: print(xUBootstrap) - -The additional information here can be used to compute the bias, tail effects and test against the normality assumption. If desired, a simultaneous confidence interval can also be approximated empirically. Note however that because we are using a semi--parameter method here, if the model specification is wrong then the resulting estimates for the bias is also wrong. The confidence interval still has the normal approximation guarantee if number of sample is large. - -In this case, because the error in the observation is extremely small, the confidence interval is narrow. - -.. ipython:: - - In [1]: import pylab as P - - In [2]: f = plt.figure() - - In [3]: n, bins, patches = P.hist(setX[:,0], 50) - - In [4]: P.xlabel(r'Estimates of $\beta$'); - - In [5]: P.ylabel('Frequency'); - - In [6]: P.title('Estimates under a semi-parametric bootstrap scheme'); - - @savefig bootstrapCIHist.png - In [7]: P.show() - - In [8]: P.close() - -Comparison Between Methods -========================== - -Although we have shown the numerical values for the confidence interval obtained using different method, it may be hard to comprehend how they vary. As they say, a picture says a million word, and given that this particular model only has two parameters, we can obtain inspect and compare the methods visually via a contour plot. The code to perform this is shown below but the code block will not be run to save time and space. - -.. ipython :: - :verbatim: - - In [1]: niter = 1000 - - In [2]: randNum = numpy.random.rand(niter,2)*2.0 - - In [3]: target = [objSIR.cost(randNum[i,:]) for i in range(niter)] - - In [4]: z = numpy.array(target) - - In [5]: x = randNum[:,0] - - In [6]: y = randNum[:,1] - - In [7]: from scipy.interpolate import griddata - - In [8]: xi = numpy.linspace(0.0, 2.0, 100) - - In [9]: yi = numpy.linspace(0.0, 2.0, 100) - - In [10]: zi = griddata((x, y), numpy.log(z), (xi[None,:], yi[:,None]), method='cubic') - - In [11]: fig = plt.figure() - - In [12]: CS = plt.contour(xi, yi, zi, linewidth=0.5) - - In [13]: plt.clabel(CS, fontsize=10, inline=1); - - In [14]: l0 = plt.scatter(xhat[0], xhat[1], marker='o', c='k', s=30) - - In [15]: l1 = plt.scatter(numpy.append(xL[0], xU[0]), numpy.append(xL[1], xU[1]), marker='x', c='m', s=30) - - In [16]: l2 = plt.scatter(numpy.append(xLBootstrap[0], xUBootstrap[0]), numpy.append(xLBootstrap[1], xUBootstrap[1]), marker='x', c='g', s=30) - - In [17]: l3 = plt.scatter(numpy.append(xLGeometric[0], xUGeometric[0]), numpy.append(xLGeometric[1], xUGeometric[1]), marker='x', c='r', s=30) - - In [19]: plt.legend((l0, l1, l2, l3), ('MLE', 'Asymptotic', 'Bootstrap', 'Geometric'), loc='upper left'); - - In [20]: plt.ylabel(r'Estimates of $\gamma$'); - - In [21]: plt.xlabel(r'Estimates of $\beta$'); - - In [22]: plt.title('Location of the confidence intervals on the likelihood surface'); - - In [23]: plt.tight_layout(); - - In [24]: plt.show() - - In [25]: plt.close() - -In the plot above, the bootstrap confidence interval were so close to the MLE, it is impossible to distinguish the two on such a coarse scale. - -Furthermore, because the geometric confidence interval is the result of an integration, we can trace the path that lead to the final output that was shown previously. Again, we are space conscious (and time constrained) so the code block below will not be run. - -.. ipython:: - :verbatim: - - In [1]: fig = plt.figure() - - In [2]: CS = plt.contour(xi, yi, zi, linewidth=0.5) - - In [3]: plt.clabel(CS, fontsize=10, inline=1) - - In [4]: l1 = plt.scatter(xLList[0][:,0], xLList[0][:,1], marker='o', c='m', s=10); - - In [5]: l2 = plt.scatter(xUList[0][:,0], xUList[0][:,1], marker='x', c='m', s=10); - - In [6]: plt.legend((l1, l2), ('Lower CI path', 'Upper CI path'), loc='upper left'); - - In [7]: plt.ylabel(r'Estimates of $\gamma$'); - - In [8]: plt.xlabel(r'Estimates of $\beta$'); - - In [9]: plt.title('Integration path of the geometric confidence intervals on the likelihood surface'); - - In [10]: plt.tight_layout(); - - In [11]: plt.show() - - In [12]: plt.close() - - -Profile Likelihood Surface -========================== - -To investigate why it was hard to find the profile likelihood confidence interval, we can simply look at the surface (which is simply a line as we are profiling). We find solution of :eq:`nuisanceOptim` for each :math:`\boldsymbol{\theta}_{-j}` at various points of :math:`\boldsymbol{\theta}`. Equivalently, we can minimize the original loss function as defined previously, and this is the approach below. We focus out attention to the parameter :math:`\beta` of our SIR model. The results are not shown here but the existence of a solution to :eq:`obj` is evident by simply *eyeballing* the plots. - -.. ipython:: - :verbatim: - - In [1]: numIter = 100 - - In [2]: x2 = numpy.linspace(0.0, 2.0, numIter) - - In [3]: funcOut = numpy.linspace(0.0, 2.0, numIter) - - In [4]: ode.parameters = [('beta',0.5), ('gamma',1.0/3.0)] - - In [5]: for i in range(numIter): - ...: paramEval = [('beta',x2[i]), ('gamma',x2[i])] - ...: ode2 = copy.deepcopy(ode) - ...: ode2.parameters = paramEval - ...: ode2.initial_values = (x0, t[0]) - ...: objSIR2 = NormalLoss(x2[i], ode2, x0, t[0], t[1::], yObv.copy(), targetState, target_param='gamma') - ...: res = scipy.optimize.minimize(fun=objSIR2.cost, - ...: jac=objSIR2.gradient, - ...: x0=x2[i], - ...: bounds=[(0,2)], - ...: method='L-BFGS-B') - ...: funcOut[i] = res['fun'] - - In [10]: fig = plt.figure() - - In [10]: plt.plot(x2, objSIR.cost(xhat) - funcOut) - - In [11]: l1 = plt.axhline(-0.5*qchisq(1 - alpha, df=1), 0, 2, color='r') - - In [12]: plt.ylabel(r'$\mathcal{L}(\hat{\theta}) - \mathcal{L}(\theta \mid \beta)$'); - - In [13]: plt.xlabel(r'Fixed value of $\beta$'); - - In [14]: plt.title('Difference in objective function between MLE\n and the maximization of the nuisance parameters given the\n parameter of interest, beta in this case'); - - In [15]: plt.tight_layout(); - - In [16]: plt.legend((l1,), (r'$-0.5\mathcal{X}_{1 - \alpha}^{2}(1)$',), loc='lower right'); - - @savefig profileLLMaximizerGivenBeta.png - In [17]: plt.show() # @savefig profileLLMaximizerGivenBeta.png - - In [18]: plt.close() - -Both the upper and lower confidence interval can be found in the profiling procedure, but the part between of :math:`\beta \in \left[0,\hat{\beta}\right]` is not convex, with :math:`\hat{\beta}` being the MLE. This non--quadratic profile likelihood is due to the non-identifiability of the model given data [Raue2009]_. For this particular case, we can fix it simply by introducing additional observations in the form of the :math:`I` state. We encourage the users to try it out for themselves to confirm. - -.. ipython:: - :verbatim: - - In [1]: targetState = ['I', 'R'] - - In [2]: targetStateIndex = numpy.array(ode.get_state_index(targetState)) - - In [3]: y = solution[1::,targetStateIndex] + numpy.random.normal(0, 0.01, (len(solution[1::,targetStateIndex]), 1)) - - In [4]: objSIR = NormalLoss(theta, ode, x0, t[0], t[1::], y.copy(), targetState) - - In [5]: xhat = objSIR.fit(theta, lb=boxBoundsArray[:,0], ub=boxBoundsArray[:,1]) - - In [6]: for i in range(numIter): - ...: paramEval = [('beta', x2[i]), ('gamma', x2[i])] - ...: ode2 = copy.deepcopy(ode) - ...: ode2.parameters = paramEval - ...: ode2.initial_values = (x0, t[0]) - ...: objSIR2 = NormalLoss(x2[i], ode2, x0, t[0], t[1::], y.copy(), targetState, target_param='gamma') - ...: res = scipy.optimize.minimize(fun=objSIR2.cost, - ...: jac=objSIR2.gradient, - ...: x0=x2[i], - ...: bounds=[(0,2)], - ...: method='L-BFGS-B') - ...: funcOut[i] = res['fun'] - - In [10]: fig = plt.figure() - - In [10]: plt.plot(x2, objSIR.cost(xhat) - funcOut); - - In [11]: l1 = plt.axhline(-0.5*qchisq(1 - alpha, df=1), 0, 2, color='r') - - In [12]: plt.ylabel(r'$\mathcal{L}(\hat{\theta}) - \mathcal{L}(\theta \mid \beta)$'); - - In [13]: plt.xlabel(r'Fixed value of $\beta$'); - - In [14]: plt.title('Profile likelihood curve for the parameter of\n interest with more observation'); - - In [15]: plt.tight_layout(); - - In [16]: plt.legend((l1,), (r'$-0.5\mathcal{X}_{1 - \alpha}^{2}(1)$',), loc='lower right'); - - @savefig profileLLMaximizerGivenBetaMoreObs.png - In [17]: plt.show() # @savefig profileLLMaximizerGivenBetaMoreObs.png - - In [18]: plt.close() diff --git a/doc/doc_to_sort/ref.rst b/doc/doc_to_sort/ref.rst deleted file mode 100644 index c1f0f93e..00000000 --- a/doc/doc_to_sort/ref.rst +++ /dev/null @@ -1,76 +0,0 @@ -.. _ref: - -********** -References -********** - -.. [Aron1984] Seasonality and period-doubling bifurcations in an epidemic model, - Joan L. Aron and Ira B. Schwartz, Journal of Theoretical Biology, Volume 110, - Issue 4, page 665-679, 1984 - -.. [Brauer2008] Mathematical Epidemiology, Lecture Notes in Mathematics, - Fred Brauer, Springer 2008 - -.. [Cao2006] Efficient step size selection for the tau-leaping simulation - method, Yang Cao et el., The Journal of Chemical Physics, Volume 124, - Issue 4, page 044109, 2006 - -.. [Finnie2016] EpiJSON: A unified data-format for epidemiology, - Thomas Finnie et al., Epidemics, Volume 15, page 20-26, 2016 - -.. [FitzHugh1961] Impulses and Physiological States in Theoretical Models of - Nerve Membrane, Richard FitzHugh, Biophysical Journal, Volume 1, Issue 6, - page 445-466, 1961 - -.. [Gillespie1977] Exact stochastic simulation of coupled chemical reactions, - Danial T. Gillespie, The Journal of Physical Chemistry, Volume 81, - Issue 25, page 2340-2361, 1977 - -.. [Girolami2011] Riemann manifold Langevin and Hamiltonian Monte Carlo methods, - Mark Girolami and Ben Calderhead, Journal of the Royal Statistical Society - Series B, Volume 73, Issue 2, page 123-214, 2011. - -.. [Hethcote1973] Asymptotic behavior in a deterministic epidemic model, - Herbert W. Hethcote, Bulletin of Mathematical Biology, Volume 35, - page 607-614, 1973 - -.. [Legrand2007] Understanding the dynamics of Ebola epidemics, - J. Legrand et al. Epidemiology and Infection, Volume 135, Issue 4, - page 610-621, 2007 - -.. [Lloyd1996] Spatial Heterogeneity in Epidemic Models, A.L. Lloyd and - R.M. May, Journal of Theoretical Biology, Volume 179, - Issue 1, page 1-11, 1996 - -.. [Lorenz1963] Deterministic Nonperiodic Flow, Edward N. Lorenz, Journal of - the Atmospheric Sciences, Volume 20, Issue 2, page 130-141, 1963 - -.. [Lotka1920] Analytical Note on Certain Rhythmic Relations in Organic Systems, - Alfred J. Lotka, Proceedings of the National Academy of Sciences of the - United States of America, Volume 7, Issue 7, page 410-415, 1920 - -.. [Moolgavkar1987] Confidence Regions for Parameters of the Proportional - Hazards Model: A Simulation Study, S.H. Moolgavkar and D.J. Venzon, - Scandianvia Journal of Statistics, Volume 14, page 43-56, 1987 - -.. [Press2007] Numerical Recipes 3rd Edition: The Art of Scientific Computing, - W.H. Press et al., Cambridge University Press, 2007 - -.. [Ramsay2007] Parameter estimation for differential equations: a generalized - smoothing approach, Journal of the Royal Statistical Society Series B, - James O. Ramsay et al., Volume 69, Issue 5, page 741-796, 2007 - -.. [Raue2009] Structural and Practical Identifiability Analysis of Partially - Observed Dynamical Models by Exploiting the Profile Likelihood, - A. Raue et al., Bioinformatics, Volume 25, Issue 15, page 1923-1929, 2009 - -.. [Robertson1966] The solution of a set of reaction rate equations, - H.H. Robertson, Academic Press, page 178-182, 1966 - -.. [vanderpol1926] On Relaxed Oscillations, Balthasar van der Pol, The London, - Edinburgh, and Dublin Philosophical Magazine and Journal of Science, - Volume 2, Issue 11, page 978-992, 1926 - -.. [Venzon1988] A Method for Computing Profile-Likelihood-Based Confidence - Intervals, D.J. Venzon and S.H. Moolgavkar, Journal of the Royal Statistical - Society Series C (Applied Statistics), Volume 37, Issue 1, page 87-94, 1988 diff --git a/doc/doc_to_sort/stochastic.rst b/doc/doc_to_sort/stochastic.rst deleted file mode 100644 index 98f380b9..00000000 --- a/doc/doc_to_sort/stochastic.rst +++ /dev/null @@ -1,269 +0,0 @@ -.. _stochastic: - -******************************** -Stochastic representation of ode -******************************** - -There are multiple interpretation of stochasticity of a deterministic ode. We have implemented two of the most common interpretation; when the parameters are realizations of some underlying distribution, and when we have a so called chemical master equation where each transition represent a jump. Again, we use the standard SIR example as previously seen in ref:`sir`. - -.. ipython:: - - In [1]: from pygom import SimulateOde, Transition, TransitionType - - In [1]: import matplotlib.pyplot as plt - - In [1]: import numpy as np - - In [1]: x0 = [1, 1.27e-6, 0] - - In [1]: t = np.linspace(0, 150, 100) - - In [1]: stateList = ['S', 'I', 'R'] - - In [1]: paramList = ['beta', 'gamma'] - - In [1]: transitionList = [ - ...: Transition(origin='S', destination='I', equation='beta*S*I', transition_type=TransitionType.T), - ...: Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T) - ...: ] - - In [1]: odeS = SimulateOde(stateList, paramList, transition=transitionList) - - In [1]: odeS.parameters = [0.5, 1.0/3.0] - - In [1]: odeS.initial_values = (x0, t[0]) - - In [1]: solutionReference = odeS.integrate(t[1::], full_output=False) - - -Stochastic Parameter -==================== - -In our first scenario, we assume that the parameters follow some underlying distribution. Given that both :math:`\beta` and :math:`\gamma` in our SIR model has to be non-negative, it seemed natural to use a Gamma distribution. We make use of the familiar syntax from `R `_ to define our distribution. Unfortunately, we have to define it via a tuple, where the first is the function handle (name) while the second the parameters. Note that the parameters can be defined as either a dictionary or as the same sequence as `R `_, which is the shape then the rate in the Gamma case. - -.. ipython:: - - In [1]: from pygom.utilR import rgamma - - In [1]: d = dict() - - In [1]: d['beta'] = (rgamma,{'shape':100.0, 'rate':200.0}) - - In [1]: d['gamma'] = (rgamma,(100.0, 300.0)) - - In [1]: odeS.parameters = d - - In [1]: Ymean, Yall = odeS.simulate_param(t[1::], 10, full_output=True) - -Note that a message is printed above where it is trying to connect to an mpi backend, as our module has the capability to compute in parallel using the IPython. We have simulated a total of 10 different solutions using different parameters, the plots can be seen below - -.. ipython:: - - In [1]: f, axarr = plt.subplots(1,3) - - In [1]: for solution in Yall: - ...: axarr[0].plot(t, solution[:,0]) - ...: axarr[1].plot(t, solution[:,1]) - ...: axarr[2].plot(t, solution[:,2]) - - @savefig stochastic_param_all.png - In [1]: plt.show() - - In [1]: plt.close() - -We then see how the expected results, using the sample average of the simulations - -.. math:: - - \tilde{x}(T) = \mathbb{E}\left[ \int_{t_{0}}^{T} f(\theta,x,t) dt \right] - -differs from the reference solution - -.. math:: - - \hat{x}(T) = \int_{t_{0}}^{T} f(\mathbb{E}\left[ \theta \right],x,t) dt - -.. ipython:: - - In [1]: f, axarr = plt.subplots(1,3) - - In [1]: for i in range(3): axarr[i].plot(t, Ymean[:,i] - solutionReference[:,i]) - - @savefig stochastic_param_compare.png - In [1]: plt.show() - - In [1]: plt.close() - -The difference is relatively large especially for the :math:`S` state. We can decrease this difference as we increase the number of simulation, and more sophisticated sampling method for the generation of random variables can also decrease the difference. - -In addition to using the built-in functions to represent stochasticity, we can also use standard frozen distributions from scipy. Note that it must be a frozen distribution as that is the only for the parameters of the distributions to propagate through the model. - -.. ipython:: - - In [1]: import scipy.stats as st - - In [1]: d = dict() - - In [1]: d['beta'] = st.gamma(a=100.0, scale=1.0/200.0) - - In [1]: d['gamma'] = st.gamma(a=100.0, scale=1.0/300.0) - - In [1]: odeS.parameters = d - - -Obviously, there may be scenarios where only some of the parameters are stochastic. Let's say that the :math:`\gamma` parameter is fixed at :math:`1/3`, then simply replace the distribution information with a scalar. A quick visual inspection at the resulting plot suggests that the system of ODE potentially has less variation when compared to the case where both parameters are stochastic. - -.. ipython:: - - In [1]: d['gamma'] = 1.0/3.0 - - In [1]: odeS.parameters = d - - In [1]: YmeanSingle, YallSingle = odeS.simulate_param(t[1::], 5, full_output=True) - - In [1]: f, axarr = plt.subplots(1,3) - - In [1]: for solution in YallSingle: - ...: axarr[0].plot(t,solution[:,0]) - ...: axarr[1].plot(t,solution[:,1]) - ...: axarr[2].plot(t,solution[:,2]) - - @savefig stochastic_param_single.png - In [1]: plt.show() - - In [1]: plt.close() - -Continuous Markov Representation -================================ - -Another common method of introducing stochasticity into a set of ode is by assuming each movement in the system is a result of a jump process. More concretely, the probabilty of a move for transition :math:`j` is governed by an exponential distribution such that - -.. math:: - - \Pr(\text{process $j$ jump within time } \tau) = \lambda_{j} e^{-\lambda_{j} \tau}, - -where :math:`\lambda_{j}` is the rate of transition for process :math:`j` and :math:`\tau` the time elapsed after current time :math:`t`. - -A couple of the commmon implementation for the jump process have been implemented where two of them are used during a normal simulation; the first reaction method [Gillespie1977]_ and the :math:`\tau`-Leap method [Cao2006]_. The two changes interactively depending on the size of the states. - -.. ipython:: - - In [1]: x0 = [2362206.0, 3.0, 0.0] - - In [1]: stateList = ['S', 'I', 'R'] - - In [1]: paramList = ['beta', 'gamma', 'N'] - - In [1]: transitionList = [ - ...: Transition(origin='S', destination='I', equation='beta*S*I/N', transition_type=TransitionType.T), - ...: Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T) - ...: ] - - In [1]: odeS = SimulateOde(stateList, paramList, transition=transitionList) - - In [1]: odeS.parameters = [0.5, 1.0/3.0, x0[0]] - - In [1]: odeS.initial_values = (x0, t[0]) - - In [1]: solutionReference = odeS.integrate(t[1::]) - - In [1]: simX, simT = odeS.simulate_jump(t[1:10], 10, full_output=True) - - In [1]: f, axarr = plt.subplots(1, 3) - - In [1]: for solution in simX: - ...: axarr[0].plot(t[:9], solution[:,0]) - ...: axarr[1].plot(t[:9], solution[:,1]) - ...: axarr[2].plot(t[:9], solution[:,2]) - - @savefig stochastic_process.png - In [1]: plt.show() - - In [1]: plt.close() - -Above, we see ten different simulation, again using the SIR model but without standardization of the initial conditions. We restrict our time frame to be only the first 10 time points so that the individual changes can be seen more clearly above. If we use the same time frame as the one used previously for the deterministic system (as shown below), the trajectories are smoothed out and we no longer observe the *jumps*. Looking at the raw trajectories of the ODE below, it is obvious that the mean from a jump process is very different to the deterministic solution. The reason behind this is that the jump process above was able to fully remove all the initial infected individuals before any new ones. - -.. ipython:: - - In [1]: simX,simT = odeS.simulate_jump(t, 5, full_output=True) - - In [1]: simMean = np.mean(simX, axis=0) - - In [1]: f, axarr = plt.subplots(1,3) - - In [1]: for solution in simX: - ...: axarr[0].plot(t, solution[:,0]) - ...: axarr[1].plot(t, solution[:,1]) - ...: axarr[2].plot(t, solution[:,2]) - - @savefig stochastic_process_compare_large_n_curves.png - In [1]: plt.show() - - In [1]: plt.close() - - -Repeatable Simulation -===================== - -One of the possible use of compartmental models is to generate forecasts. Although most of the time the requirement would be to have (at least point-wise) convergence in the limit, reproducibility is also important. For both types of interpretation explained above, we have given the package the capability to repeat the simulations by setting a seed. When the assumption is that the parameters follows some sort of distribution, we simply set the seed which governs the global state of the random number generator. - -.. ipython:: - - In [1]: x0 = [2362206.0, 3.0, 0.0] - - In [1]: odeS = SimulateOde(stateList, paramList, transition=transitionList) - - In [1]: d = {'beta': st.gamma(a=100.0, scale=1.0/200.0), 'gamma': st.gamma(a=100.0, scale=1.0/300.0), 'N': x0[0]} - - In [1]: odeS.parameters = d - - In [1]: odeS.initial_values = (x0, t[0]) - - In [1]: Ymean, Yall = odeS.simulate_param(t[1::], 10, full_output=True) - - In [1]: np.random.seed(1) - - In [1]: Ymean1, Yall1 = odeS.simulate_param(t[1::], 10, full_output=True) - - In [1]: np.random.seed(1) - - In [1]: Ymean2, Yall2 = odeS.simulate_param(t[1::], 10, full_output=True) - - In [1]: sim_diff = [np.linalg.norm(Yall[i] - yi) for i, yi in enumerate(Yall1)] - - In [1]: sim_diff12 = [np.linalg.norm(Yall2[i] - yi) for i, yi in enumerate(Yall1)] - - In [1]: print("Different in the simulations and the mean: (%s, %s) " % (np.sum(sim_diff), np.sum(np.abs(Ymean1 - Ymean)))) - - In [1]: print("Different in the simulations and the mean using same seed: (%s, %s) " % (np.sum(sim_diff12), np.sum(np.abs(Ymean2 - Ymean1)))) - -In the alternative interpretation, setting the global seed is insufficient. Unlike simulation based on the parameters, where we can pre-generate all the parameter values and send them off to individual processes in the parallel backend, this is prohibitive here. In a nutshell, the seed does not propagate when using a parallel backend because each *integration* requires an unknown number of random samples. Therefore, we have an additional flag **parallel** in the function signature. By ensuring that the computation runs in serial, we can make use of the global seed and generate identical runs. - -.. ipython:: - - In [1]: x0 = [2362206.0, 3.0, 0.0] - - In [1]: odeS = SimulateOde(stateList, paramList, transition=transitionList) - - In [1]: odeS.parameters = [0.5, 1.0/3.0, x0[0]] - - In [1]: odeS.initial_values = (x0, t[0]) - - In [1]: simX, simT = odeS.simulate_jump(t[1:10], 10, parallel=False, full_output=True) - - In [1]: np.random.seed(1) - - In [1]: simX1, simT1 = odeS.simulate_jump(t[1:10], 10, parallel=False, full_output=True) - - In [1]: np.random.seed(1) - - In [1]: simX2, simT2 = odeS.simulate_jump(t[1:10], 10, parallel=False, full_output=True) - - In [1]: sim_diff = [np.linalg.norm(simX[i] - x1) for i, x1 in enumerate(simX1)] - - In [1]: sim_diff12 = [np.linalg.norm(simX2[i] - x1) for i, x1 in enumerate(simX1)] - - In [1]: print("Difference in simulation: %s" % np.sum(np.abs(sim_diff))) - - In [1]: print("Difference in simulation using same seed: %s" % np.sum(np.abs(sim_diff12))) - diff --git a/doc/doc_to_sort/transition.rst b/doc/doc_to_sort/transition.rst deleted file mode 100644 index a36959db..00000000 --- a/doc/doc_to_sort/transition.rst +++ /dev/null @@ -1,183 +0,0 @@ -.. _transition: - -***************** -Transition Object -***************** - -The most important part of setting up the model is to correctly define the set odes, which is based solely on the classes defined in :mod:`transition`. All transitions that gets fed into the ode system needs to be defined as a transition object, :class:`Transition`. It takes a total of four input arguments - -#. The origin state -#. Equation that describe the process -#. The type of transition -#. The destination state - -where the first three are mandatory. To demonstrate, we go back to the SIR model defined previously in the section :ref:`sir`. Recall that the set of odes are - -.. math:: - - \frac{\partial S}{\partial t} &= -\beta SI \\ - \frac{\partial I}{\partial t} &= \beta SI - \gamma I \\ - \frac{\partial R}{\partial t} &= \gamma I. - -We can simply define the set of ode, as seen previously, via - -.. ipython:: - - In [1]: from pygom import Transition, TransitionType, common_models - - In [2]: ode1 = Transition(origin='S', equation='-beta*S*I', transition_type=TransitionType.ODE) - - In [3]: ode2 = Transition(origin='I', equation='beta*S*I - gamma*I', transition_type=TransitionType.ODE) - - In [4]: ode3 = Transition(origin='R', equation='gamma*I', transition_type=TransitionType.ODE) - -Note that we need to state explicitly the type of equation we are inputting, which is simply of type **ODE** in this case. We can confirm this has been entered correctly by putting it into :class:`DeterministicOde` - -.. ipython:: - - In [1]: from pygom import DeterministicOde - - In [2]: stateList = ['S', 'I', 'R'] - - In [3]: paramList = ['beta', 'gamma'] - - In [4]: model = DeterministicOde(stateList, - ...: paramList, - ...: ode=[ode1, ode2, ode3]) - -and check it - -.. ipython:: - - In [1]: model.get_ode_eqn() - -An alternative print function :func:`print_ode` is also available which may be more suitable in other situation. The default prints the formula in a rendered format and another which prints out the latex format which can be used directly in a latex document. The latter is useful as it saves typing out the formula twice, once in the code and another in documents. - -.. ipython:: - - In [1]: model.print_ode(False) - - In [2]: model.print_ode(True) - -Now we are going to show the different ways of defining the same set of odes. - -.. _defining-eqn: - -Defining the equations -====================== - -Recognizing that the set of odes defining the SIR model is the result of two transitions, - -.. math:: - - S \rightarrow I &= \beta SI \\ - I \rightarrow R &= \gamma I - -where :math:`S \rightarrow I` denotes a transition from state :math:`S` to state :math:`I`. Therefore, we can simply define our model by these two transition, but now these two transition needs to be inputted via the ``transition`` argument instead of the ``ode`` argument. Note that we are initializing the model using a different class, because the stochastic implementation has more operation on transitions. - -.. ipython:: - - In [600]: from pygom import SimulateOde - - In [601]: t1 = Transition(origin='S', destination='I', equation='beta*S*I', transition_type=TransitionType.T) - - In [602]: t2 = Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T) - - In [603]: modelTrans = SimulateOde(stateList, - .....: paramList, - .....: transition=[t1, t2]) - - In [604]: modelTrans.get_ode_eqn() - -We can see that the resulting ode is exactly the same, as expected. The transition matrix that defines this process can easily be visualized using graphviz. Because only certain renderer permit the use of sub and superscript, operators such as :math:`**` are left as they are in the equation. - -.. ipython:: - - In [1]: import matplotlib.pyplot as plt - - In [2]: f = plt.figure() - - In [3]: modelTrans.get_transition_matrix() - - @savefig sir_transition_graph.png - In [4]: dot = modelTrans.get_transition_graph() - -If we put in via the wrong argument like below (not run), then an error will appear. - -.. ipython:: - - In [1]: # modelTrans = DeterministicOde(stateList, paramList, ode=[t1, t2]) - -because :class:`TranstionType` was defined explicitly as a transition instead of an ode. The same can be observed when the wrong :class:`TransitionType` is used for any of the input argument. - -This though, only encourages us to define the transitions carefully. We can also pretend that the set of odes are in fact just a set of birth process - -.. ipython:: - - In [619]: birth1 = Transition(origin='S', equation='-beta*S*I', transition_type=TransitionType.B) - - In [620]: birth2 = Transition(origin='I', equation='beta*S*I - gamma*I', transition_type=TransitionType.B) - - In [621]: birth3 = Transition(origin='R', equation='gamma*I', transition_type=TransitionType.B) - - In [622]: modelBirth = DeterministicOde(stateList, - .....: paramList, - .....: birth_death=[birth1, birth2, birth3]) - - In [623]: modelBirth.get_ode_eqn() - -which will yield the same set result. Alternatively, we can use the negative of the equation but set it to be a death process. For example, we multiply the equations for state :math:`S` and :math:`R` with a negative sign and set the transition type to be a death process instead. - -.. ipython:: - - In [624]: death1 = Transition(origin='S', equation='beta*S*I', transition_type=TransitionType.D) - - In [625]: birth2 = Transition(origin='I', equation='beta*S*I - gamma*I', transition_type=TransitionType.B) - - In [626]: death3 = Transition(origin='R', equation='-gamma*I', transition_type=TransitionType.D) - - In [627]: modelBD = DeterministicOde(stateList, - .....: paramList, - .....: birth_death=[death1, birth2, death3]) - - In [628]: modelBD.get_ode_eqn() - - -We can see that all the above ways yield the same set of ode at the end. - -Model Addition -============== - -Because we allow the separation of transitions between states and birth/death processes, the birth/death processes can be added later on. - -.. ipython:: - - In [1]: modelBD2 = modelTrans - - In [1]: modelBD2.param_list = paramList + ['mu', 'B'] - - In [1]: birthDeathList = [Transition(origin='S', equation='B', transition_type=TransitionType.B), - ...: Transition(origin='S', equation='mu*S', transition_type=TransitionType.D), - ...: Transition(origin='I', equation='mu*I', transition_type=TransitionType.D)] - - In [1]: modelBD2.birth_death_list = birthDeathList - - In [1]: modelBD2.get_ode_eqn() - -So modeling can be done in stages. Start with a standard closed system and extend it with additional flows that interact with the environment. - -.. _transition-type: - -Transition type -=============== - -There are currently four different type of transitions allowed, which is defined in an enum class also located in :mod:`transition`. The four types are B, D, ODE and T, where they represent different type of process with explanation in their corresponding value. - -.. ipython:: - - In [1]: from pygom import transition - - In [2]: for i in transition.TransitionType: - ...: print(str(i) + " = " + i.value) - -Each birth process are added to the origin state while each death process are deducted from the state, i.e. added to the state after multiplying with a negative sign. An ode type is also added to the state and we forbid the number of input ode to be greater than the number of state inputted. diff --git a/doc/doc_to_sort/unroll/unrollBD.rst b/doc/doc_to_sort/unroll/unrollBD.rst deleted file mode 100644 index b8be3a88..00000000 --- a/doc/doc_to_sort/unroll/unrollBD.rst +++ /dev/null @@ -1,66 +0,0 @@ -.. _unrollBD: - -ODE With Birth and Death Process -================================ - -We follow on from the SIR model of :ref:`unrollSimple` but with additional birth and death processes. - -.. math:: - - \frac{dS}{dt} &= -\beta SI + B - \mu S\\ - \frac{dI}{dt} &= \beta SI - \gamma I - \mu I\\ - \frac{dR}{dt} &= \gamma I. - -which consists of two transitions and three birth and death process - -.. graphviz:: - - digraph SIR_Model { - rankdir=LR; - size="8" - node [shape = circle]; - S -> I [ label = "βSI" ]; - I -> R [ label = "γI" ]; - B [height=0 margin=0 shape=plaintext width=0]; - B -> S; - "S**2*μ" [height=0 margin=0 shape=plaintext width=0]; - S -> "S**2*μ"; - "I*μ" [height=0 margin=0 shape=plaintext width=0]; - I -> "I*μ"; - } - -Let's define this in terms of ODEs, and unroll it back to the individual processes. - -.. ipython:: - - In [1]: from pygom import Transition, TransitionType, SimulateOde, common_models - - In [1]: import matplotlib.pyplot as plt - - In [1]: stateList = ['S', 'I', 'R'] - - In [1]: paramList = ['beta', 'gamma', 'B', 'mu'] - - In [1]: odeList = [ - ...: Transition(origin='S', - ...: equation='-beta*S*I + B - mu*S', - ...: transition_type=TransitionType.ODE), - ...: Transition(origin='I', - ...: equation='beta*S*I - gamma*I - mu*I', - ...: transition_type=TransitionType.ODE), - ...: Transition(origin='R', - ...: equation='gamma*I', - ...: transition_type=TransitionType.ODE) - ...: ] - - In [1]: ode = SimulateOde(stateList, paramList, ode=odeList) - - In [1]: ode2 = ode.get_unrolled_obj() - - In [1]: f = plt.figure() - - @savefig sir_unrolled_transition_graph.png - In [1]: ode2.get_transition_graph() - - In [1]: plt.close() - diff --git a/doc/doc_to_sort/unroll/unrollHard.rst b/doc/doc_to_sort/unroll/unrollHard.rst deleted file mode 100644 index 2361cf4d..00000000 --- a/doc/doc_to_sort/unroll/unrollHard.rst +++ /dev/null @@ -1,73 +0,0 @@ -.. _unrollHard: - -Hard Problem -============ - -Now we turn to a harder problem that does not have a one to one mapping between all the transitions and the terms in the ODEs. We use the model in :func:`Influenza_SLIARN`, defined by - -.. math:: - \frac{dS}{dt} &= -S \beta (I + \delta A) \\ - \frac{dL}{dt} &= S \beta (I + \delta A) - \kappa L \\ - \frac{dI}{dt} &= p \kappa L - \alpha I \\ - \frac{dA}{dt} &= (1 - p) \kappa L - \eta A \\ - \frac{dR}{dt} &= f \alpha I + \eta A \\ - \frac{dN}{dt} &= -(1 - f) \alpha I. - -The outflow of state **L**, :math:`\kappa L`, is composed of two transitions, one to **I** and the other to **A** but the ode of **L** only reflects the total flow going out of the state. Same can be said for state **I**, where the flow :math:`\alpha I` goes to both **R** and **N**. Graphically, it is a rather simple process as shown below. - -.. graphviz:: - - digraph SLIARD_Model { - labelloc = "t"; - label = "Original transitions"; - rankdir=LR; - size="8" - node [shape = circle]; - S -> L [ label = "-Sβ(I + δA)/N" ]; - L -> I [ label = "κLp" ]; - L -> A [ label = "κL(1-p)" ]; - I -> R [ label = "αIf" ]; - I -> D [ label = "αI(1-f)" ]; - A -> R [ label = "ηA" ]; - } - -We slightly change the model by introducing a new state **D** to convert it into a closed system. The combination of state **D** and **N** is a constant, the total population. So we can remove **N** and this new system consist of six transitions. We define them explicitly as ODEs and unroll them into transitions. - -.. ipython:: - - In [1]: from pygom import SimulateOde, Transition, TransitionType - - In [1]: stateList = ['S', 'L', 'I', 'A', 'R', 'D'] - - In [2]: paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'epsilon', 'N'] - - In [3]: odeList = [ - ...: Transition(origin='S', equation='- beta*S/N*(I + delta*A)', transition_type=TransitionType.ODE), - ...: Transition(origin='L', equation='beta*S/N*(I + delta*A) - kappa*L', transition_type=TransitionType.ODE), - ...: Transition(origin='I', equation='p*kappa*L - alpha*I', transition_type=TransitionType.ODE), - ...: Transition(origin='A', equation='(1 - p)*kappa * L - epsilon*A', transition_type=TransitionType.ODE), - ...: Transition(origin='R', equation='f*alpha*I + epsilon*A', transition_type=TransitionType.ODE), - ...: Transition(origin='D', equation='(1 - f)*alpha*I', transition_type=TransitionType.ODE) ] - - In [4]: ode = SimulateOde(stateList, paramList, ode=odeList) - - In [5]: ode.get_transition_matrix() - - In [6]: ode2 = ode.get_unrolled_obj() - - In [7]: ode2.get_transition_matrix() - - In [8]: ode2.get_ode_eqn() - -After unrolling the odes, we have the following transition graph - -.. ipython:: - - @savefig sir_unrolled_transition_graph_hard.png - In [1]: ode2.get_transition_graph() - - In [2]: plt.close() - - In [3]: print(sum(ode.get_ode_eqn() - ode2.get_ode_eqn()).simplify()) # difference - -which is exactly the same apart from slightly weird arrangement of symbols in some of the equations. The last line with a value of zero also reaffirms the result. diff --git a/doc/doc_to_sort/unroll/unrollSimple.rst b/doc/doc_to_sort/unroll/unrollSimple.rst deleted file mode 100644 index 21d3948a..00000000 --- a/doc/doc_to_sort/unroll/unrollSimple.rst +++ /dev/null @@ -1,54 +0,0 @@ -.. _unrollSimple: - -Simple Problem -============== - -For a simple problem, we consider the SIR model defined by - -.. math:: - - \frac{dS}{dt} &= -\beta SI \\ - \frac{dI}{dt} &= \beta SI - \gamma I \\ - \frac{dR}{dt} &= \gamma I. - -which consists of two transitions - -.. graphviz:: - - digraph SIR_Model { - rankdir=LR; - size="8" - node [shape = circle]; - S -> I [ label = "βSI" ]; - I -> R [ label = "γI" ]; - } - -Let's define this using the code block below - -.. ipython:: - - In [1]: from pygom import SimulateOde, Transition, TransitionType - - In [2]: ode1 = Transition(origin='S', equation='-beta*S*I', transition_type=TransitionType.ODE) - - In [3]: ode2 = Transition(origin='I', equation='beta*S*I - gamma*I', transition_type=TransitionType.ODE) - - In [4]: ode3 = Transition(origin='R', equation='gamma*I', transition_type=TransitionType.ODE) - - In [6]: stateList = ['S', 'I', 'R'] - - In [7]: paramList = ['beta', 'gamma'] - - In [8]: ode = SimulateOde(stateList, - ...: paramList, - ...: ode=[ode1, ode2, ode3]) - - In [9]: ode.get_transition_matrix() - -and the last line shows that the transition matrix is empty. This is the expected result because :class:`SimulateOdeModel` was not initialized using transitions. We populate the transition matrix below and demonstrate the difference. - -.. ipython:: - - In [1]: ode = ode.get_unrolled_obj() - - In [2]: ode.get_transition_matrix() diff --git a/doc/doc_to_sort/unrollOde.rst b/doc/doc_to_sort/unrollOde.rst deleted file mode 100644 index 09b44cef..00000000 --- a/doc/doc_to_sort/unrollOde.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. _unrollOde: - -**************************** -Convert ODE into transitions -**************************** - -As seen previously in :ref:`transition`, we can define the model via the transitions or explicitly as ODEs. There are times when we all just want to test out some model in a paper and the only available information are the ODEs themselves. Even though we know that the ODEs come from some underlying transitions, breaking them down can be a time consuming process. We provide the functionalities to do this automatically. - -.. toctree:: - - unroll/unrollSimple.rst - unroll/unrollBD.rst - unroll/unrollHard.rst diff --git a/doc/make.bat b/doc/make.bat deleted file mode 100644 index 597a35c2..00000000 --- a/doc/make.bat +++ /dev/null @@ -1,113 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation -set SPHINXBUILD=sphinx-build -set BUILDDIR=_build -set SPHINXOPTS= -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pyGenericOdeModelDoc.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pyGenericOdeModelDoc.ghc - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -:end diff --git a/doc/requirements.txt b/doc/requirements.txt deleted file mode 100644 index d6e1e29a..00000000 --- a/doc/requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -dask[complete]>=0.13.0 -graphviz>=0.4.9 -matplotlib>=1.0.0 -numpy>=1.6.0 -pandas>=0.15.0 -python-dateutil>=2.0.0 -scipy>=0.10.0 -sympy>=1.0.0 -numpydoc>=0.6.0 -#sphinx>=1.4.1 -#sphinx_rtd_theme>=0.2.0 -#ipython>=7.1.1 -jupyter-book diff --git a/doc/source/_static/.gitignore b/doc/source/_static/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100644 index dc804650..00000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,264 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is execfile() with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os -import warnings - -#slight hack for graphvis on windows to ensure conda path is correct -#if sys.platform == 'win32': -# os.environ['PATH'] += os.pathsep + os.environ['CONDA_PREFIX'] + r'\Library\bin\graphviz' - -import sphinx -if sphinx.__version__ < '1.4.1': - raise RuntimeError("Sphinx 1.4.1 or newer required") - -import pygom - -needs_sphinx = '1.4.1' - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.append(os.path.abspath('.')) -sys.path.append(os.path.abspath('sphinxext')) -#sys.path.append(os.path.abspath('../pygom')) - -# -- General configuration ----------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - 'sphinx.ext.mathjax', # 'sphinx.ext.imgmath', - 'sphinx.ext.autodoc', - 'sphinx.ext.autosummary', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - 'sphinx.ext.graphviz',# 'matplotlib.sphinxext.only_directives', - 'matplotlib.sphinxext.plot_directive', - 'numpydoc', - 'IPython.sphinxext.ipython_console_highlighting', - 'IPython.sphinxext.ipython_directive', - 'nbsphinx' - ] - -# the mapping for code in other packages -intersphinx_mapping = {'matplotlib': ('http://matplotlib.org/', None), - 'numpy': ('https://docs.scipy.org/doc/numpy/', None), - 'python': ('https://docs.python.org/2', None), - 'scipy': ('https://docs.scipy.org/doc/scipy/reference/', None), - 'sympy': ('http://docs.sympy.org/latest/', None)} - -numpydoc_show_class_members = False - - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'PyGOM Documentation' -copyright = '2015-2019, Public Health England' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = pygom.__version__ -# The full version, including alpha/beta/rc tags. -release = pygom.__version__ - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of documents that shouldn't be included in the build. -#unused_docs = [] - -# List of directories, relative to source directory, that shouldn't be searched -# for source files. -exclude_trees = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -#Set the directory to save figures in -ipython_savefig_dir = 'savefig' -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -#['alabaster',sphinx_rtd_theme','classic','sphinxdoc','scrolls','agogo', -# 'traditional','nature','haiku','pyramid','bizstyle'] -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' -if not on_rtd: # only import and set the theme if we're building docs locally - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] - exclude_patterns = ['doc_to_sort.*'] -else: - # RTD will time out if we try to build the whole of the documentation so - # ignore some of the longer bits and perhaps add them later - # // TODO: speed up runtime for longer examples for readthedocs - exclude_patterns = ['common_models/*.rst', -# 'bvpSimple.rst', - 'epi.rst', -# 'estimate1.rst', - 'estimate2.rst', - 'gradient.rst', - 'epijson.rst', - 'fh.rst', -# 'getting_started.rst', - 'initialGuess.rst', - 'profile.rst', - 'sir.rst', -# 'stochastic.rst', -# 'transition.rst' - ] - -# html_theme = 'sphinx_rtd_theme' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_use_modindex = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'PyGOM Documentation' - -html_add_permalinks = '' - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'PyGOM.tex', 'PyGOM Documentation', - 'Edwin Tye', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# Additional stuff for the LaTeX preamble. -latex_preamble = '\\usepackage{amsmath,amssymb}' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_use_modindex = True - -# latex_encodings = 'utf-8' -warnings.filterwarnings("ignore", category=UserWarning, - message='Matplotlib is currently using agg, which is a' - ' non-GUI backend, so cannot show the figure.') diff --git a/doc/source/getting_started.rst b/doc/source/getting_started.rst deleted file mode 100644 index cf58249b..00000000 --- a/doc/source/getting_started.rst +++ /dev/null @@ -1,87 +0,0 @@ -.. _getting_started: - -*************** -Getting started -*************** - -.. _package-purpose: - -What this package does -====================== - -The purpose of this package is to allow the end user to easily define a set of -ordinary differential equations (ODE) and obtain information about the ODE by -invoking the the appropriate methods. Here, we define the set of ODE's -as - -.. math:: - \frac{\partial \mathbf{x}}{\partial t} = f(\mathbf{x},\boldsymbol{\theta}) - -where :math:`\mathbf{x} = \left(x_{1},x_{2},\ldots,x_{n}\right)` is the state -vector with :math:`d` state and :math:`\boldsymbol{\theta}` the parameters of -:math:`p` dimension. Currently, this package allows the user to find the -algebraic expression of the ODE, Jacobian, gradient and forward sensitivity of -the ODE. A numerical output is given when all the state and parameter values -are provided. Note that the only important class is :file:`DeterministicOde` -where all the functionality described previously are exposed. - -The current plan is to extend the functionality to include - -* Solving the ode analytically when it is linear - -* Analysis of the system via eigenvalues during the integration - -* Detection of DAE - - -.. _installing-docdir: - -Obtaining the package -===================== - -The location of the package is current on GitHub and can be pulled via https -from:: - - https://github.com/PublicHealthEngland/pygom.git - -The package is currently as follows:: - - pygom/ - bin/ - doc/ - pygom/ - loss/ - tests/ - model/ - tests/ - sbml_translate/ - utilR/ - LICENSE.txt - README.rst - requirements.txt - setup.py - -with files in each of the three main folders not shown. You can install the -package via command line:: - - python setup.py install - -or locally on a user level:: - - python setup.py install --user - -Please note that there are current redundant file are kept for development -purposes for the time being. - -.. _testing-the-package: - -Testing the package -=================== - -Testing can be performed prior or after the installation. Some standard test -files can be found in their respective folder and they can be run in the command -line:: - - python setup.py test - -which can be performed prior to installing the package if desired. diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index e4625e13..00000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,63 +0,0 @@ -##################################### -Welcome to the documentation of pygom -##################################### - -PyGOM (Python Generic ODE Model) is a Python package that aims to facilitate the application of ordinary differential equations (ODEs) in the real world, -with a focus in epidemiology. -This package helps the user define their ODE system in an intuitive manner and provides convenience functions - -making use of various algebraic and numerical libraries in the backend - that can be used in a straight forward fashion. - -This is an open source project hosted on `Github `_. - -A manuscript containing a shortened motivation and use is hosted on `arxXiv `_. - -# // TODO Insert intro text - -################## -User Documentation -################## - -.. toctree:: - :maxdepth: 5 - - getting_started.rst - #sir.rst - #notebooks/sir.ipynb - #transition.rst - #stochastic.rst - #unrollOde.rst - #epi.rst - #epijson.rst - #bvpSimple.rst - #gradient.rst - #fh.rst - #estimate1.rst - #estimate2.rst - #initialGuess.rst - #profile.rst - #common_models.rst - -########################## -Code Documentation and FAQ -########################## - -.. toctree:: - :maxdepth: 5 - - #faq.rst - #mod/index.rst - -########## -References -########## - -.. toctree:: - - #ref.rst - -################## -Indices and tables -################## - -* :ref:`genindex` -* :ref:`modindex` diff --git a/doc/source/sir.rst b/doc/source/sir.rst deleted file mode 100644 index 86ed2b22..00000000 --- a/doc/source/sir.rst +++ /dev/null @@ -1,281 +0,0 @@ -.. _sir: - -***************************** -Motivating Example: SIR Model -***************************** - -Defining the model -================== - -First, we are going to go through an SIR model to show the functionality of the package. The SIR model is defined by the following equations - -.. math:: - - \frac{dS}{dt} &= -\beta SI \\ - \frac{dI}{dt} &= \beta SI- \gamma I \\ - \frac{dR}{dt} &= \gamma I. - -We can set this up as follows - -.. ipython:: - - In [32]: # first we import the classes require to define the transitions - - In [33]: from pygom import Transition, TransitionType - - In [34]: # define our state - - In [35]: stateList = ['S', 'I', 'R'] - - In [36]: # and the set of parameters, which only has two - - In [37]: paramList = ['beta', 'gamma'] - - In [38]: # then the set of ode - - In [38]: odeList = [ - ....: Transition(origin='S', equation='-beta*S*I', transition_type=TransitionType.ODE), - ....: Transition(origin='I', equation='beta*S*I - gamma*I', transition_type=TransitionType.ODE), - ....: Transition(origin='R', equation='gamma*I', transition_type=TransitionType.ODE) - ....: ] - -Here, we have invoke a class from :mod:`Transition` to define the transition object. We proceed here and ignore the details for now. The details of defining a transition object will be covered later in :ref:`transition`. Both the set of states and parameters should be defined when constructing the object, even though not explicitly enforced, to help clarify what we are trying to model. Similarly, this holds for the rest, such as the derived parameters and transitions, where we force the end user to input the different type of transition/process via the corret argument. See :ref:`defining-eqn` for an example when the input is wrong. - -.. ipython:: - - In [39]: # now we import the ode module - - In [40]: from pygom import DeterministicOde - - In [41]: # initialize the model - - In [42]: model = DeterministicOde(stateList, - ....: paramList, - ....: ode=odeList) - -That is all the information required to define a simple SIR model. We can verify the equations by - -.. ipython:: - - In [40]: model.get_ode_eqn() - -where we can see the equations corresponding to their respective :math:`S,I` and :math:`R` state. The set of ode is in the standard :math:`S,I,R` sequence because of how the states are defined initially. We can change them around - -.. ipython:: - - In [59]: # now we are going to define in a different order. note that the output ode changed with the input state - - In [60]: stateList = ['R', 'S', 'I'] - - In [61]: model = DeterministicOde(stateList, - ....: paramList, - ....: ode=odeList) - - In [62]: model.get_ode_eqn() - -and find that the set of ode's still comes out in the correct order with respect to how the states are ordered. In addition to showing the ode in English, we can also display it as either symbols or latex code which save some extra typing when porting the equations to a proper document. - -.. ipython:: - - In [1]: model.print_ode() - - In [2]: model.print_ode(True) - -The SIR model above was defined as a set of explicit ODEs. An alternative way is to define the model using a series of transitions between the states. We have provided the capability to obtain a *best guess* transition matrix when only the ODEs are available. See the section :ref:`unrollOde` for more information, and in particular :ref:`unrollSimple` for the continuing demonstration of the SIR model. - - -Model information -================= - -The most obvious thing information we wish to know about an ode is whether it is linear - -.. ipython:: - - In [65]: model.linear_ode() - -which we know is not for an SIR. So we may want to have a look at the Jacobian say, it is as simple as - -.. ipython:: - - In [64]: model.get_jacobian_eqn() - -or maybe we want to know the gradient (of the ode) - -.. ipython:: - - In [65]: model.get_grad_eqn() - -Invoking the functions that computes :math:`f(x)` (or the derivatives) like below will output an error (not run) - -.. ipython:: - - In [66]: # model.ode() - - In [67]: # model.jacobian() - -This is because the some of the functions are used to solve the ode numerically and expect input values of both state and time. But just invoking the two methods above without defining the parameter value, such as the second line below, will also throws an error. - -.. ipython:: - - In [77]: initialState = [0, 1, 1.27e-6] - - In [78]: # model.ode(state=initialState, t=1) - -It is important to note at this point that the numeric values of the states need to be set in the correct order against the list of states, which can be found by - -.. ipython:: - - In [79]: model.state_list - -There is currently no mechanism to set the numeric values of the states along with the state. This is because of implementation issue with external package, such as solving an initial value problem. - -Initial value problem -===================== - -Setting the parameters will allow us to evaluate - -.. ipython:: - - In [80]: # define the parameters - - In [81]: paramEval = [ - ....: ('beta',0.5), - ....: ('gamma',1.0/3.0) - ....: ] - - In [82]: model.parameters = paramEval - - In [83]: model.ode(initialState, 1) - -Now we are well equipped with solving an initial value problem, using standard numerical integrator such as :func:`odeint ` from :mod:`scipy.integrate`. We also used :mod:`matplotlib.pyplot` for plotting and :func:`linspace ` to create the time vector. - -.. ipython:: - - In [96]: import scipy.integrate - - In [97]: import numpy - - In [98]: t = numpy.linspace(0, 150, 100) - - In [99]: solution = scipy.integrate.odeint(model.ode, initialState, t) - - In [100]: import matplotlib.pyplot as plt - - In [101]: plt.figure(); - - In [102]: plt.plot(t, solution[:,0], label='R'); - - In [103]: plt.plot(t, solution[:,1], label='S'); - - In [104]: plt.plot(t, solution[:,2], label='I'); - - In [105]: plt.xlabel('Time'); - - In [106]: plt.ylabel('Population proportion'); - - In [107]: plt.title('Standard SIR model'); - - In [108]: plt.legend(loc=0); - - @savefig sir_plot.png - In [109]: plt.show(); - - In [110]: plt.close() - -Where a nice standard SIR progression can be observed in the figure above. Alternatively, we can also integrate and plot via the **ode** object which we have initialized. - -.. ipython:: - - In [1]: model.initial_values = (initialState, t[0]) - - In [2]: model.parameters = paramEval - - In [3]: solution = model.integrate(t[1::]) - - In [4]: model.plot() - -The plot is not shown as it is identical to the one above without the axis labels. Obviously, we can solve the ode above using the Jacobian as well. Unfortunately, it does not help because the number of times the Jacobian was evaluated was zero, as expected given that our set of equations are not stiff. - -.. ipython:: - - In [583]: %timeit solution1, output1 = scipy.integrate.odeint(model.ode, initialState, t, full_output=True) - - In [584]: %timeit solution2, output2 = scipy.integrate.odeint(model.ode, initialState, t, Dfun=model.jacobian, mu=None, ml=None, full_output=True) - - In [584]: %timeit solution3, output3 = model.integrate(t, full_output=True) - -It is important to note that we return our Jacobian as a dense square matrix. Hence, the two argument (mu,ml) for the ode solver was set to ``None`` to let it know the output explicitly. - -Solving the forward sensitivity equation -======================================== - -Likewise, the sensitivity equations are also solved as an initial value problem. Let us redefine the model in the standard SIR order and we solve it with the sensitivity all set at zero, i.e. we do not wish to infer the initial value of the states - -.. ipython:: - - In [452]: stateList = ['S', 'I', 'R'] - - In [453]: model = DeterministicOde(stateList, - .....: paramList, - .....: ode=odeList) - - In [454]: initialState = [1, 1.27e-6, 0] - - In [455]: paramEval = [ - .....: ('beta', 0.5), - .....: ('gamma', 1.0/3.0) - .....: ] - - In [456]: model.parameters = paramEval - - In [457]: solution = scipy.integrate.odeint(model.ode_and_sensitivity, numpy.append(initialState, numpy.zeros(6)), t) - - In [458]: f,axarr = plt.subplots(3,3); - - In [459]: # f.text(0.5,0.975,'SIR with forward sensitivity solved via ode',fontsize=16,horizontalalignment='center',verticalalignment='top'); - - In [460]: axarr[0,0].plot(t, solution[:,0]); - - In [461]: axarr[0,0].set_title('S'); - - In [462]: axarr[0,1].plot(t, solution[:,1]); - - In [463]: axarr[0,1].set_title('I'); - - In [464]: axarr[0,2].plot(t, solution[:,2]); - - In [465]: axarr[0,2].set_title('R'); - - In [466]: axarr[1,0].plot(t, solution[:,3]); - - In [467]: axarr[1,0].set_title(r'state S parameter $\beta$'); - - In [468]: axarr[2,0].plot(t, solution[:,4]); - - In [469]: axarr[2,0].set_title(r'state S parameter $\gamma$'); - - In [470]: axarr[1,1].plot(t, solution[:,5]); - - In [471]: axarr[1,1].set_title(r'state I parameter $\beta$'); - - In [472]: axarr[2,1].plot(t, solution[:,6]); - - In [473]: axarr[2,1].set_title(r'state I parameter $\gamma$'); - - In [474]: axarr[1,2].plot(t, solution[:,7]); - - In [475]: axarr[1,2].set_title(r'state R parameter $\beta$'); - - In [476]: axarr[2,2].plot(t, solution[:,8]); - - In [477]: axarr[2,2].set_title(r'state R parameter $\gamma$'); - - In [478]: plt.tight_layout(); - - @savefig sir_sensitivity_plot.png - In [480]: plt.show(); - - In [481]: plt.close() - -This concludes the introductory example and we will be moving on to look at parameter estimation next in :ref:`estimate1` and the most important part in terms of setting up the ode object; defining the equations in various different ways in :ref:`transition`. - From 35d4e4e3394287d5972c7617b8bc54adbdc6f9fa Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 4 Jun 2024 16:52:45 +0100 Subject: [PATCH 016/123] Update readme --- README.rst | 90 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/README.rst b/README.rst index b78b4bd3..be277cd7 100644 --- a/README.rst +++ b/README.rst @@ -1,6 +1,6 @@ -=============================== -pygom - ODE modelling in Python -=============================== +================================ +PyGOM - Python Generic ODE Model +================================ |Build status| |Github actions| |Documentation Status| |pypi version| |licence| |Jupyter Book Badge| @@ -15,53 +15,81 @@ pygom - ODE modelling in Python .. |Jupyter Book Badge| image:: https://jupyterbook.org/badge.svg :target: https://hwilliams-phe.github.io/pygom/intro.html -A generic framework for ode models, specifically compartmental type problems. +A generic framework for Ordinary Differential Equation (ODE) models, especially compartmental type systems. +This package provides a simple interface for users to construct ODE models. +This is backed by a comprehensive and easy to use tool–box which implements functions to easily perform +common operations for ODE systems such as parameter estimation and solving for deterministic or stochastic time evolution. +With both the algebraic and numeric calculations performed automatically (but still accessible), +the end user is freed to focus on model development. -This package depends on:: +Installation +============ + +You can download a local copy of the PyGOM source files from this GitHub repository:: + +$ git clone https://github.com/ukhsa-collaboration/pygom.git + +Please be aware that there may be redundant files within the package as it is under active development. + +.. note:: + The latest fully reviewed version of PyGOM will be on the master branch and + we generally recommend that users install the version from there. However, + the current version being prepared for release (featuring up-to-date documentation) + is hosted on the feature/prep_doc branch. + +Activate the relevant branch for installation via Git Bash, if you have been recruited to test code for the +new release then this is the feature/prep_doc branch:: + +$ git activate feature/prep_doc - dask - matplotlib - enum34 - pandas - python-dateutil - numpy - scipy - sympy +Package dependencies can be found in the file, requirements.txt. +An easy way to install these to create a new `conda `_ environment via:: -and they should be installed if not already available. Alternatively, the easier way -to use a minimal (and isolated) setup is to use `conda `_ and -create a new environment via:: +$ conda env create -f conda-env.yml - conda env create -f conda-env.yml +which you should ensure is active for the installation process using -Installation of this package can be performed via:: +$ conda activate pygom + +Alternatively, you may add dependencies to your own environment:: + +$ pip install -r requirements.txt + +If you are working on a Windows machine you will also need to install:: + * `Graphviz `_ + * `Visual C++ `_ + * `Visual C++ Build Tools ` + +You should be able to install the PyGOM package via command line:: $ python setup.py install -and tested via:: +and test that installation has completed successfully $ python setup.py test -A reduced form of the documentation may be found on ReadTheDocs_. +This will run a few test cases and can take some minutes to complete. -.. _ReadTheDocs: https://pygom.readthedocs.io/en/master/ +Documentation +============= -You may get the full documentation, including the lengthy examples by locally -building the documentation found in the folder:: +Documentation must be built locally and all necessary files can be found in the docs folder. +Documentation is built from the command line:: -$ doc +$ jupyter-book build docs -Note that building the documentation can be extremely slow depending on the -setup of the system. Further details can be found at it's own read me:: +The html files will be saved in the local copy of your repository under: -$ doc/README.rst +$ pygom/docs/_build/html + +.. note:: + Building the documentation involves running many examples in python + which can take up to tens of minutes. Subsequent builds with these + examples unchanged are much quicker due to caching of the code outputs. Please be aware that if the module tests fails, then the documentation for the package will not compile. -Please be aware that there may be redundant files within the package as it is -under active development. - Contributors ============ Thomas Finnie (Thomas.Finnie@phe.gov.uk) @@ -74,6 +102,8 @@ Jonty Carruthers Martin Grunnill +Joseph Gibson + Version ======= 0.1.7 Add Approximate Bayesian Computation (ABC) as a method of fitting to data From 94b336cb0018bdc45a1286ba8092ce3288d2605a Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 4 Jun 2024 16:55:43 +0100 Subject: [PATCH 017/123] Clean up readme rst bugs --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index be277cd7..90b0c4e6 100644 --- a/README.rst +++ b/README.rst @@ -56,6 +56,7 @@ Alternatively, you may add dependencies to your own environment:: $ pip install -r requirements.txt If you are working on a Windows machine you will also need to install:: + * `Graphviz `_ * `Visual C++ `_ * `Visual C++ Build Tools ` From 941eae1912a1251ed9c6f4aacbe6aa94cdcb234e Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 4 Jun 2024 17:02:58 +0100 Subject: [PATCH 018/123] Readme bullet points --- README.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 90b0c4e6..6b9b2ecb 100644 --- a/README.rst +++ b/README.rst @@ -56,10 +56,10 @@ Alternatively, you may add dependencies to your own environment:: $ pip install -r requirements.txt If you are working on a Windows machine you will also need to install:: - - * `Graphviz `_ - * `Visual C++ `_ - * `Visual C++ Build Tools ` + + - `Graphviz `_ + - `Visual C++ `_ + - `Visual C++ Build Tools ` You should be able to install the PyGOM package via command line:: From 7b3021b076f5d501bc8cc75a67f7d3cac23a91d8 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 4 Jun 2024 17:22:44 +0100 Subject: [PATCH 019/123] Change README from rst to md --- README.rst => README.md | 83 ++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 47 deletions(-) rename README.rst => README.md (55%) diff --git a/README.rst b/README.md similarity index 55% rename from README.rst rename to README.md index 6b9b2ecb..0bde57ea 100644 --- a/README.rst +++ b/README.md @@ -1,19 +1,10 @@ -================================ -PyGOM - Python Generic ODE Model -================================ - -|Build status| |Github actions| |Documentation Status| |pypi version| |licence| |Jupyter Book Badge| - -.. |pypi version| image:: https://img.shields.io/pypi/v/pygom.svg - :target: https://pypi.python.org/pypi/pygom -.. |Documentation Status| image:: https://readthedocs.org/projects/pygom/badge/?version=master - :target: https://pygom.readthedocs.io/en/master/?badge=master -.. |licence| image:: https://img.shields.io/pypi/l/pygom?color=green :alt: PyPI - License - :target: https://raw.githubusercontent.com/PublicHealthEngland/pygom/master/LICENSE.txt -.. |Github actions| image:: https://github.com/PublicHealthEngland/pygom/workflows/pygom/badge.svg - :target: https://github.com/PublicHealthEngland/pygom/actions/ -.. |Jupyter Book Badge| image:: https://jupyterbook.org/badge.svg - :target: https://hwilliams-phe.github.io/pygom/intro.html +# PyGOM - Python Generic ODE Model + +[![pypi version](https://img.shields.io/pypi/v/pygom.svg)](https://pypi.python.org/pypi/pygom) +[![Documentation Status](https://readthedocs.org/projects/pygom/badge/?version=master)](https://pygom.readthedocs.io/en/master/?badge=master) +[![licence](https://img.shields.io/pypi/l/pygom?color=green)](https://raw.githubusercontent.com/PublicHealthEngland/pygom/master/LICENSE.txt) +[![Github actions](https://github.com/PublicHealthEngland/pygom/workflows/pygom/badge.svg)](https://github.com/PublicHealthEngland/pygom/actions/) +[![Jupyter Book Badge](https://jupyterbook.org/badge.svg)](https://hwilliams-phe.github.io/pygom/intro.html) A generic framework for Ordinary Differential Equation (ODE) models, especially compartmental type systems. This package provides a simple interface for users to construct ODE models. @@ -22,77 +13,75 @@ common operations for ODE systems such as parameter estimation and solving for d With both the algebraic and numeric calculations performed automatically (but still accessible), the end user is freed to focus on model development. -Installation -============ +## Installation -You can download a local copy of the PyGOM source files from this GitHub repository:: +You can download a local copy of the PyGOM source files from this GitHub repository: -$ git clone https://github.com/ukhsa-collaboration/pygom.git + git clone https://github.com/ukhsa-collaboration/pygom.git Please be aware that there may be redundant files within the package as it is under active development. -.. note:: +```{note} The latest fully reviewed version of PyGOM will be on the master branch and we generally recommend that users install the version from there. However, the current version being prepared for release (featuring up-to-date documentation) - is hosted on the feature/prep_doc branch. + is hosted on the `feature/prep_doc` branch. +``` Activate the relevant branch for installation via Git Bash, if you have been recruited to test code for the -new release then this is the feature/prep_doc branch:: +new release then this is the `feature/prep_doc` branch: -$ git activate feature/prep_doc + git activate feature/prep_doc -Package dependencies can be found in the file, requirements.txt. -An easy way to install these to create a new `conda `_ environment via:: +Package dependencies can be found in the file, `requirements.txt`. +An easy way to install these to create a new [conda](https://conda.io/docs) environment via: -$ conda env create -f conda-env.yml + conda env create -f conda-env.yml which you should ensure is active for the installation process using -$ conda activate pygom - -Alternatively, you may add dependencies to your own environment:: + conda activate pygom -$ pip install -r requirements.txt +Alternatively, you may add dependencies to your own environment: -If you are working on a Windows machine you will also need to install:: + pip install -r requirements.txt - - `Graphviz `_ - - `Visual C++ `_ - - `Visual C++ Build Tools ` +If you are working on a Windows machine you will also need to install: +- [Graphviz](https://graphviz.org/) +- [Visual C++](https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0) +- [Visual C++ Build Tools](https://go.microsoft.com/fwlink/?LinkId=691126) You should be able to install the PyGOM package via command line:: -$ python setup.py install + python setup.py install and test that installation has completed successfully -$ python setup.py test + python setup.py test This will run a few test cases and can take some minutes to complete. -Documentation -============= +## Documentation Documentation must be built locally and all necessary files can be found in the docs folder. -Documentation is built from the command line:: +Documentation is built from the command line: -$ jupyter-book build docs + jupyter-book build docs The html files will be saved in the local copy of your repository under: -$ pygom/docs/_build/html + pygom/docs/_build/html -.. note:: +```{note} Building the documentation involves running many examples in python which can take up to tens of minutes. Subsequent builds with these examples unchanged are much quicker due to caching of the code outputs. +``` Please be aware that if the module tests fails, then the documentation for the package will not compile. -Contributors -============ +## Contributors Thomas Finnie (Thomas.Finnie@phe.gov.uk) Edwin Tye @@ -105,8 +94,8 @@ Martin Grunnill Joseph Gibson -Version -======= +## Version + 0.1.7 Add Approximate Bayesian Computation (ABC) as a method of fitting to data 0.1.6 Bugfix scipy API, pickling, print to logging and simulation From 5ebe701a9833891042c35f66012aaf4e21451539 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 4 Jun 2024 17:28:35 +0100 Subject: [PATCH 020/123] More README edits --- README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0bde57ea..d3b9c64a 100644 --- a/README.md +++ b/README.md @@ -22,16 +22,14 @@ You can download a local copy of the PyGOM source files from this GitHub reposit Please be aware that there may be redundant files within the package as it is under active development. ```{note} - The latest fully reviewed version of PyGOM will be on the master branch and - we generally recommend that users install the version from there. However, - the current version being prepared for release (featuring up-to-date documentation) - is hosted on the `feature/prep_doc` branch. +The latest fully reviewed version of PyGOM will be on the master branch and we generally recommend that users install the version from there. +However, the current version being prepared for release (featuring up-to-date documentation) is hosted on the `feature/prep-doc` branch. ``` Activate the relevant branch for installation via Git Bash, if you have been recruited to test code for the -new release then this is the `feature/prep_doc` branch: +new release then this is the `feature/prep-doc` branch: - git activate feature/prep_doc + git activate feature/prep-doc Package dependencies can be found in the file, `requirements.txt`. An easy way to install these to create a new [conda](https://conda.io/docs) environment via: @@ -73,15 +71,15 @@ The html files will be saved in the local copy of your repository under: pygom/docs/_build/html ```{note} - Building the documentation involves running many examples in python - which can take up to tens of minutes. Subsequent builds with these - examples unchanged are much quicker due to caching of the code outputs. +Building the documentation involves running many examples in python which can take up to tens of minutes. +Subsequent builds with these examples unchanged are much quicker due to caching of the code outputs. ``` Please be aware that if the module tests fails, then the documentation for the package will not compile. ## Contributors + Thomas Finnie (Thomas.Finnie@phe.gov.uk) Edwin Tye From d5f7189540f2193376f00d6aeb82b42505912f07 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 4 Jun 2024 18:12:11 +0100 Subject: [PATCH 021/123] Even more README edits --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d3b9c64a..84d23858 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,8 @@ You can download a local copy of the PyGOM source files from this GitHub reposit Please be aware that there may be redundant files within the package as it is under active development. -```{note} -The latest fully reviewed version of PyGOM will be on the master branch and we generally recommend that users install the version from there. -However, the current version being prepared for release (featuring up-to-date documentation) is hosted on the `feature/prep-doc` branch. -``` +> [!NOTE] +> The latest fully reviewed version of PyGOM will be on the master branch and we generally recommend that users install the version from there. However, the current version being prepared for release (featuring up-to-date documentation) is hosted on the `feature/prep-doc` branch. Activate the relevant branch for installation via Git Bash, if you have been recruited to test code for the new release then this is the `feature/prep-doc` branch: From ea67a42712c430651723bd3203dbeee1a1189947 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 4 Jun 2024 18:20:28 +0100 Subject: [PATCH 022/123] Further minor README edits --- README.md | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 84d23858..0c39e2f9 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,9 @@ [![Jupyter Book Badge](https://jupyterbook.org/badge.svg)](https://hwilliams-phe.github.io/pygom/intro.html) A generic framework for Ordinary Differential Equation (ODE) models, especially compartmental type systems. -This package provides a simple interface for users to construct ODE models. -This is backed by a comprehensive and easy to use tool–box which implements functions to easily perform -common operations for ODE systems such as parameter estimation and solving for deterministic or stochastic time evolution. +This package provides a simple interface for users to construct ODE models which is backed by a comprehensive and easy to use tool–box which implements functions to easily perform common operations such as parameter estimation and solving for deterministic or stochastic time evolution. With both the algebraic and numeric calculations performed automatically (but still accessible), -the end user is freed to focus on model development. +the end user is free to focus on model development. ## Installation @@ -22,7 +20,7 @@ You can download a local copy of the PyGOM source files from this GitHub reposit Please be aware that there may be redundant files within the package as it is under active development. > [!NOTE] -> The latest fully reviewed version of PyGOM will be on the master branch and we generally recommend that users install the version from there. However, the current version being prepared for release (featuring up-to-date documentation) is hosted on the `feature/prep-doc` branch. +> The latest fully reviewed version of PyGOM will be on the `master` branch and we generally recommend that users install this version. However, the current version being prepared for release (featuring up-to-date documentation) is hosted on the `feature/prep-doc` branch. Activate the relevant branch for installation via Git Bash, if you have been recruited to test code for the new release then this is the `feature/prep-doc` branch: @@ -42,12 +40,12 @@ Alternatively, you may add dependencies to your own environment: pip install -r requirements.txt -If you are working on a Windows machine you will also need to install: +The final prerequisite, if you are working on a Windows machine, is that you will also need to install: - [Graphviz](https://graphviz.org/) - [Visual C++](https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0) - [Visual C++ Build Tools](https://go.microsoft.com/fwlink/?LinkId=691126) -You should be able to install the PyGOM package via command line:: +You should now be able to install the PyGOM package via command line: python setup.py install @@ -59,7 +57,7 @@ This will run a few test cases and can take some minutes to complete. ## Documentation -Documentation must be built locally and all necessary files can be found in the docs folder. +Documentation must be built locally and all necessary files can be found in the `docs` folder. Documentation is built from the command line: jupyter-book build docs @@ -68,13 +66,10 @@ The html files will be saved in the local copy of your repository under: pygom/docs/_build/html -```{note} -Building the documentation involves running many examples in python which can take up to tens of minutes. -Subsequent builds with these examples unchanged are much quicker due to caching of the code outputs. -``` +> [!NOTE] +> Building the documentation involves running many examples in python which can take up to tens of minutes. Subsequent builds with these examples unchanged are much quicker due to caching of the code outputs. -Please be aware that if the module tests fails, then the documentation for the -package will not compile. +Please be aware that if the module tests fails, then the documentation for the package will not compile. ## Contributors From a283f42bc1a67199214181d7bd2c59002f5a4e12 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 4 Jun 2024 18:41:41 +0100 Subject: [PATCH 023/123] Try to fix failed workflow --- README.md | 4 ++-- setup.py | 2 +- tests/test_abc.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0c39e2f9..b60b7374 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Jupyter Book Badge](https://jupyterbook.org/badge.svg)](https://hwilliams-phe.github.io/pygom/intro.html) A generic framework for Ordinary Differential Equation (ODE) models, especially compartmental type systems. -This package provides a simple interface for users to construct ODE models which is backed by a comprehensive and easy to use tool–box which implements functions to easily perform common operations such as parameter estimation and solving for deterministic or stochastic time evolution. +This package provides a simple interface for users to construct ODE models backed by a comprehensive and easy to use tool–box implementing functions to easily perform common operations such as parameter estimation and solving for deterministic or stochastic time evolution. With both the algebraic and numeric calculations performed automatically (but still accessible), the end user is free to focus on model development. @@ -64,7 +64,7 @@ Documentation is built from the command line: The html files will be saved in the local copy of your repository under: - pygom/docs/_build/html + docs/_build/html > [!NOTE] > Building the documentation involves running many examples in python which can take up to tens of minutes. Subsequent builds with these examples unchanged are much quicker due to caching of the code outputs. diff --git a/setup.py b/setup.py index 934baa63..0128ec87 100644 --- a/setup.py +++ b/setup.py @@ -68,7 +68,7 @@ else: install_requires.append(r) -with open('README.rst', 'r') as f: +with open('README.md', 'r') as f: readme = f.read() setup_requires = [ diff --git a/tests/test_abc.py b/tests/test_abc.py index e980d40b..9918f746 100644 --- a/tests/test_abc.py +++ b/tests/test_abc.py @@ -64,7 +64,7 @@ def test_SIR_abc_NormalLoss(self): parameters = [pgabc.Parameter('beta', 'unif', 0, 3, logscale=False), pgabc.Parameter('gamma', 'unif', 0, 3, logscale=False)] - sir_obj = pgabc.create_loss(NormalLoss, parameters, self.ode, self.x0, self.t[0], + sir_obj = pgabc.create_loss("NormalLoss", parameters, self.ode, self.x0, self.t[0], self.t[1::], y, ['I', 'R'], sigma=1.0) sir_abc = pgabc.ABC(sir_obj, parameters) From acd270bb0bb2c124e87718b795e51880a520e89a Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 5 Jun 2024 22:49:36 +0100 Subject: [PATCH 024/123] Finishing touches --- README.md | 2 +- docs/_toc.yml | 13 +- docs/md/getting_started.md | 109 ----- docs/md/intro.md | 30 +- docs/md/parameter_fitting.md | 23 +- docs/md/solving.md | 4 +- docs/notebooks/extract_info.ipynb | 77 +-- docs/notebooks/insights.ipynb | 6 +- docs/notebooks/model_params.ipynb | 20 +- docs/notebooks/model_solver.ipynb | 138 +++--- docs/notebooks/model_spec.ipynb | 58 +-- docs/notebooks/paramfit/bvpSimple.ipynb | 450 ++++++------------ docs/notebooks/paramfit/params_via_abc.ipynb | 90 ++-- .../paramfit/params_via_optimization.ipynb | 98 +++- docs/notebooks/paramfit/profile.ipynb | 133 ++++-- docs/notebooks/unroll/unrollSimple.ipynb | 386 ++------------- pygom/model/epi_analysis.py | 4 +- 17 files changed, 552 insertions(+), 1089 deletions(-) delete mode 100644 docs/md/getting_started.md diff --git a/README.md b/README.md index b60b7374..57cf9fa8 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ The html files will be saved in the local copy of your repository under: docs/_build/html > [!NOTE] -> Building the documentation involves running many examples in python which can take up to tens of minutes. Subsequent builds with these examples unchanged are much quicker due to caching of the code outputs. +> Building the documentation involves running many examples in python which can take up to 30 minutes. Subsequent builds with these examples unchanged are much quicker due to caching of the code outputs. Please be aware that if the module tests fails, then the documentation for the package will not compile. diff --git a/docs/_toc.yml b/docs/_toc.yml index fa34133d..cca0ae10 100644 --- a/docs/_toc.yml +++ b/docs/_toc.yml @@ -6,8 +6,9 @@ root: md/intro parts: - caption: Getting started chapters: - - file: md/getting_started - - caption: Pygom workflow + - file: md/installation + - file: md/building_doc + - caption: PyGOM workflow chapters: - file: notebooks/model_spec - file: notebooks/insights @@ -37,10 +38,10 @@ parts: # - file: notebooks/paramfit/estimate2 # - file: notebooks/paramfit/initialGuess # - file: notebooks/paramfit/profile - - caption: Appendix - chapters: - - file: notebooks/paramfit/gradient - - file: notebooks/paramfit/profile + #- caption: Appendix + # chapters: + # - file: notebooks/paramfit/gradient + # - file: notebooks/paramfit/profile - caption: Common biological compartmental models chapters: - file: md/common_models diff --git a/docs/md/getting_started.md b/docs/md/getting_started.md deleted file mode 100644 index 79904e57..00000000 --- a/docs/md/getting_started.md +++ /dev/null @@ -1,109 +0,0 @@ -# Set up - - - -## Installation - -### From source - -Source code for PyGOM can be downloaded from the GitHub repository: https://github.com/ukhsa-collaboration/pygom - -```bash -git clone https://github.com/ukhsa-collaboration/pygom.git -``` - -```{note} -The latest fully reviewed version of PyGOM will be on the master branch and we recommend that users install the version from there. -``` - -Dependencies may be added by creating an environment using conda - -```bash -conda env create -f conda-env.yml -``` - -This environment should be active during the installation process - -```bash -conda activate pygom -``` - -Alternatively, you may add dependencies to your own environment. - -```bash -pip install -r requirements.txt -``` - -If you are working on a Windows machine you will also need to install: -- [Graphviz](https://graphviz.org/) -- [Visual C++](https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0) -- [Visual C++ Build Tools](https://go.microsoft.com/fwlink/?LinkId=691126) - -You you should be able to install the PyGOM package via command line: - -```bash -python setup.py install -``` - -If you anticipate making your own frequent changes to the PyGOM source files, it might be more convenient to install in develop mode instead: - -```bash -python setup.py develop -``` - -### From PyPI - -Alternatively, the latest release can be installed from [PyPI](https://pypi.org/project/pygom/): - -```bash -pip install pygom -``` - -```{note} -Please note that there are some redundant files that are being kept for development purposes. -``` - -## Testing the package - -Test files can be run from the command line to check that installation has completed successfully - -```bash -python setup.py test -``` - -## Building the documentation locally - -The documentation which you are currently reading may be built locally. -First, install additional packages: - -```bash -pip install -r docs/requirements.txt -``` - -Then build the documentation from command line - -```bash -jupyter-book build docs -``` - -The html files will be saved in the local copy of your repository under: - - pygom/docs/_build/html \ No newline at end of file diff --git a/docs/md/intro.md b/docs/md/intro.md index 5895f46a..01054c30 100644 --- a/docs/md/intro.md +++ b/docs/md/intro.md @@ -2,14 +2,13 @@ ## What does this package do? -PyGOM (Python Generic ODE Model) is a Python package which provides a simple interface to easily construct systems -governed by Ordinary Differential Equations (ODEs), with a focus on compartmental models and epidemiology. -This is backed by a comprehensive and easy to use tool–box which implements functions to easily perform common operations for ODE -systems such as solving, parameter estimation, and stochastic simulation. -The package source is freely available (hosted on [Github](https://github.com/PublicHealthEngland/pygom)) and organized in a way that permits easy extension. With both the algebraic and numeric calculations performed automatically (but still accessible), the end user is freed to focus on model development. +PyGOM (Python Generic ODE Model) is a Python package which provides a simple interface for users to construct Ordinary Differential Equation (ODE) models, with a focus on compartmental models and epidemiology. +This is backed by a comprehensive and easy to use tool–box implementing functions to easily perform common operations such as parameter estimation and solving for deterministic or stochastic time evolution. +The package source is freely available (hosted on [Github](https://github.com/ukhsa-collaboration/pygom)) and organized in a way that permits easy extension. With both the algebraic and numeric calculations performed automatically (but still accessible), the end user is freed to focus on model development. ## Using this documentation -This documentation is built using [JupyterBook](https://jupyterbook.org/en/stable/intro.html). To use the contents of a notebook as a starting point for trialing or developing your own models and analyses, you can download any of the examples within this documentation by using the download icon on the desired page (located at the top right). +This documentation is built using [JupyterBook](https://jupyterbook.org/en/stable/intro.html). +To use the contents of a notebook as a starting point for trialing or developing your own models and analyses, you can download any of the examples within this documentation by using the download icon on the desired page (located at the top right). ![download file](../images/download.png) @@ -20,22 +19,3 @@ Please see the [contribution guidance](https://github.com/ukhsa-collaboration/py - The process by which code contributions should be incorporated - What is required by pull requests to PyGOM, including how to add to the documentation - How we will acknowledge your contributions - - - -```{tableofcontents} -``` diff --git a/docs/md/parameter_fitting.md b/docs/md/parameter_fitting.md index 7729d02f..64961c48 100644 --- a/docs/md/parameter_fitting.md +++ b/docs/md/parameter_fitting.md @@ -1,21 +1,6 @@ # Parameter fitting -In this chapter we outline how PyGOM may be used to estimate values for model parameters from data. -We focus on the common problem of finding epidemiological parameters from case data using Approximate Bayesian Computation (ABC). -We also demonstrate PyGom's ability to solve more commode ODE style problems like boundary value problems and -also ability to use more classical methods for optimization. - - - \ No newline at end of file +As well as producing forecasts, another key activity in infectious disease modelling is inference of epidemic parameters from incidence data. +In this chapter we outline how PyGOM may be used to assist these endeavours. +In {doc}`the first section <../notebooks/paramfit/params_via_abc>`, we present a more up to date method which uses Approximate Bayesian Computation (ABC) and {doc}`then <../notebooks/paramfit/params_via_optimization>` a more classical approach via Maximum Likelihood Estimation (MLE). +We also demonstrate PyGOM's ability to solve the less epidemiologically related task of {doc}`boundary value problems <../notebooks/paramfit/bvpSimple>` \ No newline at end of file diff --git a/docs/md/solving.md b/docs/md/solving.md index 6c9635d4..09df1175 100644 --- a/docs/md/solving.md +++ b/docs/md/solving.md @@ -1,10 +1,10 @@ # Producing forecasts -Once the system of ODE's has been specified, PyGOM allows the user to numerically solve for both the deterministic and stochastic time evolution. +An exercise central to the study of infectious diseases (and indeed ODE models in general) is performing simulations to understand the evolution of the system in time. +PyGOM allows the user to easily obtain numerical solutions for both the deterministic and stochastic time evolution of their model. Furthermore, users may specify model parameters to take either fixed values or to be drawn randomly from a probability distribution. In this chapter, we will use an SIR model as our example system to introduce - How to prescribe parameters in {doc}`Parameterisation <../notebooks/model_params>` - - How to obtain solutions and process the model output in {doc}`Finding ODE solutions <../notebooks/model_solver>` \ No newline at end of file diff --git a/docs/notebooks/extract_info.ipynb b/docs/notebooks/extract_info.ipynb index a609c546..d81401e1 100644 --- a/docs/notebooks/extract_info.ipynb +++ b/docs/notebooks/extract_info.ipynb @@ -7,9 +7,9 @@ "source": [ "# Extracting model information\n", "\n", - "In the study of ODE systems, there are many calculations which are commonly performed and PyGOM has some functionality to make these easier.\n", - "We will again use the SIR model (REF) as our model system, but this time we will make use of the common_models feature, where many predefined models are stored.\n", - "This means we can avoid having to define the model from scratch again." + "In the study of ODE systems, there are many calculations which are frequently performed and so PyGOM has some functionality to provide assistance.\n", + "We will again use the SIR model as our model system, but this time we will make use of the functions from PyGOM's `common_models`, where many predefined models are stored.\n", + "This means we can avoid having to build the model from scratch again." ] }, { @@ -30,7 +30,7 @@ "source": [ "## Verification\n", "\n", - "As seen previously, the `get_ode_eqn` function allows us to check our system of ODEs." + "As seen previously, the {func}`.get_ode_eqn` function allows us to verify that our ODE equations are as we'd expect:" ] }, { @@ -49,7 +49,8 @@ "metadata": {}, "source": [ "```{tip}\n", - "In addition to showing the equation form of the ODEs, we can also display them as either symbols or latex code, which can save some extra typing when porting the equations to another document.```" + "In addition to showing the Python equation form of the ODEs, we can also display them as either symbols or latex code, which can save some extra typing when porting the equations to another document.\n", + "```" ] }, { @@ -68,7 +69,7 @@ "id": "d9d71015", "metadata": {}, "source": [ - "We can also check in terms of transitions" + "We can check the model definition in terms of a transition matrix:" ] }, { @@ -86,7 +87,7 @@ "id": "9c7b5c60", "metadata": {}, "source": [ - "And even inspect the transition diagram" + "and even inspect the transitions graphically:" ] }, { @@ -126,7 +127,7 @@ "id": "c3fa0e62", "metadata": {}, "source": [ - "For stability analysis and speeding up numerical integrators, it may be useful to know the Jacobian, Hessian or gradient" + "For stability analysis and speeding up numerical integrators, it may be useful to know the Jacobian, Hessian or gradient which PyGOM has functions for respectively:" ] }, { @@ -166,82 +167,32 @@ "source": [ "## Epidemiology specific insights\n", "\n", - "The {func}`.R0` function may be used to obtain the basic reproduction number $R_{0}$.\n", - "We must specify which state represents the *disease state*, which in this case is the state **I**.\n", - "#TODO is this the disease state, or the infectious state?" + "Under development are functions to obtain numeric and algebraic expressions for the basic reproduction number, $R_0$.\n", + "We must specify which state represents the *infectious state*, which in this case is the state **I**." ] }, { "cell_type": "code", - "execution_count": 2, - "id": "b6eeb070", + "execution_count": 3, + "id": "d099d92b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Matrix([[S*beta/N]])\n", - "Matrix([[gamma]])\n", - "[S*beta/(N*gamma)]\n", - "{S: 0, R: 0}\n", - "[0]\n", - "[0]\n" + "[S*beta/(N*gamma)]\n" ] } ], "source": [ "from pygom.model.epi_analysis import *\n", "\n", - "R_0=R0(ode, 'I')\n", - "print(R_0)" - ] - }, - { - "cell_type": "markdown", - "id": "290ce7ec", - "metadata": {}, - "source": [ - "We may also wish to get the $R_{0}$ in pure algebraic terms.\n", - "This can be achieved by the following few lines of code. Note that the result below is slightly different from the one above.\n", - "The difference is due to the internal working of the functions, where {func}`.getR0` computes the disease-free equilibrium value for the states and substitutes them back into the equation." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d099d92b", - "metadata": {}, - "outputs": [], - "source": [ "F, V = disease_progression_matrices(ode, 'I')\n", "\n", "e = R0_from_matrix(F, V)\n", "print(e)" ] - }, - { - "cell_type": "markdown", - "id": "94980c72", - "metadata": {}, - "source": [ - "To replicate the output before, we have to find the values where the\n", - "disease-free equilibrium will be achieved. Substitution can then be\n", - "performed to retrieve $R_{0}$ in pure parameters." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "68ea8f68", - "metadata": {}, - "outputs": [], - "source": [ - "dfe = DFE(ode, ['I'])\n", - "\n", - "print(dfe)\n", - "print(e[0].subs(dfe))" - ] } ], "metadata": { diff --git a/docs/notebooks/insights.ipynb b/docs/notebooks/insights.ipynb index 3fb96cf1..ee10c1b7 100644 --- a/docs/notebooks/insights.ipynb +++ b/docs/notebooks/insights.ipynb @@ -7,10 +7,8 @@ "source": [ "# ODE Insights\n", "\n", - "As mentioned previously, once our ODE system is encapsulated in the `SimulateOde` class, it is ready to be studied using PyGOM's simulation and parameter estimation methods.\n", - "However, we can also take advantage of several useful features of PyGOM which provide us with more analytical insights which we might commonly need pen and paper to find for ourselves.\n", - "\n", - "In this chapter we outline some of these methods which allow us to quickly obtain algebraic results which we frequently find ourselves calculating." + "Now that our SIR model is encapsulated in the {class}`SimulateOde` class, it is ready to be studied using PyGOM's various functionalities.\n", + "Before moving on to more complex methods such as parameter fitting and simulation, we can take advantage of several useful features of PyGOM which provide us with more analytical insights - the sort we might commonly find ourselves calculating, requiring pen and paper to do so." ] } ], diff --git a/docs/notebooks/model_params.ipynb b/docs/notebooks/model_params.ipynb index 5a43fd9b..964d8514 100644 --- a/docs/notebooks/model_params.ipynb +++ b/docs/notebooks/model_params.ipynb @@ -9,9 +9,9 @@ "\n", "Until now, we have only dealt with parameters when it was necessary to inform PyGOM which of our symbols refer to states and which to parameters.\n", "However, before PyGOM can find numerical solutions to the equations, it must be fed numerical parameter values.\n", - "\n", - "PyGOM's ODE solvers accept parameters in two forms: fixed, where they remain constant or random, where they are drawn at random from a given distribution.\n", - "We demonstrate these features on our model system, the SIR compartmental model. We start, as always, by encapsulating our ODE system in a pygom object from the previous section:" + "PyGOM's ODE solvers accept parameters in two forms: fixed, where they remain constant or random, where they are drawn from a given distribution.\n", + "We demonstrate these features on our model system, the SIR compartmental model.\n", + "We start, as always, by encapsulating our ODE system in a PyGOM object, in this case loading a previously defined model." ] }, { @@ -32,8 +32,7 @@ "source": [ "## Fixed parameters\n", "\n", - "Defining fixed parameters is simple.\n", - "Here we assign $\\beta$, $\\gamma$ and $N$ as follows." + "Defining fixed parameters is for $\\beta$, $\\gamma$ and $N$ is simply done as follows:" ] }, { @@ -58,12 +57,13 @@ "\n", "## Random parameters\n", "\n", - "Instead, imagine that we wish to run model simulations over a variety of parameter values to reflect our prior uncertainty on the values of those parameters.\n", + "Instead, imagine that we have some prior uncertainty on the values of our model parameters.\n", + "We may wish to reflect this by running model simulations over a variety of parameter values drawn randomly from a probability distribution.\n", "A suitable choice of distribution for $\\gamma$ and $\\beta$ is a Gamma distribution, since it ensures that both parameters are positive as required.\n", "In this example, we'll keep the total population, $N$, fixed, showing that a mixture of parameter types (fixed and random) is possible.\n", "\n", "To define our random distributions, we make use of the familiar syntax from [R](http://www.r-project.org/).\n", - "Unfortunately, we have to define it via a tuple, where the first item is the function handle (name) and the second the parameters. " + "Slightly cumbersomely, we have to define it via a tuple, where the first item is the function handle (name) and the second the parameters. " ] }, { @@ -85,9 +85,9 @@ "id": "a4c4ca97", "metadata": {}, "source": [ - "Here, $\\gamma$ and $\\beta$ have means of 0.25 and 0.3 standard deviations of 0.025 and 0.03 respectively.\n", - "\n", - "When changing parameters, it is a good idea to define a new `SimulateOde` object, since there may be some calculated variables leftover from the previous parameter set." + "The values of the shape and rate parameters mean that $\\gamma$ and $\\beta$ have means of 0.25 and 0.3 and standard deviations of 0.025 and 0.03 respectively.\n", + "When changing parameters, it is a good idea to define a new `SimulateOde` object, since there may be some calculated variables leftover from the previous parameter set.\n", + "We do not need to inform PyGOM that the parameters are random and define them in the same way as before:" ] }, { diff --git a/docs/notebooks/model_solver.ipynb b/docs/notebooks/model_solver.ipynb index 5e5c4e62..c8eeda8e 100644 --- a/docs/notebooks/model_solver.ipynb +++ b/docs/notebooks/model_solver.ipynb @@ -6,20 +6,18 @@ "source": [ "# Finding ODE solutions\n", "\n", - "PyGOM allows the user to evaluate both the **deterministic** and **stochastic** time evolution of their ODE system using the class methods `solve_determ` and `solve_stochast` respectively. These methods work with fixed and random parameters as introduced in the {doc}`previous section <../notebooks/model_params>`.\n", + "PyGOM allows the user to evaluate both the **deterministic** and **stochastic** time evolution of their ODE system using the class methods {func}`solve_determ` and {func}`solve_stochast` respectively.\n", + "These methods work with both fixed and random parameters as introduced in the {doc}`previous section <../notebooks/model_params>`.\n", "\n", - "We begin by defining the series of ODEs and parameters which define our SIR system." + "We begin by defining the series of ODEs and parameters which define our SIR system.\n", + "This we do from scratch rather than loading in a previously defined model in order to present a more comprehensive example of the workflow." ] }, { "cell_type": "code", "execution_count": null, "id": "1679a48a", - "metadata": { - "tags": [ - "hide-input" - ] - }, + "metadata": {}, "outputs": [], "source": [ "from pygom import SimulateOde, Transition, TransitionType\n", @@ -36,15 +34,14 @@ "transitionList = [Transition(origin='S', destination='I', equation='beta*S*I/N', transition_type=TransitionType.T),\n", " Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)]\n", "\n", - "# Total population is fixed\n", - "n_pop=1e4\n", + "n_pop=1e4 # Total population is fixed\n", "\n", "############\n", "# Parameters\n", "############\n", "\n", - "beta_mn=0.35 # infectivity, beta. Gives the actual value for fixed params and mean for random distribution.\n", - "gamma_mn=0.25 # recovery rate, gamma.\n", + "beta_mn=0.35 # Infectivity, beta. Gives the actual value for fixed params and mean for random distribution.\n", + "gamma_mn=0.25 # Recovery rate, gamma.\n", "\n", "#######\n", "# Fixed\n", @@ -72,13 +69,32 @@ "random_param_set['N'] = n_pop" ] }, + { + "cell_type": "markdown", + "id": "fa186a81", + "metadata": {}, + "source": [ + "Since this notebook will involve stochastic processes, we set the random number generator seed to make outputs reproducible." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dc7996d", + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "random.seed(1)" + ] + }, { "cell_type": "markdown", "id": "e976c853", "metadata": {}, "source": [ "In order to determine the time evolution of the system, we must supply initial conditions as well as the desired time points for the numerical solver.\n", - "It is generally a good idea to have the timestep an order of magnitude smaller than the fastest timescale of the system, in this case...." + "Timesteps should be sufficiently short to minimise numerical integration errors, but not too short such that the computational time costs become too large." ] }, { @@ -106,7 +122,7 @@ "source": [ "## Deterministic time evolution\n", "\n", - "To solve for the deterministic time evolution of the system, PyGOM uses `scipy.integrate.odeint`.\n", + "To solve for the deterministic time evolution of the system, PyGOM uses {func}`scipy.integrate.odeint` which is wrapped by the member function {func}`solve_determ`.\n", "We begin with the simple (and likely familiar) case of fixed parameters.\n", "\n", "### Fixed parameters\n", @@ -123,7 +139,7 @@ "source": [ "# Set up pygom object (D_F suffix implies Deterministic_Fixed)\n", "ode_D_F = SimulateOde(stateList, paramList, transition=transitionList)\n", - "ode_D_F.initial_values = (x0, t[0])\n", + "ode_D_F.initial_values = (x0, t[0]) # (initial state conditions, initial timepoint)\n", "ode_D_F.parameters=fixed_param_set" ] }, @@ -132,7 +148,7 @@ "id": "801dbfd6", "metadata": {}, "source": [ - "The solution is then found via `solve_determ`, specifying the required time steps not including the initial one." + "The solution is then found via `solve_determ`, specifying the required time steps (not including the initial one)." ] }, { @@ -150,7 +166,7 @@ "id": "a4d12509", "metadata": {}, "source": [ - "Plotting the output yields the familiar result, where infecteds initially increase in number exponentially until critical depletion of susceptibles sends the epidemic into decline." + "Plotting the output yields the familiar result, where infecteds initially increase in number exponentially until critical depletion of susceptibles results in epidemic decline." ] }, { @@ -171,7 +187,9 @@ "axarr[2].plot(t, solution_D_F[:,2], color='C2')\n", "\n", "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_title(state)\n" + " axarr[idx].set_title(state)\n", + " axarr[idx].set_xlabel('Time')\n", + "\n" ] }, { @@ -198,7 +216,7 @@ "metadata": {}, "source": [ "We now solve the same system, but for 1000 repetitions using randomly drawn parameters for each simulation.\n", - "This time we initialise the parameters with`random_param_set` and solve using `solve_determ` as before" + "This time we initialise the parameters with`random_param_set`, but still use {func}`solve_determ` to find solutions as before" ] }, { @@ -211,9 +229,9 @@ "# Set up pygom object\n", "ode_D_R = SimulateOde(stateList, paramList, transition=transitionList)\n", "ode_D_R.initial_values = (x0, t[0])\n", + "ode_D_R.parameters=random_param_set\n", "\n", "n_param_draws=1000 # number of parameters to draw\n", - "ode_D_R.parameters=random_param_set\n", "Ymean, solution_D_R = ode_D_R.solve_determ(t[1::], n_param_draws, full_output=True)" ] }, @@ -225,8 +243,7 @@ "```{note}\n", "Note that a message may be printed above where PyGOM is trying to connect to an\n", "mpi backend, as our module has the capability to compute in parallel\n", - "using the IPython. We have simulated a total of 10 different solutions\n", - "using different parameters, the plots can be seen below.\n", + "using the IPython.\n", "```" ] }, @@ -235,7 +252,7 @@ "id": "9bb7c942", "metadata": {}, "source": [ - "We visualise the output in 2 ways, first by viewing 50 randomly selected trajectories and also by viewing the confidence intervals (here 95% and 50%) and median calculated over the full 1000 solutions." + "Here we visualise the output in 2 ways, first by viewing 50 randomly selected trajectories and secondly by viewing the confidence intervals (here 95% and 50%) and median calculated over the full 1000 solutions." ] }, { @@ -257,8 +274,6 @@ "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", "\n", "# Select 50 simulations to plot\n", - "import random\n", - "random.seed(10)\n", "i_rand=random.sample(range(n_param_draws), 50)\n", "\n", "# Plot colours\n", @@ -290,7 +305,7 @@ " axarr[i].plot(t, y_D_R_md[:,i], color=colours[i])\n", "\n", "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_title(state)\n" + " axarr[idx].set_xlabel('Time')\n" ] }, { @@ -318,23 +333,17 @@ "source": [ "## Stochastic evolution\n", "\n", - "In a continuous Markov representation, each movement in the system is a result of a jump process.\n", - "More concretely, the probabilty of a move for transition $j$ is governed\n", - "by an exponential distribution such that\n", - "\n", - "$$\\Pr(\\text{process $j$ jump within time } \\tau) = \\lambda_{j} e^{-\\lambda_{j} \\tau},$$\n", - "\n", - "where $\\lambda_{j}$ is the rate of transition for process $j$ and $\\tau$\n", - "the time elapsed after current time $t$.\n", + "The approximation that numbers of individuals in each state may be treated as a continuum break down when their sizes are small.\n", + "In this regime, transitions between states do not represent continuous flows but are instead stochastic events that occur at rates governed by the current state of the system. The simplifying assumption that waiting times for these events to occur are exponentially distributed (memoryless), allows for quicker evaluation of the dynamics.\n", "\n", - "Two of the commmon algorithms for the jump process have been\n", - "implemented for use during simulation; the reaction method [\\[Gillespie1977\\]]() and the $\\tau$-Leap method\n", - "[\\[Cao2006\\]](). The two change interactively depending on the size of the states.\n", + "Two common algorithms have been implemented for use during simulation; the reaction method [\\[Gillespie1977\\]]() and the $\\tau$-Leap method\n", + "[\\[Cao2006\\]]().\n", + "The two change interactively depending on the size of the states.\n", "\n", "### Fixed parameters\n", "\n", "As previously, we define a model and pass our fixed parameters `fixed_param_set`.\n", - "However, this time we employ the function `solve_stochast`" + "However, this time we employ the function `solve_stochast` to allow for stochastic time evolution:" ] }, { @@ -376,6 +385,7 @@ "final_size_S_F=y_S_F[-1, 2, :]\n", "\n", "plt.figure(figsize=(3, 2.5))\n", + "plt.title(\"Epidemic final size distribution\")\n", "plt.hist(final_size_S_F, bins=100, color=\"C0\")\n", "\n", "# Plot failed epidemics\n", @@ -383,6 +393,8 @@ "y_fail_S_F=np.delete(y_S_F, obj=i_success_S_F, axis=2) \n", "f, ax = plt.subplots(figsize=(3, 2.5))\n", "\n", + "ax.set_title(\"Stochastically extinct epidemic trajectories\")\n", + "ax.set_xlabel(\"Time\")\n", "for i in range(min(y_fail_S_F.shape[2], 3)):\n", " ax.plot(t[0:300], y_fail_S_F[0:300,1,i], color=\"C0\", alpha=0.5)" ] @@ -392,9 +404,9 @@ "id": "39f93f66", "metadata": {}, "source": [ - "We see that a fraction, perhaps 4%, of the simulations have final sizes very close to zero.\n", - "In these cases, the chain of infecteds reaches stochastic extinction before an epidemic is able to take off.\n", - "We proceed to eliminate these when plotting our simulation outputs" + "We see that a fraction, just under 4%, of the simulations have final sizes very close to zero.\n", + "In these cases, the chain of infections reaches stochastic extinction before an epidemic is able to take off.\n", + "We proceed to eliminate these when plotting our simulation outputs, since we'd like to compare the output here with our deterministic results (which, by definition, no not exhibit stochastic extinction):" ] }, { @@ -449,7 +461,7 @@ " axarr[i].plot(t, y_S_F_md[:,i], color=colours[i])\n", "\n", "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_title(state)\n", + " axarr[idx].set_xlabel(\"Time\")\n", "\n" ] }, @@ -503,6 +515,7 @@ "\n", "final_size_S_R=y_S_R[-1, 2, :]\n", "plt.figure(figsize=(3, 2.5))\n", + "plt.title(\"Epidemic final size distribution\")\n", "plt.hist(final_size_S_R, bins=100)\n", "plt.show()" ] @@ -569,7 +582,7 @@ " axarr[i].plot(t, y_S_R_md[:,i], color=colours[i])\n", "\n", "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_title(state)" + " axarr[idx].set_xlabel(\"Time\")" ] }, { @@ -580,7 +593,7 @@ "## Summary\n", "\n", "With two possible simulation methods and two possible parameter types, we have explored the four total model configurations.\n", - "We plot these results side by side for the infected compartment so we can observe the key differences." + "We plot these results side by side for the infected compartment so provide a final illustration of their key qualitative differences." ] }, { @@ -596,27 +609,6 @@ "source": [ "ymax=1250\n", "\n", - "#fig, axarr = plt.subplots(2,2, layout='constrained')\n", - "\n", - "# axarr[0][0].plot(t, solution_D_F[:,1], color=\"black\")\n", - "# axarr[0][0].set_ylim(bottom=0, top=ymax)\n", - "\n", - "# axarr[0][1].fill_between(t, y_S_F_lolo[:,j], y_S_F_hihi[:,j], alpha=0.3, facecolor='blue')\n", - "# axarr[0][1].fill_between(t, y_S_F_lo[:,j], y_S_F_hi[:,j], alpha=0.4, facecolor='blue')\n", - "# axarr[0][1].plot(t, y_S_F_md[:,j], color=\"black\")\n", - "# axarr[0][1].set_ylim(bottom=0, top=ymax)\n", - "\n", - "# axarr[1][0].fill_between(t, y_D_R_lolo[:,j], y_D_R_hihi[:,j], alpha=0.3, facecolor='blue')\n", - "# axarr[1][0].fill_between(t, y_D_R_lo[:,j], y_D_R_hi[:,j], alpha=0.4, facecolor='blue')\n", - "# axarr[1][0].plot(t, y_D_R_md[:,j], color=\"black\")\n", - "# axarr[1][0].set_ylim(bottom=0, top=ymax)\n", - "\n", - "# axarr[1][1].fill_between(t, y_S_R_lolo[:,j], y_S_R_hihi[:,j], alpha=0.3, facecolor='blue')\n", - "# axarr[1][1].fill_between(t, y_S_R_lo[:,j], y_S_R_hi[:,j], alpha=0.4, facecolor='blue')\n", - "# axarr[1][1].plot(t, y_S_R_md[:,j], color=\"black\")\n", - "# axarr[1][1].set_ylim(bottom=0, top=ymax)\n", - "\n", - "\n", "fig, axarr2 = plt.subplots(2,2, layout='constrained', figsize=(10, 6))\n", "\n", "axarr2[0][0].plot(t, solution_D_F[:,1], color=\"C0\")\n", @@ -626,14 +618,22 @@ "\n", "for i in i_rand:\n", " axarr2[0][1].plot(t, y_S_F[:,1,i], color=\"C0\", alpha=0.3)\n", - " axarr2[0][1].set_ylim(bottom=0, top=ymax)\n", - "\n", " axarr2[1][0].plot(t, y_D_R[:,1,i], color=\"C0\", alpha=0.3)\n", - " axarr2[1][0].set_ylim(bottom=0, top=ymax)\n", - "\n", " axarr2[1][1].plot(t, y_S_R[:,1,i], color=\"C0\", alpha=0.3)\n", - " axarr2[1][1].set_ylim(bottom=0, top=ymax)\n", "\n", + "axarr2[0][0].set_title(\"Deterministic with fixed params\")\n", + "axarr2[0][1].set_title(\"Stochastic with fixed params\")\n", + "axarr2[1][0].set_title(\"Deterministic with random params\")\n", + "axarr2[1][1].set_title(\"Stochastic with random params\")\n", + "\n", + "axarr2[0][0].set_xlabel(\"Time\")\n", + "axarr2[0][1].set_xlabel(\"Time\")\n", + "axarr2[1][0].set_xlabel(\"Time\")\n", + "axarr2[1][1].set_xlabel(\"Time\")\n", + "\n", + "axarr2[0][1].set_ylim(bottom=0, top=ymax)\n", + "axarr2[1][0].set_ylim(bottom=0, top=ymax)\n", + "axarr2[1][1].set_ylim(bottom=0, top=ymax)\n", "plt.show()" ] }, diff --git a/docs/notebooks/model_spec.ipynb b/docs/notebooks/model_spec.ipynb index 7aef2beb..7d0316e5 100644 --- a/docs/notebooks/model_spec.ipynb +++ b/docs/notebooks/model_spec.ipynb @@ -7,10 +7,9 @@ "source": [ "# Defining an ODE system\n", "\n", - "The starting point in using PyGOM to study an ODE system is to encapsulate the relevant information about the system into a class {class}`SimulateOde`.\n", - "When set up in this object, the system is prepared for application of the various features of PyGOM such as simulation and model fitting.\n", + "The starting point when using PyGOM to study an ODE system is to encapsulate the relevant information into a class {class}`.SimulateOde`.\n", + "Once defined as an object of this class, the system is prepared for the application of PyGOM's various features such as simulation and parameter fitting.\n", "\n", - "\n", "## Equations vs Transitions\n", "\n", "Firstly, we outline the two main ways we might think about defining our ODE system.\n", @@ -18,9 +17,9 @@ "\n", "$$\\frac{\\mathrm{d} \\mathbf{y}}{\\mathrm{d} t} = f(\\mathbf{y},\\boldsymbol{\\theta}, t)$$\n", "\n", - "where $\\mathbf{y} = \\left(y_{1},\\ldots,y_{n}\\right)$ is the state vector, $\\boldsymbol{\\theta} = \\left(\\theta_{1},\\ldots, \\theta_{p}\\right)$ is the set of parameters and $f$ is a vector function giving the rates of change of each state.\n", + "where $\\mathbf{y} = \\left(y_{1},\\ldots,y_{n}\\right)$ is a vector of the dependent variables, $\\boldsymbol{\\theta} = \\left(\\theta_{1},\\ldots, \\theta_{p}\\right)$ is the set of parameters and $f$ is a vector function giving the rates of change of each dependent variable.\n", "\n", - "Compartmental models, whereby the variables represent categories, have another interpretation in which we may instead consider transitions between the different groups\n", + "Compartmental models, whereby the dependent variables represent categories or states, have another interpretation in which we may instead consider transitions between the different groups\n", "\n", "$$\\begin{aligned}\n", "y_i \\rightarrow y_j = f_{i,j}(\\mathbf{y},\\boldsymbol{\\theta}) \\\\\n", @@ -28,18 +27,20 @@ "\n", "where $i, j = \\{1,\\ldots, n\\}$ and $f_{i,j}$ are functions governing the rate at which members of group $i$ transition to $j$.\n", "\n", - "PyGOM allows the user flexibility to choose which of these perspectives to use, or indeed combine, in order to build their models.\n", - "If given transitions, Pygom will automatically convert these into equations and, as we'll see later, it can also attempt to reverse engineer transitions from equations.\n", + "PyGOM allows the user flexibility in choosing which of these perspectives to use, or indeed combine, in order to build their models.\n", + "If given transitions, PyGOM will automatically convert these into equations and, as we'll see later, it can also attempt to reverse engineer transitions from equations.\n", "\n", "## Example: SIR model\n", "\n", "Here we use a Susceptible-Infected-Recovered epidemic model (an SIR model, for short) to demonstrate the two different ways PyGOM supports model specification.\n", - "Since we will frequently rely on the SIR model in examples throughout the tutorial, we take a moment here to outline its key features.\n", + "Since we will frequently rely on the SIR model in examples throughout this tutorial, we take a moment here to outline its key features.\n", "\n", - "Firstly, there is some ambiguity in the naming of the Recovered class which is also commonly referred to as Removed.\n", + "```{warning}\n", + "There is some ambiguity in the naming of the Recovered class which is also commonly referred to as Removed.\n", "In the latter sense, there is no distinction made between those who can no longer be infected due to infection acquired immunity and infection induced death.\n", - "However, for more complex models, the recovered class may become susceptible again due to immune waning and number of deaths is typically important to distinguish.\n", - "Thus, we make the distinction clear from the outset so that when we talk about deaths in this tutorial it will have its own class, Dead, separate from Recovered. \n", + "However, for more complex models, the recovered class may become susceptible again due to immune waning and deaths versus recoveries are typically important to distinguish in real world applications.\n", + "Therefore, in this tutorial, the Recovered class will be reserved solely for those who survive infection.\n", + "```\n", "\n", "The assumptions of the SIR model:\n", "1) An average member of the population makes contact sufficient to transmit infection with $\\beta$ others per unit time (*standard* as opposed to *mass-action* incidence, where this would be $\\beta N$).\n", @@ -62,18 +63,18 @@ "I \\rightarrow R &= \\gamma I\n", "\\end{aligned}$$\n", "\n", - "Advantages of specifying our system using the transition approach are firstly that transitions are a more intuitive language when thinking about building compartmental models.\n", - "Perhaps more beneficial, though, is that it enables the computer to do our book-keeping when converting transitions to ODE equations.\n", + "Advantages of specifying our system using the transition approach are firstly that transitions are a more intuitive language when thinking about compartmental models.\n", + "Perhaps more beneficial, though, is that when building models with transitions using PyGOM in enables the computer to do our book-keeping when converting transitions to ODE equations.\n", "This reduces the error of, for example, including a flow out of one state, but forgetting to include it in the recipient state.\n", - "In this case, we had to remember to include $-\\frac{\\beta SI}{N}$ in the $S$ equation and the opposite sign in the $I$ equation, for example.\n", + "For instance, in this case, we had to remember to include $-\\frac{\\beta SI}{N}$ in the $S$ equation and the opposite sign in the $I$ equation.\n", "\n", "## Defining the model with PyGOM\n", "\n", - "Defining the system is handled by feeding classes of {class}`Transition` into the main class we referred to at the start, {class}`SimulateOde`.\n", - "The {class}`Transition` class has 4 types, which are specified by the `transition_type` argument.\n", - "This lets `SimulateOde` know in which format we are inputting our information.\n", - "This could be as transitions or ODEs as we've just been discussing, or as the other two available options which are birth and death processes.\n", - "The {class}`Transition` class accepts 3 or 4 parameters depending on which type is being defined as summarised in the below table:\n", + "Defining the system is handled by feeding {class}`.Transition` classes into the main class we referred to at the start, {class}`.SimulateOde`.\n", + "The {class}`.Transition` class has 4 types, which are specified by the `transition_type` argument.\n", + "This lets {class}`.SimulateOde` know in which format we are inputting our information.\n", + "This could be as `.Transitions` or `ODEs` as we've just been discussing, or as the other two available options, namely `Birth` and `Death` processes.\n", + "The {class}`.Transition` class accepts 3 or 4 parameters depending on which type is being defined as summarised in the below table:\n", "\n", "| | Transition | Equation | Birth | Death |\n", "|:---------------:|:-------------------------------:|:---------------------------------:|:--------------------------------------:|:--------------------------------------:|\n", @@ -83,11 +84,10 @@ "| equation | $f_{i,j}$ | $\\frac{dy_i}{dt}$ | $\\frac{dy_i}{dt}$ due to birth process | $\\frac{dy_i}{dt}$ due to death process |\n", "\n", "```{note}\n", - "Arguably the state which the birth process populates could be defined as a destination rather than an origin, but this is the convention adopted here.\n", + "Arguably, the state which the birth process populates could be defined as a destination rather than an origin, but this is not the convention adopted here.\n", "\n", - "Also, the {class}`Transition` class may have been better named.\n", - "Firstly, one of the four possible input types is also called \"transition\", which would imply that it has a special place within the class given that it shares its name.\n", - "However, all other forms of input (ODE, birth and death) are equally valid.\n", + "Furthermore, the {class}`.Transition` class may have been better named.\n", + "This is because one of the four possible input types is also called \"transition\", which would incorrectly imply that it has a special place within the class, given that it shares its name.\n", "```\n", "\n", "Let's see how this is implemented for our example SIR system." @@ -121,7 +121,7 @@ "id": "bc7ee766", "metadata": {}, "source": [ - "We now initialise two `SimulateODE` objects using these different approaches.\n", + "We now initialise two {class}`.SimulateOde` objects using these different approaches.\n", "In addition to the ODE or transition information, we must specify which variables are parameters and which refer to states." ] }, @@ -141,7 +141,7 @@ "id": "b6a2bec7", "metadata": {}, "source": [ - "We define the model in two different ways" + "We define the model in two different ways:" ] }, { @@ -161,7 +161,7 @@ "id": "8e38d76b", "metadata": {}, "source": [ - "We can use the `get_ode_eqn` function to verify that the models are equivalent" + "We can use the {func}`.get_ode_eqn` function to verify that the models are equivalent" ] }, { @@ -191,7 +191,7 @@ "source": [ "## Modifying models\n", "\n", - "Once a `SimulateODE` object has been defined, it may be modified.\n", + "Once a {class}`.SimulateOde` object has been defined it may be modified.\n", "For example, let's say we wish to add birth and death processes to the the previously defined SIR model of `model_ode`.\n", "We must update the parameters of the class to reflect any additions." ] @@ -211,7 +211,7 @@ "id": "f9236e77", "metadata": {}, "source": [ - "We must also add in the new processes" + "We then include the additional processes" ] }, { @@ -234,7 +234,7 @@ "id": "3685b2e1", "metadata": {}, "source": [ - "We can again use `get_ode_eqn` to verify that the equations are updated" + "We can again use {func}`.get_ode_eqn` to verify that the equations are updated" ] }, { diff --git a/docs/notebooks/paramfit/bvpSimple.ipynb b/docs/notebooks/paramfit/bvpSimple.ipynb index 7b2d5d6e..f57ab79b 100644 --- a/docs/notebooks/paramfit/bvpSimple.ipynb +++ b/docs/notebooks/paramfit/bvpSimple.ipynb @@ -6,134 +6,81 @@ "source": [ "# Solving Boundary Value Problems\n", "\n", - "In addition to finding solutions for an initial value problem (IVP) and estimating the unknown\n", - "parameters, this package also allows you to solve boundary value problems (BVP) with a little bit\n", - "of imagination. Here, we are going to show how a BVP can be solved by\n", - "treating it as a parameter estimation problem. Essentially, a shooting\n", - "method where the first boundary condition defines the initial condition\n", - "of an IVP and the second boundary condition is an observation. Two\n", - "examples, both from the [bvp4c implementation in MATLAB](https://uk.mathworks.com/help/matlab/ref/bvp4c.html), are demonstrated here.\n", - "\n", - "\n", - "```{note}\n", - "These examples are general and not specific to disease scenarios.\n", - "```" + "In addition to finding solutions for an initial value problem (IVP) and estimating unknown parameters, PyGOM also allows users to solve boundary value problems (BVPs) with a little bit of imagination.\n", + "Here, we show how a BVP can be solved by treating it as a parameter estimation problem.\n", + "Essentially, this is done via a shooting method where the first boundary condition defines the initial condition of an IVP and the second boundary condition is an observation.\n", + "We use projectile motion as our example system, which we note is not specific to disease modelling scenarios, but then BVPs are not commonly useful in this domain anyway." ] }, { "cell_type": "markdown", - "id": "1cfce26c", + "id": "1908ca0b", "metadata": {}, "source": [ - "## Simple model 1\n", + "## Problem\n", "\n", - "We are trying to find the solution to the second order differential\n", - "equation\n", + "Imagine launching a ball straight up into the air from a starting height $y(t=0)=0$. Ignoring air resistance, the ball will be pulled back to it's starting position under gravity.\n", "\n", "$$\\begin{aligned}\n", - "\\frac{\\mathrm{d}^2 y}{\\mathrm{d} t^2} + |y| = 0\n", + "\\frac{\\mathrm{d}^2 y}{\\mathrm{d} t^2}=-g\n", "\\end{aligned}$$\n", "\n", - "subject to the boundary conditions $y(0) = 0$ and $y(4) = -2$.\n", - "Convert this into a set of first order ODEs\n", + "where $g$ is acceleration due to gravity. Reducing this equation to two first order ODEs in terms of position and velocity, $v$, yields:\n", "\n", "$$\\begin{aligned}\n", - "\\frac{\\mathrm{d} y}{\\mathrm{d} t} &= z \\\\\n", - "\\frac{\\mathrm{d} z}{\\mathrm{d} t} &= -|y|\n", + "\\frac{\\mathrm{d} y}{\\mathrm{d} t}&=v\\\\\n", + "\\frac{\\mathrm{d} v}{\\mathrm{d} t}&=-g\n", "\\end{aligned}$$\n", "\n", - "Here we set up the system." + "Let's suppose that the ball lands 3 seconds later (i.e. $y(t=3)=0$).\n", + "We will now solve two related BVPs in which the initial speed is unknown and later, the parameter $g$.\n", + "\n", + "## Unknown initial conditions\n", + "\n", + "First, assuming we know that the acceleration due to gravity is $g=-10ms^{-2}$, we must estimate the initial velocity ($v(t=0)$) required to ensure that the ball lands 3 seconds later.\n", + "This could be trivially solved via a quick analytical solution of the above equations resulting in $v(0)=15ms^{-1}$.\n", + "Here we focus on demonstrating PyGOM's functionality, so this value will instead serve as a target we hope to reproduce.\n", + "For some reason, PyGOM will treat model parameters as unknowns and we must specify parameters (in this case $g$) numerically in our equations:" ] }, { "cell_type": "code", - "execution_count": 14, - "id": "594a9de8", + "execution_count": 1, + "id": "f244ed16", "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}z\\\\- \\left|{y}\\right|\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[ z],\n", - "[-Abs(y)]])" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "from pygom import Transition, TransitionType, SimulateOde, SquareLoss\n", - "\n", - "import matplotlib.pyplot as plt\n", - "\n", - "stateList = ['y', 'z']\n", - "paramList = []\n", + "from pygom import Transition, TransitionType, SimulateOde\n", "\n", - "ode1 = Transition(origin='y', equation='z', transition_type=TransitionType.ODE)\n", - "ode2 = Transition(origin='z', equation='-abs(y)', transition_type=TransitionType.ODE)\n", + "stateList = ['y', 'v']\n", + "paramList=[]\n", "\n", - "model = SimulateOde(stateList, paramList, ode=[ode1, ode2])\n", + "ode1 = Transition(transition_type=TransitionType.ODE, origin='y', equation='v')\n", + "ode2 = Transition(transition_type=TransitionType.ODE, origin='v', equation='-10')\n", "\n", - "model.get_ode_eqn()" + "model = SimulateOde(stateList, paramList, ode=[ode1, ode2])" ] }, { "cell_type": "markdown", - "id": "9456e756", + "id": "9aa96bec", "metadata": {}, "source": [ - "We check that the equations are correct before proceeding to set up our\n", - "loss function. The loss function enables us to optimize the parameter choice.\n", - "\n", - "#TODO add some ref/notes for loss functions" + "We first plot an example trajectory.\n", + "Given we know that that the ball will land in 3 seconds if launched with speed $15ms^{-1}$, let's try a faster launch of $20ms^{-1}$ and the ball should still be in the air." ] }, { "cell_type": "code", - "execution_count": 15, - "id": "9ae19c03", + "execution_count": 2, + "id": "46ea09e8", "metadata": {}, - "outputs": [], - "source": [ - "import numpy\n", - "\n", - "initialState = [0.0, 1.0]\n", - "t = numpy.linspace(0, 4, 100)\n", - "model.initial_values = (initialState, t[0])\n", - "\n", - "solution = model.integrate(t[1::])" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "3952c813", - "metadata": { - "tags": [ - "hide" - ] - }, "outputs": [ { "data": { + "image/png": "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8Udc4AIAAIAKURYBAABQIcpiNdhsNv3f//2fbDab2VFcFtu4frCd6x7buH6wnese27h+OON2dpkLXAAAAFD7GFkEAABAhSiLAAAAqBBlEQAAABWiLAIAAKBClEUAAABUiLJYjtdff13R0dHy8vJSr1699O233152+fXr16tXr17y8vJSmzZtNG/evHpK2rBVZTuvW7dOFovlkseBAwfqMXHDEhcXp7FjxyoiIkIWi0XLli274jrsy1VX1e3Mvlx1sbGx6tOnj/z8/BQSEqLx48fr4MGDV1yP/bnyqrON2Zerbu7cubr66qtL784yYMAAffHFF5ddxxn2Y8ri/1i0aJFmzJihP/zhD4qPj9eQIUM0ZswYJSUllbt8YmKibrjhBg0ZMkTx8fF66qmn9Jvf/EaLFy+u5+QNS1W3848OHjyolJSU0kf79u3rKXHDk5OTo27dumnOnDmVWp59uXqqup1/xL5ceevXr9f06dO1efNmrV69WkVFRRo1apRycnIqXIf9uWqqs41/xL5ceS1bttSLL76obdu2adu2bbr22ms1btw47d27t9zlnWY/NlBG3759jWnTppV5rVOnTsaTTz5Z7vK///3vjU6dOpV57YEHHjD69+9fZxldQVW389q1aw1JxoULF+ohneuRZCxduvSyy7Av11xltjP7cs2lpaUZkoz169dXuAz7c81UZhuzL9eOpk2bGm+99Va57znLfszI4s8UFBRo+/btGjVqVJnXR40apY0bN5a7zqZNmy5ZfvTo0dq2bZsKCwvrLGtDVp3t/KMePXooPDxcI0aM0Nq1a+syZqPDvly/2JerLzMzU5IUFBRU4TLszzVTmW38I/bl6ikuLtZHH32knJwcDRgwoNxlnGU/piz+THp6uoqLixUaGlrm9dDQUKWmppa7TmpqarnLFxUVKT09vc6yNmTV2c7h4eF68803tXjxYi1ZskQdO3bUiBEjFBcXVx+RGwX25frBvlwzhmFo5syZGjx4sLp06VLhcuzP1VfZbcy+XD27d+9WkyZNZLPZNG3aNC1dulQxMTHlLuss+7F7vf2kBsRisZR5bhjGJa9dafnyXkdZVdnOHTt2VMeOHUufDxgwQMnJyfr73/+uoUOH1mnOxoR9ue6xL9fMww8/rF27dmnDhg1XXJb9uXoqu43Zl6unY8eOSkhIUEZGhhYvXqzJkydr/fr1FRZGZ9iPGVn8meDgYLm5uV0yupWWlnZJs/9RWFhYucu7u7urWbNmdZa1IavOdi5P//79dfjw4dqO12ixL5uHfblyHnnkEa1YsUJr165Vy5YtL7ss+3P1VGUbl4d9+co8PT3Vrl079e7dW7GxserWrZv+9a9/lbuss+zHlMWf8fT0VK9evbR69eoyr69evVoDBw4sd50BAwZcsvyqVavUu3dveXh41FnWhqw627k88fHxCg8Pr+14jRb7snnYly/PMAw9/PDDWrJkib755htFR0dfcR3256qpzjYuD/ty1RmGofz8/HLfc5r9uF4vp2kAPvroI8PDw8OYP3++sW/fPmPGjBmGr6+vcfz4ccMwDOPJJ580Jk6cWLr8sWPHDB8fH+Oxxx4z9u3bZ8yfP9/w8PAwPvnkE7O+QoNQ1e38z3/+01i6dKlx6NAhY8+ePcaTTz5pSDIWL15s1ldwellZWUZ8fLwRHx9vSDJefvllIz4+3jhx4oRhGOzLtaWq25l9ueoefPBBIyAgwFi3bp2RkpJS+sjNzS1dhv25ZqqzjdmXq27WrFlGXFyckZiYaOzatct46qmnDKvVaqxatcowDOfdjymL5XjttdeM1q1bG56enkbPnj3LTB0wefJkY9iwYWWWX7dundGjRw/D09PTiIqKMubOnVvPiRumqmznl156yWjbtq3h5eVlNG3a1Bg8eLCxcuVKE1I3HD9Oa/G/j8mTJxuGwb5cW6q6ndmXq6687SvJWLBgQeky7M81U51tzL5cdVOnTi39u9e8eXNjxIgRpUXRMJx3P7YYxg9nSgIAAAD/g3MWAQAAUCHKIgAAACpEWQQAAECFKIsAAACoEGURAAAAFaIsAgAAoEKURQAAAFSIsggAAIAKURYBAABQIcoiAAAAKkRZBAAAQIX+H4HuGNqfDzZXAAAAAElFTkSuQmCC", "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -141,173 +88,108 @@ } ], "source": [ - "f = plt.figure()\n", - "model.plot()" + "import numpy as np\n", + "t = np.linspace(0, 3, 100) # Time-points at which to find solutions\n", + "\n", + "theta = [0.0, 20.0] # Initial position and velocity\n", + "model.initial_values = (theta, t[0]) # Initial position, velocity and t[0]\n", + "solution = model.solve_determ(t[1::]) # Solve for subsequent timepoints\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "f, axarr = plt.subplots(layout='constrained')\n", + "axarr.plot(t, solution[:,0])\n", + "axarr.set_title(\"Height, y\")\n", + "axarr.set_xlabel(\"Time\");" ] }, { "cell_type": "markdown", - "id": "1a6de472", + "id": "5c225208", "metadata": {}, "source": [ - "\n", - "Setting up the second boundary condition $y(4) = -2$ is easy, because\n", - "that is only a single observation attached to the state $y_{1}$.\n", - "Enforcing the first boundary condition requires us to set it as the\n", - "initial condition. Because the condition only states that $y(0) = 0$,\n", - "the starting value of the other state $y_1$ is free. We let our loss\n", - "object know that it is free through the `targetState` input argument.\n", - "\n", - "#TODO unsure what this means" + "Let's now use PyGOM to solve for the initial condition that satisfies the BVP.\n", + "We use $20ms^{-1}$ as our initial guess.\n", + "It is perhaps a bit inefficient that we have to specify this initial guess twice both in the `theta` parameter and also the initial condition.\n", + "We let the solver know which variable we are solving the initial condition for by specifying the `target_state`." ] }, { "cell_type": "code", - "execution_count": 17, - "id": "aaf5a503", + "execution_count": 3, + "id": "f73ab2a2", "metadata": {}, "outputs": [], "source": [ "from scipy.optimize import minimize\n", + "from pygom import SquareLoss\n", + "\n", + "theta = [20.0]\n", "\n", - "theta = [0.0]\n", + "initialState = [0.0, 20.0]\n", "\n", "obj = SquareLoss(theta=theta,\n", " ode=model,\n", " t0=t[0], x0=initialState,\n", - " t=t[-1], y=[-2],\n", - " state_name=['y'], target_state=['z'])\n", - "\n", - "thetaHat = minimize(fun=obj.costIV, x0=[0.0])\n", - "#print(thetaHat)\n", - "model.initial_values = ([0.0] + thetaHat['x'].tolist(), t[0])\n", - "\n", - "solution = model.integrate(t[1::])" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "bffe9f2f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "f = plt.figure()\n", - "model.plot()\n", - "plt.close()" + " t=t[-1], y=[0],\n", + " state_name=['y'], target_state=['v'])\n" ] }, { "cell_type": "markdown", - "id": "472ff583", + "id": "4734f011", "metadata": {}, "source": [ - "\n", - "We are going to visualize the solution, and also check the boundary\n", - "condition. The first became our initial condition, so it is always\n", - "satisfied and only the latter is of concern, which is zero (subject to\n", - "numerical error) from thetahat.\n", - "\n", - "#TODO what is thetahat?" + "We use the {func}`costIV` function to let the solver know we are considering an initial value problem" ] }, { - "cell_type": "markdown", - "id": "85032ca8", + "cell_type": "code", + "execution_count": 4, + "id": "b70c7c06", "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: Optimization terminated successfully.\n", + " success: True\n", + " status: 0\n", + " fun: 4.987646893079144e-16\n", + " x: [ 1.500e+01]\n", + " nit: 4\n", + " jac: [ 1.122e-10]\n", + " hess_inv: [[ 5.556e-02]]\n", + " nfev: 10\n", + " njev: 5\n" + ] + } + ], "source": [ - "\n", - "## Simple model 2\n", - "\n", - "Our second example is different as it involves an actual parameter and\n", - "also time. We have the Mathieu's Equation\n", - "\n", - "#TODO add ref\n", - "\n", - "$$\\begin{aligned}\n", - "\\frac{\\mathrm{d}^2 y}{\\mathrm{d} t^2} + \\left(p - 2q \\cos(2t)\\right) y = 0\n", - "\\end{aligned}$$\n", - "\n", - "and the aim is to compute the fourth eigenvalue $q=5$. There are three\n", - "boundary conditions\n", - "\n", - "$$\\begin{aligned}\n", - "\\dot{y}(0)=0, \\quad \\dot{y}(\\pi)=0, \\quad y(0) = 1\n", - "\\end{aligned}$$\n", - "\n", - "and we aim to solve it by converting it to a first order ODE and tackle\n", - "it as an IVP. As our model object does not allow the use of the time\n", - "component in the equations, we introduce a anxiliary state $\\tau$ that\n", - "replaces time $t$. Rewrite the equations using\n", - "$z=\\dot{y}(t)$ and define our model as" + "thetaHat = minimize(fun=obj.costIV, x0=theta)\n", + "print(thetaHat)" ] }, { - "cell_type": "code", - "execution_count": 9, - "id": "afcf4558", + "cell_type": "markdown", + "id": "b603595e", "metadata": {}, - "outputs": [], "source": [ - "stateList = ['y', 'z', 'tau']\n", - "\n", - "paramList = ['p']\n", - "\n", - "ode1 = Transition(transition_type=TransitionType.ODE, origin='y', equation='z')\n", - "ode2 = Transition(transition_type=TransitionType.ODE, origin='z', equation='-(p - 2*5*cos(2*tau))*y', )\n", - "ode3 = Transition(transition_type=TransitionType.ODE, origin='tau', equation='1')\n", - "\n", - "model = SimulateOde(stateList, paramList, ode=[ode1, ode2, ode3])\n", - "\n", - "model.parameters = [('p', 15.0)]\n", - "\n", - "theta = [1.0, 1.0, 0.0]\n", - "model.initial_values = (theta, t[0])\n", - "\n", - "t = numpy.linspace(0, numpy.pi)\n", - "solution = model.integrate(t[1::])" + "We see that the target value of $15ms^{-1}$ and when plotting the trajectory below we see that the ball lands after precisely 3 seconds." ] }, { "cell_type": "code", - "execution_count": 10, - "id": "c75eea5c", + "execution_count": 5, + "id": "cc728465", "metadata": {}, "outputs": [ { "data": { + "image/png": "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crlUXFzcblkDXVs+64yMDD311FN644039Oabb6pfv346/fTTNW/evI6IHHK4tjsO17Zv2Latu+++WyeeeKIGDx7c4uu4tn3jWD9vru+2W7t2reLi4hQZGalbb71Vs2bN0sCBA4/4Wn+6rsM69N0MsSzrkB/btn3Yc0d7/ZGex+Fa81n369dP/fr1a/7xhAkTlJeXp7/97W866aST2jVnqOLa7hhc275x++23a82aNZo/f/5RX8u1ffyO9fPm+m67fv36adWqVSotLdUbb7yh6667TnPnzm2xMPrLdR3UI4udO3eW0+k8bGSrqKjosLbepEuXLkd8fVhYmFJSUtota6Bry2d9JOPHj9fWrVt9HQ/i2jaNa7t17rjjDr3zzjv6/PPPlZ2d/Z2v5do+fq35vI+E6/vYREREqHfv3ho9erSmT5+uYcOG6Z///OcRX+tP13VQl8WIiAiNGjVKc+bMOeT5OXPmaOLEiUf8NRMmTDjs9R9//LFGjx6t8PDwdssa6NryWR/JypUrlZGR4et4ENe2aVzbx8a2bd1+++1688039dlnn6lHjx5H/TVc223Xls/7SLi+28a2bdXV1R3x5/zquu7wJTUdbMaMGXZ4eLj97LPP2hs2bLCnTZtmx8bG2rt27bJt27bvvfde+9prr21+/Y4dO+yYmBj7rrvusjds2GA/++yzdnh4uP3666+b+r8QMFr7Wf/jH/+wZ82aZW/ZssVet26dfe+999qS7DfeeMPU/4WAUlFRYa9cudJeuXKlLcl+6KGH7JUrV9q7d++2bZtr25da+1lzbbfdj370IzsxMdH+4osv7IKCguZHdXV182u4tn2nLZ8313fb3Hffffa8efPsnTt32mvWrLF/+ctf2g6Hw/74449t2/bv6zroy6Jt2/Zjjz1md+vWzY6IiLBHjhx5yJYA1113nX3yyScf8vovvvjCHjFihB0REWF3797dfuKJJzo4ceBqzWf94IMP2r169bKjoqLspKQk+8QTT7Rnz55tIHVgatq+4tuP6667zrZtrm1fau1nzbXddkf6nCXZzz33XPNruLZ9py2fN9d32/zwhz9s/n5MTU21Tz/99OaiaNv+fV1btt14tyQAAADwLUF9zyIAAACOD2URAAAALaIsAgAAoEWURQAAALSIsggAAIAWURYBAADQIsoiAAAAWkRZBAAAQIsoiwAAAGgRZREAAAAtoiwCAACgRf8PwFmKu+Rd1aIAAAAASUVORK5CYII=", "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnYAAAHWCAYAAAD6oMSKAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAACQcklEQVR4nO3deXxU9bk/8M/MJDOTdbKRjQQIyI4gBIFgUSwahUr1uouNWgV/FPfUehtt69Lbm7bXa3FFbUFqEUQvrleKYmXzssgWV0BAICEkZJ/JOuv5/THzPTNDtplkzjnfc+Z5v155vcxkZvIdzEmeeb7f53l0giAIIIQQQgghqqdXegGEEEIIISQyKLAjhBBCCNEICuwIIYQQQjSCAjtCCCGEEI2gwI4QQgghRCMosCOEEEII0QgK7AghhBBCNIICO0IIIYQQjaDAjhBCCCFEIyiwI4QQQsiA7dy5E0888QRaWlqUXgoBBXaEEEIIGYSdO3fiySefpMCOExTYEUIIIYRoBAV2pFc7duyATqfDunXrun3t9ddfh06nw969exVYGSF80el0vX6cPHlS6eURIpknnngCv/rVrwAABQUF4s/91q1bsX79ehQXFyMnJwdxcXEYP348fv3rX6O9vT3oOebOnYu5c+d2e+477rgDI0aMkOFVaItOEARB6UUQfk2bNg3x8fH4/PPPg26fMWMGAOCLL75QYlmEcGX37t1Bn3d2dqKkpARutxtHjhxBcnKyQisjRFqnT5/Gn//8Zzz//PN45513kJOTAwCYMGECnnvuOSQmJmLMmDFISEjA4cOH8ac//QkjRozAZ599Jj4HC+q2bt0a9Nx33HEHtm7dSm+OwhSj9AII3+6//378/Oc/R0VFBS644AIAwN69e7F37178/e9/V3ZxhHBi1qxZ4n+73W5cd911sFqt2LZtGwV1RNPy8vIwbNgwAMDUqVODMmy/+c1vxP8WBAEXXXQRxo8fj0suuQRfffUVJk+eLPdyowJtxZI+3XLLLcjMzMSLL74o3vb8889jyJAhuOmmmxRcGSF8uvfee/HRRx/h7bffxrRp05ReDiGK+eGHH7Bo0SJkZ2fDYDAgNjYWl1xyCQDg0KFDCq9OuyiwI30ymUz4f//v/2Ht2rVoaWlBfX093nrrLSxevBgmk0np5RHClf/4j//Ayy+/jFdeeQVXXnml0sshRDFtbW2YM2cO9uzZg//4j//A1q1bsXfvXrzzzjsAvMcViDRoK5b06xe/+AX++Mc/YtWqVejq6oLL5cLSpUuVXhYhXFm9ejV++9vf4oknnsCdd96p9HIIUdRnn32GM2fOYOvWrWKWDkCPLVHMZjOsVmu32xsaGqRcomZRYEf6lZOTgxtuuAEvvfQSHA4HFi5cKJ6pIIQAmzZtwpIlS3DnnXfi8ccfV3o5hMiK7d4EZuF0Ol3Q15hXXnml2+NHjBiBt99+G3a7Xbx/Y2Mjdu7cSWdUB4ACOxKSBx54ADNnzgQAvPbaawqvhhB+nDhxAjfccANGjhyJn//8590qZKdOnUrHFoimnX/++QCAZ599FrfffjtiY2MxefJkpKamYunSpXj88ccRGxuLN954A19++WW3x5eUlOCVV17Bz372MyxZsgSNjY3485//TEHdAFG7ExKygoICxMXF4bvvvlN6KYRwY+vWrbj00kt7/fqJEyeoFxfRvEcffRR///vfUVtbC4/Hgy1btsBkMuGXv/wlvvzySyQkJODqq6/GsmXLMG3aNLz22mu44447xMe//vrr+OMf/4gTJ05g5MiRePzxx7Fx40ZqdzIAFNiRkHz11VeYMmUKXnzxRSxbtkzp5RBCCCGkBxTYkT4dP34cp06dwqOPPorKykocO3YM8fHxSi+LEEIIIT2gdiekT7///e9x+eWXo62tDW+//TYFdYQQQgjHKGNHCCGEEKIRlLEjhBBCCNEICuwIIYQQQjSCAjtCCCGEEI2IygbFHo8HZ86cQVJSktgdmxApCIKA1tZW5ObmQq9X1/souk6IXNR6ndA1QuQSzjUSlYHdmTNnkJ+fr/QySBSpqqpCXl6e0ssIC10nRG5qu07oGiFyC+UaicrALikpCYD3H4hGlhAp2Ww25Ofniz9zakLXCZGLWq8TukaIXMK5RqIysGMp8+TkZLoYiSzUuE1D1wmRm9quE7pGiNxCuUbUc5iBEEIIIYT0iQI7QqJAeXk5dDodHnzwQaWXQgghREIU2BGicXv37sWrr76KyZMnK70UQgghEqPAjhANa2trw6233oq//vWvSE1NVXo5hBBCJEaBHSEads899+AnP/kJLrvssn7va7fbYbPZgj4IIYSoS1RWxRISDd58800cOHAAe/fuDen+5eXlePLJJyVeFSGEEClRxo4QDaqqqsIDDzyANWvWwGw2h/SYsrIyWK1W8aOqqkriVRJCCIk0ytgRokH79+9HXV0dCgsLxdvcbje2b9+OF154AXa7HQaDIegxJpMJJpNJ7qUSQgiJIArsCNGgefPm4euvvw667ec//znGjRuHf//3f+8W1BFCCNEGCuwI0aCkpCRMmjQp6LaEhASkp6d3u50QQoh20Bk7QgghhBCNoIwdIVFi69atSi+BEEKIxChjRwghhBCiERTYDUCnw40up1vpZRBCFOB0e9Dc7lB6GYQQjdl1vBG2Luegn4e2YsNQa+3CX3f8gLV7KpESH4v1dxdhWHq80ssihMjE5fag+C/bcaKhHekJRozOSsQtM4bh6guGKr00QoiKtdldWPz3vfAIwEf3/wgjhyQO+LkosAvRi1uO4dlPj8Lh9gAAOq1u3LZqD/7nF7ORkUi9vwiJBicb23GioR0A0NjuQOMPTfjujA0/nZILnU6n8OoIIWr14Zdn0O5wY2RGAgoyEgb1XLQVG4LvztjwXx8fgcPtwYUjUvH8LVMxNCUOJxs78PPX9qLN7lJ6iYQQGRw92wYAmJCTjPfuuQh6HWDrcqG+za7wyggharZ2TyUA4JYZwwb9JpECuxA8s/l7AMBPJufg7aWzsXBKLv5x1wykJRjxdbUVv3yrQtkFEkJk8b0vsBufk4wL8lOQl+o9inG8rl3JZRFCVOzr01Z8XW2F0aDHdYV5g34+Cuz6UVHVgk8PnYVeB5RePka8feSQRKy640LodMDH357F6eYOBVdJCJHD0bpWAMCYLO/5l1FDvFsmPzS0KbYmQoi6rf3Cm627clI20hKMg34+Cuz68d+fHAEAXDstD6POOcx4QX4KZhakAQDerzgj+9oIIfI6VucN4Eb7Ajt2wPmHesrYEULC12Z34YOKagDAopnDIvKcFNj1Yc8PjdhxtAExeh0emDe6x/tc46uGe7+iGoIgyLk8QoiMXG6PGMCNzkwCAIz0ZeyO11PGjhASvg8qfEUTQxLERNFgUWDXhxe2HAMA3HRhPvLTem5rMv/8HBgNenx/tg2HalrlXB4hREanmjrgcHsQF2vA0JQ4ABCz+JSxI4QMxDrfNuyiCBRNMBTY9cLa4cTO440AgCVzRvZ6P0tcLH48LhOAN2tHCNGmo2e9b9xGZyVCr/f+AmYZu6rmDmpaTggJS2DRxLXTBl80wVBg14ut39fB7REwJisRI/rpKXPN1FwAwAdfnoHHQ9uxhGgRa3VyXqb/rO2QRBOSzDEQBOBUIxVQEUJCF+miCYYCu158eqgOAHDZ+Kx+7zt3bCaSzDGosXZhz4kmqZdGCFHA977CiTFZSeJtOp0uoICCztkRQkIjRdEEQ4FdDxwuD7Ye8QV2E/oP7MyxBiyYlAOAtmMJ0SpxKzYzuDp+VAYVUBBCwiNF0QRDgV0P9p5sQmuXCxmJRlyQlxLSYxZM9gZ2nx9rkHBlhBAlBFbEBmbsAGBUJhVQ8GDFihWYPHkykpOTkZycjKKiIvzzn//s8zHbtm1DYWEhzGYzRo4ciZdfflmm1ZJot/aLUwAiWzTBSBrYbd++HQsXLkRurneO4nvvvdfvY0K50DZs2IAJEybAZDJhwoQJePfddyO67k8PnQUA/HhcpnhIuj9Th6VApwNON3eivpXGCxGiJZU9VMQyI1nGroECOyXl5eXhj3/8I/bt24d9+/bhxz/+Ma6++mp8++23Pd7/xIkTWLBgAebMmYODBw/i0Ucfxf33348NGzbIvHISbb4+bcU31baIF00wkgZ27e3tmDJlCl544YWQ7h/KhbZr1y7cdNNNKCkpwZdffomSkhLceOON2LNnT0TWLAiCGNiFcr6OSTbH4jzfWZuKqpaIrIUQwofvAwonzn2zJ56xq2ujXpYKWrhwIRYsWIAxY8ZgzJgx+MMf/oDExETs3r27x/u//PLLGDZsGJYvX47x48dj8eLFuPPOO/H000/LvHISbVi2LtJFE0xMxJ8xwPz58zF//vyQ7x94oQHA+PHjsW/fPjz99NO47rrrAADLly/H5ZdfjrKyMgBAWVkZtm3bhuXLl2PdunWDXvP3Z9tQ1dQJY4wePxqdEdZjL8hPwdG6NlRUNePyEM7mEULU4Vhdz+frAGB4ejz0OqDV7kJ9mx2ZSWa5l0fO4Xa78fbbb6O9vR1FRUU93mfXrl0oLi4Ouu2KK67AypUr4XQ6ERsbK8dSSZRps7vESVW3zIhs0QTD1Rm73i60ffv2wel09nmfnTt39vq8drsdNpst6KM3LFv3o/MyEG8ML+6dOiwVAGXsCNEalrEbfc75OsBbPJWX6m1gTufslPX1118jMTERJpMJS5cuxbvvvosJEyb0eN/a2lpkZQW/Ac/KyoLL5UJDQ89npcP5W0JIT96vqEaHr2hi1sjIFk0wXAV2oVxovd2ntra21+ctLy+HxWIRP/Lz83u970C2YZkL8lMAAF9WWeGmfnaEaMZRNiO2h4wdQKPFeDF27FhUVFRg9+7d+MUvfoHbb78d3333Xa/3P/fQOttK7+0wezh/SwjpiRSTJs7FVWAHhHah9XSfvv6BysrKYLVaxY+qqqpe7/viomn4/TWTcNmEzLDXPiYrEXGxBrTZXfQLnhANqWryNh8uGNJzs3IaLcYHo9GI8847D9OnT0d5eTmmTJmCZ599tsf7Zmdnd0sI1NXVISYmBunp6T0+Jpy/JYSc66vTLZIWTTCSnrELVygXWm/3OTeLF8hkMsFkMoW0htyUOJTMGh7myr1iDHpMzrNgz4kmVFS2dGuLQAhRny6nG212FwBgSFLPv0coY8cnQRBgt/fcpaCoqAgffvhh0G2ffPIJpk+f3uv5unD+lhByLpatm3++NEUTDFcZu6KiImzevDnotnMvtN7uM3v2bNnW2ZcLhqUAAA5WNSu7EEJIRDS0eQMDo0GPJFPP74XzfWfsaq1dsq2LBHv00UexY8cOnDx5El9//TUee+wxbN26FbfeeisAb7bttttuE++/dOlSnDp1CqWlpTh06BBWrVqFlStX4uGHH1bqJRANk6NogpE0Y9fW1oZjx46Jn584cQIVFRVIS0vDsGHDUFZWhurqarz++usAvBfaCy+8gNLSUixZsgS7du3CypUrg6pdH3jgAVx88cX405/+hKuvvhrvv/8+Pv30U3z++edSvpSQTc33FlAcrGxRdiGEkIhobHMAADISjb0e+WDvvhvbHbKtiwQ7e/YsSkpKUFNTA4vFgsmTJ2PTpk24/PLLAQA1NTWorKwU719QUICNGzfioYcewosvvojc3Fw899xzYgcGQiKJFU2MkmDSxLkkDez27duHSy+9VPy8tLQUAHD77bdj9erVA7rQZs+ejTfffBO/+c1v8Nvf/hajRo3C+vXrMXPmTClfSsim+jJ2359tRbvdhYRe3uETQtSBZezSE3vfgktP9AZ2ze2Ofs/8EmmsXLmyz6+vXr26222XXHIJDhw4INGKCPFj27C3SFg0wUgadcydO7fPhp0DvdCuv/56XH/99YNdniSyks3IsZhRY+3CV6etKBrV8yFcQog6sMAuI7H3MzEsY+fyCLB1umCJpx5ohBAvsWgiRo/rJCyaYLg6Y6cVLGtH/ewIUb8G31ZsXxk7U4wBib7sfGM7jRQkhPixbN2CSdlIlbBogqHATgJT8lIAAN9UW5VdCCFk0PwZu76rIVnWronO2RFCfOQsmmAosJPA6CxvTytqfUCI+gUWT/SFCigIIecKLJqYIXHRBEOBnQRGZngDuxMN7fDQBApCVC3UjF06ZewIIeeQs2iCocBOAnmpcYg16GB3eVDd0qn0cgghg+DP2NFWLCEkdHIXTTAU2EkgxqDHiHRvJ/ofGmjEECFq5m930s9WrO/rLBAkhEQ3uYsmGArsJCKOGKqjc3aEqJXbI6CpI7SMnX8rlqpiCYl2rV1O2YsmGArsJCIOBW+gwI4QtWpqd0AQAJ0OSO2nN11agjfwo+IJQsgHX56RvWiCocBOIiNZYFdPW7GEqBXrSZcWb0SMoe9fl1Q8QQgBAEEQsHaP/EUTDAV2EhnFtmKp5QkhqtXQypoT938+hoonCCEA8HW1Fd+ekb9ogqHATiIsY3fWZkeb3aXwaki0WbFiBSZPnozk5GQkJyejqKgI//znP5VeluqE2uoECO5j19coRUKItrFsndxFEwwFdhKxxMWKDU1P0HYskVleXh7++Mc/Yt++fdi3bx9+/OMf4+qrr8a3336r9NJUxV8R239gx7J6DpcH7Q63pOsihPCptcuJD770Fk0smjlckTVQYCchlrWj7Vgit4ULF2LBggUYM2YMxowZgz/84Q9ITEzE7t27lV6aqjSEOHUCAOJiDTDFeH+lNlHLE0Ki0vsV3qKJ8zITceGIVEXWQIGdhNg5ux8osCMKcrvdePPNN9He3o6ioqJe72e322Gz2YI+ol1jGFuxOp1OLKBopJYnhEQdpYsmGArsJMRanhynJsVEAV9//TUSExNhMpmwdOlSvPvuu5gwYUKv9y8vL4fFYhE/8vPzZVwtn/xn7EI7J8OaFDd3UMaOkGjzdbUV39V4iyaunTpUsXVQYCchalJMlDR27FhUVFRg9+7d+MUvfoHbb78d3333Xa/3Lysrg9VqFT+qqqpkXC2fWE+69IT+M3ZAQC872oolJOqwbN1Pzs9RpGiCiVHsO0eBkRnejN2JhnZ4PAL0emXSsiQ6GY1GnHfeeQCA6dOnY+/evXj22Wfxyiuv9Hh/k8kEkym0ACZaNLT6MnZJof27UC87QqJTYNGE3JMmzkUZOwnlpcbBaNDD7vKguqVT6eWQKCcIAux2OvsVKkEQ0CBm7ELciqXAjpCoxEPRBEMZOwnFGPQYnh6Po3Vt+KGhHflp8UoviUSJRx99FPPnz0d+fj5aW1vx5ptvYuvWrdi0aZPSS1ONVrsLDpcHADAkxIxdYC87Qkh0EAQB675QvmiCocBOYqOGJOJoXRuO17XhkjFDlF4OiRJnz55FSUkJampqYLFYMHnyZGzatAmXX3650ktTDbYNm2iKgTnWENJjaCuWkOjz1Wn/pAkliyYYCuwkNjzDm6Wrau5QeCUkmqxcuVLpJaieWDgRYkUsQBk7QqIRy9YpNWniXHTGTmJ5KXEAgOpmOmNHiJqIhRMh9LBjWBDYRH3sCIkKPBVNMBTYSSyXBXZUPEGIqoRbOAH4253Q5AlCokNg0cSMgjSllwOAAjvJDU31BnZnKLAjRFXCbXUC+Ldi2x1udDlpXiwhWsbLpIlzUWAnsaG+jF1zhxMdDpfCqyGEhIqNBcsII2OXbI5BrMH7y50KKAjRtq9O+ydNXDdN+aIJhgI7iSWZY5Fk9taoUNaOEPVoaPUGZuFk7HQ6HVLjqTKWkGgQOGkiJV75ogmGAjsZsKzdaSqgIEQ1WMYu1HFiDFXGEqJ9PBZNMBTYyWAoFVAQojotHU4AQGp8bFiPo8pYQrTv/Yoz6HTyMWniXBTYyYAKKAhRH2unN7BLjgsvsGOVsY1UGUuIJvFaNMFQYCeDodTLjhDVYYGdJczAjqZPEKJtvBZNMBTYyYB62RGiLl1ON+y+ObHhZ+wosCNEy3gtmmAosJOBfyu2S+GVEEJCYevyZut0OiDJFN7kRXYmj53RI4RoR2DRxKKZfBVNMDQrVgZsK7bW1gWX24MYA8XThPDMxs7XmWOh14d3foZl+Frt0RPYdTndOFLbiiO1rTjV1I45o4dg1sh0pZdFSMQFFk1MH85X0QQjeYTx0ksvoaCgAGazGYWFhdixY0ev973jjjug0+m6fUycOFG8z+rVq3u8T1cXv9mwIYkmGA16uD0CzrZSpRwhvPMXToT/3pf1rbR1RkdD8mN1rZjz5y24+sX/wyMbvsKLW47j5ld3478+PgyX26P08giJGN6LJhhJA7v169fjwQcfxGOPPYaDBw9izpw5mD9/PiorK3u8/7PPPouamhrxo6qqCmlpabjhhhuC7pecnBx0v5qaGpjNZilfyqDo9TrkpHjXp8UCig6HCyUr9+DO1Xux81gDBEFQekmEDMpACycAb1NywLtlo3XWTieWvL4f9a12pMTH4qLz0nHZ+CwAwItbjmPRX/egrpXfN92EhONLzosmGEm3Yp955hncddddWLx4MQBg+fLl+Pjjj7FixQqUl5d3u7/FYoHFYhE/f++999Dc3Iyf//znQffT6XTIzs6WcukRl2uJw6nGDlS3dADgY1BwpGz/vgE7jjYAAD47XIfJeRY88dOJmDaMzzQ1If0ZTGCX7AvsbF3azth5PAIeWl+BEw3tyLWY8cF9P0JGorfVy4dfnkHZO1/ji5NNuPeNg3jz7llhb2kTwpt1nBdNMJJl7BwOB/bv34/i4uKg24uLi7Fz586QnmPlypW47LLLMHz48KDb29raMHz4cOTl5eGqq67CwYMH+3weu90Om80W9CE3LRdQ7D3ZBAAYkR4Pc6weX5224vf/+53CqyJk4Ng26sAydt73y61dTk1nr//y6ff47HAdTDF6vFIyXQzqAGDhlFy8d89sxMUa8MXJJry9v0rBlRIyeDYVFE0wkgV2DQ0NcLvdyMrKCro9KysLtbW1/T6+pqYG//znP8VsHzNu3DisXr0aH3zwAdatWwez2YyLLroIR48e7fW5ysvLxWygxWJBfn7+wF7UIORqeKwYC+weunwM3rvnIgDAt2dscNL5GqJS1oDiiXCx4gmnWxBbpmhNVVMHXthyDABQfu35OD/P0u0+52UmofTyMQCA/9x4GA1tdL6YqJcaiiYYyYsnzj1cKAhCSAcOV69ejZSUFFxzzTVBt8+aNQs/+9nPMGXKFMyZMwdvvfUWxowZg+eff77X5yorK4PVahU/qqrkf/eYl6LN6RPtdhe+PePNgE4fkYYxmUlIMsfA4fLg+7OtCq+OkIEZzFZsgtEAtuvIqmu1Zv3eKggC8KPzMnDttLxe7/fzi0ZgQk4yrJ1O/OGjQzKukJDICSyaWMRx0QQjWWCXkZEBg8HQLTtXV1fXLYt3LkEQsGrVKpSUlMBo7HsfW6/X48ILL+wzY2cymZCcnBz0ITe2Fau1JsUHKpvh9ggYmhKHoSlx0Ot1mJTrfff+TbVV4dURMjADHScGeN/MJvp632nxnJ3T7cFb+7xvjvvbkoox6FF+7fnQ6YB3D1Zjx9F6OZZISER9edqKQ76iiWs5LppgJAvsjEYjCgsLsXnz5qDbN2/ejNmzZ/f52G3btuHYsWO46667+v0+giCgoqICOTk5g1qv1HIDxopp6dzN3pPNABA0BJlty3xNgR1RKdsgMnaAPyC0abAy9rPDdahrtSMj0ShWwPZlSn4Kbi8aAQDYsP+0xKsjJPLW7jkFALiK86IJRtKq2NLSUpSUlGD69OkoKirCq6++isrKSixduhSAd4u0uroar7/+etDjVq5ciZkzZ2LSpEndnvPJJ5/ErFmzMHr0aNhsNjz33HOoqKjAiy++KOVLGbQci7fdSafTjZYOJ1IT+P/hCMXeE97zdRcW+Ct9Jw1lgZ38RSqERMJgtmIB1vKkE60azNixLanrC/NhjAktN/DL4jGYkJOM6wt737YlhEe2Lic+/LIGAHAL50UTjKSB3U033YTGxkY89dRTqKmpwaRJk7Bx40axyrWmpqZbTzur1YoNGzbg2Wef7fE5W1pacPfdd6O2thYWiwVTp07F9u3bMWPGDClfyqCZYw3ISDShoc2O6pZOTQR2DpcHB6u8GbsZI/yB3fm+wO5QjbeAIpYmbRCVGcxWLAAkB1TGaklVUwe2+7ZTb5kRehFakjkWN14of9EaIYP1/sFq1RRNMJKPFFu2bBmWLVvW49dWr17d7TaLxYKOjo5en+8vf/kL/vKXv0RqebIamhqHhjY7Tjd3ilktNfvmjBVdTg9S42NxXmaiePvwtHgkmWLQanfh6Nk2TMiV/0wjIYMx2K1Y1qRYa9MnAosmhqcnKL0cQiQlCALeUFHRBEOpFBnl+rZjz9q00cuObcNOH5EW9AOv1+swcag3mPu6ukWJpREyKKzoYcBn7DSYsRMEARsOeM/I3TKDry2p8vJyXHjhhUhKSkJmZiauueYaHDlypM/HbN26tcfxlIcPH5Zp1YR3X5624nBtq2qKJhgK7GSUmeRt4KmVETs9FU4wk/NSAFABBVEfl9uDNvsgA7s4NlZMOxm7Ew3tqLF2wWjQY974TKWXE2Tbtm245557sHv3bmzevBkulwvFxcVob2/v97FHjhwJGk85evRoGVZM1EBtRROM5FuxxC8zmWXs1N+o0+MRsO+Ur3BiRPcRaVRAQdQqsEUJmyIRLvY4LVXF7vqhEQAwdVgKzLEGhVcTbNOmTUGfv/baa8jMzMT+/ftx8cUX9/nYzMxMpKSkSLg6okZqLJpgKGMnI3/GTv2B3dnWLrR0OBGj1/V4XvDcAgpC1IIVTiQYDQMu/GETK7SUsdv9g/eNXNGodIVX0j+r1btTkJbW/1zuqVOnIicnB/PmzcOWLVukXhpRCVY0MVpFRRMMBXYyYhm7Og2csWMTNLIt5h7/+LECCofLg6Nn2+ReHiEDNtjCCSAgY6eRyROCIGDXcW/GbtZIvgM7QRBQWlqKH/3oRz22zGJycnLw6quvYsOGDXjnnXcwduxYzJs3D9u3b+/1MTzMHSfSEwQBa7/wNuG+RUVFEwxtxcpISxm76hZvcMoaL5+LFVDs/qEJ31RbqTKWqMZgW50A/qpYrWTsjte3o6HNDlOMHhfkpyi9nD7de++9+Oqrr/D555/3eb+xY8di7Nix4udFRUWoqqrC008/3ev2bXl5OZ588smIrpfwp6KqBYdqbDCprGiCoYydjFhg19TugEPlw8FZxm5oL4Ed4N+OpQIKoiaRCOyS47R1xo6dr5s2LJW783WB7rvvPnzwwQfYsmUL8vLCb4Y8a9asPsdT8jB3nEhv3RfeFic/UVnRBEMZOxmlxhsRa9DB6RbQ0GbvNdulBiywy00x93qfUUO8ve2qmnvvS0gIbwY7dQLQXsZuty+w4/V8nSAIuO+++/Duu+9i69atKCgoGNDzHDx4sM/xlCaTCSaTaaDLJCoQWDTR3yxkXlFgJyO9XochiSacsXbhrK1LI4Fd768hx/e1Wqv6zxSS6BGZwE47GTtBELDnB77P191zzz1Yu3Yt3n//fSQlJaG2thaAt+F9XJz399C5IyyXL1+OESNGYOLEiXA4HFizZg02bNiADRs2KPY6iPICiyYKVVY0wVBgJ7MhyWacsXap/pxdf2fsAP98XBYEEqIGLBgbTGDHqmLb7C54PAL0enUdvg50rK4NDW0OmGP1mJLP58ScFStWAADmzp0bdPtrr72GO+64A0D3EZYOhwMPP/wwqqurERcXh4kTJ+Kjjz7CggUL5Fo24UzQpImZ6iuaYCiwk1mWRgooQjljxwI7W5cL7XYXEkz040b4xypZWXA2ECxjJwhAm8M1qOdSGjtfVzg8FaYYPs/XCYLQ733OHWH5yCOP4JFHHpFoRUSNKqpacLi21Vs0MTX8M5q8oOIJmWUmewO7ehW3PGmzu8TtKha89STJHItEXzBXQ9uxRCX8W7EDfyNijjXAGOP99ar2c3bi+TpOt2EJiZS1vmzdTybnwBKv3jdjFNjJLDNJ/dMnWLYu2RwjHhLvDQv8aqy0HUvUQQzsBvmLPVkjvey+rPJWtRcO77/ZLyFqZety4sOvzgAAFnE2CzlcFNjJTAvzYqtDKJxgssXATr2vV40GMhSdeNk6BzcnltFCZaytyyle7xNyqBcl0a73Dlajy+nBmCz1Fk0wFNjJLItNn1DxGbtQztcxuRbvfWpaKLCT02CGokc7awTO2Hkf783Ytaq4Mvb72lYA3sy7mremCOmLIAjiNqwaJ02ci06zy2yIL2Onha3YUDJ2Ob4+d7U22oqV02CGoke7SLQ7AfwZOzW3PDnsC+zGZicpvBJCpHNQI0UTDGXsZMaKJxrb7XC51Tl94owv+zY0NYTATmx5Qhk7JYUzFD2aeTxCRNqdAP7pE2reij1c652FOi6btmGJdq3TSNEEQxk7maUnmGDQ6+D2CGhsd4hbs2oSzhm7HAs1KVZaqEPR7XY77HZ/JjkaB5y3OVxgnTMGM1IMAJJMvoydiosnjvgyduMoY0c0ytqpnaIJhjJ2MjPodchI9M6eq1Ppdqz/jF3/QamYsaOqWMWwoejr1q3r837l5eWwWCziR35+vkwr5Ie1wxuEGWP0g56JmmRWd8ZOEATaiiWa936FdoomGArsFOBveaK+LJbbI4jZt9DO2Hnv09rlQptdnX/g1Cycoeg04Dxy5+sAf8bPptLA7oy1C61dLsTodeLcZ0K0RGtFEwxtxSogU8XTJ+pb7XB5BBj0OjFA7UuiKQZJ5hi0drlQa+3EeZn0zl8OAxmKTgPO/dumkQjs1D4v9ojvfN2oIYlis2VCtERrRRMMXa0KyBRbnqgvY8fO12Unm2EIcf4lFVDI75577sGaNWuwdu1acSh6bW0tOjtpS7wvEc3YqbyP3aEa3/m6HHozRrRJa0UTDAV2CshUccuTcHrYMVRAIb8VK1bAarVi7ty5yMnJET/Wr1+v9NK4xrJrrAfdYCSpfPLEETpfRzQssGji1pnaKJpgaCtWAeK8WBVm7Pw97EKv5qUCCvmFMhSddBfJjJ1/8oQ6Azt/qxMK7Ij2BBZNTBumjaIJhjJ2CshKUu/0iXCaEzM5NH2CqERkiyfUWxXrcHnwQ713Sgn1sCNaE1g0sUhDRRMMBXYKYBk7NbY7qW4JvSKWYdMnalRYBUyiixRn7NRYPHG8vg0uj4Akc4yYcSdEKwKLJv5NQ0UTDAV2CmDVpPVtdrg96toyG9gZO19g10JbsYRvtk5vdm2wzYkBf2DX5fTA4VLXlBm2DTs+O1lz2QxCWLbuqsm5miqaYCiwU0BGohE6nbcnXFO7Q+nlhKXGd04uJ6wzdlQ8QdShVSyeGPwv+8SAAgy1nbOjxsREq6ydTvwvmzQxU5tN2CmwU0CMQY/0BFYZq55gx+n2oNnXmX9IYuj9zljGrtXuUt0fOBJd2Hm4xAhUxRr0OiQYDUHPqxbHzrYBAMZkUWNioi3vHfQWTYzNStJc0QRDgZ1ChvhanjS0qeecXbMvu6jXASnxxpAfl2CKEdtHUNaO8IxNR0mKQGAH+Ld01RbYVTZ1AACGpycovBJCIkcQBKz7gk2ayNfsMQMK7BTC5sU2tqlnK7bRF9ilxhtDbk7MsGKLMxTYEY6xACwpAlux3udR3/QJQRACArt4hVdDSOQcqAwompimvaIJhgI7haQn+AK7dvVk7Nh5wLSE0LN1TDYVUBAVYAFYoilCGTsV9rKra7XD7vLAoNeFVf1OCO9Ytu6qybkRqXznFQV2Ckn3nVFTU8aObRunJ4Yf2LFzdrUqOlNIoosgCOJWbCQmTwCBGTv1bMWybF1uihmxBvoTQbQhGoomGMmv2pdeegkFBQUwm80oLCzEjh07er3v1q1bodPpun0cPnw46H4bNmzAhAkTYDKZMGHCBLz77rtSv4yIY8FRg4oCO5axY4Uf4chQYSBLoku7ww02sCNyW7G+XnYqGit2qtEb2A1Lo21Yoh2saEKLkybOJWlgt379ejz44IN47LHHcPDgQcyZMwfz589HZWVln487cuQIampqxI/Ro0eLX9u1axduuukmlJSU4Msvv0RJSQluvPFG7NmzR8qXEnEZvuAoWrZi2WPU1t6FRA+2XWrQ62COjcyvRjZ9Qo0Zu2FpVDhBtCGwaEKLkybOJWlg98wzz+Cuu+7C4sWLMX78eCxfvhz5+flYsWJFn4/LzMxEdna2+GEwGMSvLV++HJdffjnKysowbtw4lJWVYd68eVi+fLmULyXi0lVYPMGyiwPZimVbz2qqAibRpa3LXxEbqV/8iSZvxq7drqLArtE7SowydkQrgoomNDhp4lySBXYOhwP79+9HcXFx0O3FxcXYuXNnn4+dOnUqcnJyMG/ePGzZsiXoa7t27er2nFdccUWfz2m322Gz2YI+lOY/Y6eeQKfJl11MH0DGLp0ydoRztq7ItjoBgEST902pqgI7qoglGhNUNKHBSRPnkiywa2hogNvtRlZWVtDtWVlZqK2t7fExOTk5ePXVV7Fhwwa88847GDt2LObNm4ft27eL96mtrQ3rOQGgvLwcFotF/MjPV/7gJAt0GtodEAR1jBXzb8WGf8ZOzFBSYEc41SpWxEbuFz+rrm1VYWBHGTuiBcFFE8MUXo08IvfWtBfnbmkIgtDrNsfYsWMxduxY8fOioiJUVVXh6aefxsUXXzyg5wSAsrIylJaWip/bbDbFgztWTOBwedBmd0XssLaUGgexFcvO2DV3OOD2CGH3wSNEapFuTgx4m3MD6snYtdtd4pGLfArsiAYET5pIUXo5spAsY5eRkQGDwdAtk1ZXV9ct49aXWbNm4ejRo+Ln2dnZYT+nyWRCcnJy0IfS4owGcdyQWs7ZNYpVsQMI7HyTKgTBG9wRwhvWnDhSrU4Af8auTSXFEyxblxIfq+k+XyQ6BBVNzNR+0QQjWWBnNBpRWFiIzZs3B92+efNmzJ49O+TnOXjwIHJycsTPi4qKuj3nJ598EtZz8kI8Z6eCylin2wOrr2XDQKpiYwx6pPjONtA5O8IjthUbyew5mznbppKMHW3DEi1hRRPmWD2umTpU6eXIRtKt2NLSUpSUlGD69OkoKirCq6++isrKSixduhSAd4u0uroar7/+OgBvxeuIESMwceJEOBwOrFmzBhs2bMCGDRvE53zggQdw8cUX409/+hOuvvpqvP/++/j000/x+eefS/lSJJGeaERlU4cqetkNdE5soLQEI1o6nN4MZehJW0JkwbJqkZo6AQRsxTpUEthRDzuiIWv3RMekiXNJGtjddNNNaGxsxFNPPYWamhpMmjQJGzduxPDhwwEANTU1QT3tHA4HHn74YVRXVyMuLg4TJ07ERx99hAULFoj3mT17Nt5880385je/wW9/+1uMGjUK69evx8yZM6V8KZJgjX7VsBU7mDmxTEaCCT/Ut6siQ0mijzRVserciqXAjqidtcNfNHHLjOgommAkL55YtmwZli1b1uPXVq9eHfT5I488gkceeaTf57z++utx/fXXR2J5isoQe9nxH+gMpjkxQ02KCc9axcAu8lWx7XZ3xJ5TSqeo1QnRiHcPnobdFV1FEwwNAlSQmlqADGZOLKPGMWokerTZfe1OJKiKdbg9sLv4D+6qfIEdVcQSNfMWTVQBiK6iCYYCOwWxrVg1TGMYzJxYxt+kmP/XS6KPFFWxrPId4D9r5/YION1MW7FE/Q5UNuPI2egrmmAosFOQmsaK0VYs0bpWCc7YxRj0iItVx/SJGmsnnG4BsQYdcixxSi+HkAFbu8ebrYu2ogmGAjsFZaio3clg5sQy/nmxFNgR/rCWJJGcPAH4t2N5b3nCCifyUuOpgThRrWgummAosFOQujJ2A58Ty9C8WMIzfx+7yNaUsXmx3Ad21OqEaAArmhiXHX1FEwwFdgpi59WafGO2eMaCz4HMiWXEhswqOFNIoo8U7U4A9TQprhQLJ2gblqhTYNHELTOir2iCocBOQanxsdDp1DFmSyyeGMRWLDtj19LphMvtici6CIkEu8sNh8v7M5kU6a1YozrmxdZauwAAQ1MoY0fUKdqLJhgK7BQUY9AjNV4d27GDmRPLBAeyzkgtjZBBC2wgHMl2J4B6mhTX+AK7bMvAs/KEKCnaiyYYCuwUxgIlnrcnBzsnlokx6JESR/NiCX9YRWyC0RDxwgG1bMWetfkCu2TaiiXqE1g0sWhmdBZNMBTYKUxs2stxoBOJObEMCwzVUAlMogcLuiI5dYJJUMH0CUEQxIxdjsWs8GoICV9g0cTU/BSll6MoCuwUpoaCgkjMiWX8r5ffQJZEH1tX5KdOMOJWrJ3f4we2Thc6nd7AM5sCO6IygiBg7RfeufPROGniXBTYKSwjgf8zdo0R6GHHUMsTwiMpmhMz/sCO34xdrW8bNiU+FuZYQz/3JoQvByqb8f3ZNphj9bj6gugtmmAosFOYv2kvzxk779oGc76O8ffu4/f1kujT1iX9VizPZ+xqrJ0AgOxkdWbrysvLceGFFyIpKQmZmZm45pprcOTIkX4ft23bNhQWFsJsNmPkyJF4+eWXZVgtibQ39nizdQujvGiCocBOYeIZO44zdpGYE8uwPniNGsnYCYKAJz/8Fiu2Hkeng9+MDOmb2JzYJEXGjv+RYrUqP1+3bds23HPPPdi9ezc2b94Ml8uF4uJitLe39/qYEydOYMGCBZgzZw4OHjyIRx99FPfffz82bNgg48rJYFk7nPjoqxoAwC1RXjTBRP63GAlLegL/Y8Wk2Irlees5HC0dTrz2fycBAHf+aISiayEDJ+1WrDeDwHfGjrU6UWdgt2nTpqDPX3vtNWRmZmL//v24+OKLe3zMyy+/jGHDhmH58uUAgPHjx2Pfvn14+umncd1110m9ZBIh71DRRDeUsVNYhgrGirHsWiS3YrVyxu5sq/cPYlqCEaYYOpukVv6q2MgHdglspBjHfey01urEarUCANLS0nq9z65du1BcXBx02xVXXIF9+/bB6eS30IX4eSdNUNHEuShjpzA1VMVGYk4so7V2J2dt3teRmURNXdWMjRNLjPDUCe9z+tqdOPgN7LTU6kQQBJSWluJHP/oRJk2a1Ov9amtrkZWVFXRbVlYWXC4XGhoakJOT0+0xdrsddrv/d5fNZovcwknYqGiiZ5SxUxjLYLU73Nye0fJvxQ4+eMlI1NYZO5bpyOLw0Pn27duxcOFC5ObmQqfT4b333lN6SdwSz9hJsRVr5n+kWK3Kt2ID3Xvvvfjqq6+wbt26fu97boZHEIQeb2fKy8thsVjEj/z8/MEvmAwYFU30jAI7hSWZYmA0eP838JrFYnNsU+IHf+GI82I7tDEvtk4M7PjL2LW3t2PKlCl44YUXlF4K9yTdivXNim3leCtWrIpVeWB333334YMPPsCWLVuQl5fX532zs7NRW1sbdFtdXR1iYmKQnp7e42PKyspgtVrFj6qqqoitnYSHiiZ6R1uxCtPpdEhNiMVZmx3N7U7kpSq9ou7YOLHUQU6dYM/B5sU2dTiQmaTuPyT+rVj+Xsf8+fMxf/58yZ5fEATNnGmRo4+d3eWBy+1BjIGv99MdDpe4Fa3WwE4QBNx333149913sXXrVhQUFPT7mKKiInz44YdBt33yySeYPn06YmN7fhNrMplgMvH3Ji4aUdFE7/j6DROlWMDU1MHf9qQgCGjp8AZ2kcjYGfQ6/+vVwHbsWY4zduGy2+2w2WxBHz35ptqK+c/uwDUv7ZR5hdLxb8VK18cO4HOsGNuGTTAaJGn3Iod77rkHa9aswdq1a5GUlITa2lrU1tais7NTvE9ZWRluu+028fOlS5fi1KlTKC0txaFDh7Bq1SqsXLkSDz/8sBIvgYSBiib6RoEdB9j2ZDOHgU67ww2Xx3vuJCVu8Bk7IKCAguNK4FCdbfVl7Dg8YxeuUM8PWeJicajGhu/OWOFwqX87HQhsUBz5wMYYo4cxxvurtpXDsWKB5+vU+gdyxYoVsFqtmDt3LnJycsSP9evXi/epqalBZWWl+HlBQQE2btyIrVu34oILLsDvf/97PPfcc9TqRAWoaKJv6nx7pjGpHI/ZavFlEY0xephjI/M+ID3BiGPQRgFFPcfFE+EqKytDaWmp+LnNZusxuMtLjUOSKQatdhd+aGjDuOxkOZcpiVaxKlaaX4mJphg0uRx8Zuxs6i+cYEUPfVm9enW32y655BIcOHBAghURKVHRRN8oY8cB1kakmcOtWHEbNi42Yu/m/QUU/L3ecHg8Aup8GTstbMWaTCYkJycHffREp9NhXE4SAOBQjfrbPXg8Atoc0o0UAwLnxfJXQCE2J9ZIDzuibVQ00T8K7DjA85kzVjgRifN1DHuu5nb+tqXC0dThgMsjQKfzt3GJFixLd6imVeGVDF67wwWW8JFiKxbge16s2seJkehCRRP9o61YDqSpImMXmfN1AJDiC2RbOvl7veFghRPpCSbEclbpCABtbW04duyY+PmJEydQUVGBtLQ0DBs2uHe643NYYKf+jB3bhjUa9DDHSjM9hOd5sSxjl0WBHeEcFU2EhgI7DnB9xs4XfFkimbHznYlgQaNa1dn43obdt28fLr30UvFzdn7u9ttv7/G8UTjGi1ux6s/YiefrJMrWAXxvxbI3KDkaOCdKtG3/KW/RRFysAddMpaKJ3lBgx4E0jrdiA8/YRQrbelb7GTuep04AwNy5c0M6VD4QY7OToNMBDW121LfaMUTFI9Xa7NJNnWDErVgOmxTXaGjqBNG2tb5s3cIpOUiW6DysFvC3fxSFUhO8P6BNHJ45s0lwxo5l/5pVnrE7y3nGTkrxxhiMSE8AoP7tWJuErU4YcV4sZxk7h8uDBt+cajpjR3gWVDQxg4om+kKBHQcCz9hJlWEZKH9z4sidsdNMxq7Vm+ngceqEHMZrpDJW6lYngc/N21Zsne9n2GjQi7+HCOERK5oYn5OMC6hook8U2HGABTpujyBmD3ghnrGL6Fas74xdp7ozdnWcb8VKbXy2Ngoo/M2Jpdva4bUqtlYsnDDRQXTCLUEQsNbXu27RjHz6We0HBXYcMMcakGD0Vs3xNn2CZewiGdixrVhrpxNuD18ZynBoqYfdQLDK2MO16i6g8I8Ti76tWHa+Lod62BGO7TvVjKN13qKJq6lool8U2HFCrIzlbHtSkj52vtYpguD/o6pGvBdPSI01KT5W1wa7i7+JCqFiW7FSzkllFbe8ZezYz3BmlL45Ieqwbg8VTYRD8sDupZdeQkFBAcxmMwoLC7Fjx45e7/vOO+/g8ssvx5AhQ5CcnIyioiJ8/PHHQfdZvXo1dDpdt4+uri6pX4qkeJ0XK0UfO2OM3p+hVGkBhdsjoJ7NiVVxRehgDE2JQ7I5Bi6PgGN1bUovZ8BYsBWNW7ENvnnNaq5qJtrW0uHA/37tLZpYNHO4wqtRB0kDu/Xr1+PBBx/EY489hoMHD2LOnDmYP39+0CDmQNu3b8fll1+OjRs3Yv/+/bj00kuxcOFCHDx4MOh+ycnJqKmpCfowm9WdNWHn7Hibn8rO2EUyY+d9PnUXUDS22eERAL0OSI+yqROMd7SY+idQyNPHjjUo5iuzyd6cRNvkFKIe7xyohsNXNDElz6L0clRB0j52zzzzDO666y4sXrwYALB8+XJ8/PHHWLFiBcrLy7vdf/ny5UGf/+d//ifef/99fPjhh5g6dap4u06nQ3Z2tpRLlx2PGbsupxtdTg+AyDYoBryBYnVLp2qbFLNWJ0OSTDDoo/cg74ScZHxxogmHVVxAIc8ZO+/1w1/Gzv9zTAhvaNLEwEiWsXM4HNi/fz+Ki4uDbi8uLsbOnTtDeg6Px4PW1lakpaUF3d7W1obhw4cjLy8PV111VbeMnhqJ82I5ymCx83UGvS7i54/Y6+VxjFooov18HTMu29fypFa9gR0LtqRsd5Lgy9jxFtixjN0QytgRDgUVTVyQq/RyVEOywK6hoQFutxtZWVlBt2dlZaG2tjak5/jv//5vtLe348YbbxRvGzduHFavXo0PPvgA69atg9lsxkUXXYSjR4/2+jx2ux02my3ogzdpvibFPGXsAitiI/1OiW3tqjZjF+U97Bi2FXukVr1n7NhWrJSHsnmtiqWMHeEZK5r46ZRcKpoIg+TFE+cGBIIghBQkrFu3Dk888QTWr1+PzMxM8fZZs2bhZz/7GaZMmYI5c+bgrbfewpgxY/D888/3+lzl5eWwWCziR35+/sBfkETSEry/WHmaPsHOv0VynBjjD+z4CWTDEc1TJwKNzkwE4A0QeByJFwoxYydDu5MOh5ubFj9ujyCe6aXAjvCmpcOBj3xFE7fMpEkT4ZAssMvIyIDBYOiWnaurq+uWxTvX+vXrcdddd+Gtt97CZZdd1ud99Xo9Lrzwwj4zdmVlZbBareJHVVVV6C9EJmLGjqNAhzUQjvT5OiBg+oRKmxRHe3NiJsEUg7xUbw+078+qs4CCnbGTdivW/9ztDj6yds0dDjHIpKkThDfvHKgWJ01Q0UR4JAvsjEYjCgsLsXnz5qDbN2/ejNmzZ/f6uHXr1uGOO+7A2rVr8ZOf/KTf7yMIAioqKpCTk9PrfUwmE5KTk4M+eCOeOeMo62EVW51EPrBjDY/V2u4k2psTBxqT5T1np97ATvpZsaYYPWJ8RTa8bMeybdi0BCNiDdTSlPBDEASs/YImTQyUpFWxpaWlKCkpwfTp01FUVIRXX30VlZWVWLp0KQBvJq26uhqvv/46AG9Qd9ttt+HZZ5/FrFmzxGxfXFwcLBZvxP7kk09i1qxZGD16NGw2G5577jlUVFTgxRdflPKlSC6NwwbF/lYnkX83r/Z5sf7GrtGdsQO8gd1nh+tUGdg5XB7YXd7K7ySTdGd4dDodEs0xaOlwekeYcZCA8Lc6oWwd4cu+U804RpMmBkzSwO6mm25CY2MjnnrqKdTU1GDSpEnYuHEjhg/3NhmsqakJ6mn3yiuvwOVy4Z577sE999wj3n777bdj9erVAICWlhbcfffdqK2thcViwdSpU7F9+3bMmDFDypciOTZ5oqXDCZfbgxgO3kFLMU6MUX3xhC26mxMHGpPlPWf3vQoLKAKrVFnlqlQSjL7AjrOMHZ2vI7yhoonBkTSwA4Bly5Zh2bJlPX6NBWvM1q1b+32+v/zlL/jLX/4SgZXxJXC7s6XTyUXD0BYJxokxYoPiTvVl7FxuDxrb2VYsZezErdi61pCLo3jR5tuGjTcaJH8z5a+M5aNJMTUnJjwKnDRBRRMDo3xaiAAAYgx6/7kzTs7ZSXnGLpVl7DiqAg5VQ5sDggDE6HVIk2CbWm3Oy0yEXufNvrJgQS1sMhROMP55sXz8zIvjxCiwIxyhSRODR4EdR8RzdpwEdlKesWPP2Wp3wen2RPz5pVTn62GXkWiCPoqnTjDmWAOGpycAAL4/q67tWP+cWOkDO/+8WM4ydrQVSzhBkyYigwI7johjxTgpKBDP2EmwFRt4bs+qspYn4vk6qogVsX52R1RWQNEmzomV/hyPf14sZ2fsKGNHOEGTJiKDAjuOiGPFONmebJFwK9ag1yHZlyVRW2VsHU2d6Gasb7TYUZUFdq2+bdFIj8zrSYKRZez4COzEcWKUsSOcWOsrmlg4JYeKJgaBAjuO8Nak2CoWT0hzjiywElhN6ihj181olfaya5Ohhx3j34rlK7Cj4gnCg8BJE4tmDld4NepGgR1HUjk6Y+d0e8Q/QFJk7AKfV21NillzYmp14jc2i2Xs2iAIfIzMCoWNbcXKUTzB0bxYl9sj9sykjB3hwQYqmogYCuw4khbPT2BnCzj3lixVYKfSJsX1tBXbTUFGAmL0OrTaXaixdim9nJDJMSeW4Slj19TurezW62icGFEeFU1EFgV2HOEpY8d62CWbY2CQqPIzVaVNiqk5cXfGGD0KMryVsWoqoPBvxUZX8US9OE7MJNn1TUiogiZNUNHEoFFgxxGWsePhjJ1YOCFhn7YUjl5vOMTiCTpjF2RMlvoKKFq7ZCye4KhBMY0TIzxZS5MmIooCO46kJfKTsbOKPeyku8jEsWIqanfi9ghiY1eaOhGMBXZHVDRaTJk+dspn7MTmxJR1JgoLLpqgSRORQIEdR3g6YyflnFiGFU+o6YxdU7sDbo8AnQ5Ip7NJQUb7ZsYer1dPYCcWT8gQ2PFUPCG2OqGKWKIwVjQxIScZk6loIiIosOMI62PX4XDD7lJ2u0aOrVg1tjth27DpCSbJZ4uqzagh/sBOLZWxbTJWxSbwGNhRxo4oiIompEF/mTiSFFCooHSww7ZHpWp1AgSesVNRYEeFE70anh4PvQ5o7XKpZmasfytWvuIJPrZiqYcdUd7ek96iiXgjFU1EEgV2HNHrdWIgpfR2rNW3PSrHVqxVRVuxVDjRO3OsAflp8QCAYyrZjhWLJ2Q8Y9fucCue0aSMHeHB2j2nAHiLJuR4cxUtKLDjDCsoULpSVMzYSVg8kUoZO83xb8e2K7yS/gmCoEjxhNsjwO7ySP79+iLOiaWfY6KQ5nYHNn5TCwC4ZQYVTUQSBXacSePk3Bn7/lI1JwYAiy9o7HS60eVUvgVEKNjUCaqI7dmoId5edsfr+M/Y2V0eON3ezJksZ+yM/u+h9HZsPW3FEoVtOHAaDpcHE3OpaCLSKLDjTAonlbFsTqyUW7GBzY+tKml5Im7FUqajR+dlqqcyttVXOKHTBQddUjHodYg3Kt+k2OHyiG/cKGNHlBBYNHHLDCqaiDQK7DiTxsmYLZsMxRM6nU4MHJXeeg4VmzoxhMaJ9Yhtxf6ggq1YcZyYMQZ6maYv8NDLrrHd+zNsCDjTS4ic9p5sxvH6diqakAgFdpxJSWDFE8pmsMSMnYRn7ICAM4UKv95QsUPnVDzRMxbYVbd0ctHWoy+scEKOHnZMIgfTJwKnTsgV0BISiIompEWBHWdSOcjYCYIgy1YsEFAZq4KtWEEQ/IEdbWH1KDXBKJ4TPdHAd9ZOzh52TAIH82IbfVMn0hPoZ5jIj4ompEeBHWd4mBfb4XDD5fEeKpc8sPO9XjbCjGctHU443N5qRrWcTXrppZdQUFAAs9mMwsJC7NixQ/LvKRZQcH7Ojk2dkKMilmFn+ZTcimUVsek0J5Yo4J2D1VQ0ITEK7DjDtiabFKyKZdmzWIMOcbEGSb+XmjJ2rCI2NT4Wphhp/10iYf369XjwwQfx2GOP4eDBg5gzZw7mz5+PyspKSb+v2PKE88pY8YydjFtBPIwVY4VZNBKPyE0QBHEbloompEOBHWf87U6Uy2AFbsNKfeEli/Ni+Q/sztpYRaw6CieeeeYZ3HXXXVi8eDHGjx+P5cuXIz8/HytWrJD0+/orY3nfipWvOTHDQ/EEC+zSaCuWyIyKJuRBgR1neGh3wgI7KXvYMSxD2aKijJ0aCiccDgf279+P4uLioNuLi4uxc+dOSb934MxYnrF2J0mynrFTvniikWXsaCuWyIyKJuRBgR1nUn2BTmuXCy63Mt3p5SqcAALHiqkhsPNm7NRwvq6hoQFutxtZWVlBt2dlZaG2trbHx9jtdthstqCPgRBbnjS0w+1RdnRWX8StWBkDOzYvtt2hfMZOa1ux27dvx8KFC5GbmwudTof33nuvz/tv3boVOp2u28fhw4flWXCUoaIJ+VBgxxnv9qf3v5XKYska2LEqYBUUT/jHialjKxZAt610QRB63V4vLy+HxWIRP/Lz8wf0PYemxsEYo4fD5cHp5o4BPYcc/MUT8mUOeNiKbRS3YrUV2LW3t2PKlCl44YUXwnrckSNHUFNTI36MHj1aohVGN5o0IR/53qqSkMQY9Eg2x8La6URzu0ORkT82GQM71idPDWfs1NTqJCMjAwaDoVt2rq6urlsWjykrK0Npaan4uc1mG1BwZ9DrMDIjAYdrW3G8vg3D0xPCfg45+IsnlOhjp2TGTptVsfPnz8f8+fPDflxmZiZSUlIivyAiokkT8qKMHYfYO+lmhYIdJbZi1RDYseIJNcyJNRqNKCwsxObNm4Nu37x5M2bPnt3jY0wmE5KTk4M+BmqUr4DiGMeVsWLxhCJn7JTvY0fFE15Tp05FTk4O5s2bhy1btvR530gdV4g2X5xooqIJGVFgxyGx5YlCBRRKbMXaqHgi4kpLS/G3v/0Nq1atwqFDh/DQQw+hsrISS5culfx7j8rwZul4blLcqkQfO4W3YrucbnQ4vIUbWtuKDVdOTg5effVVbNiwAe+88w7Gjh2LefPmYfv27b0+JlLHFaINy9ZdfQEVTciBtmI5pPT0CTkDO/Y9Wu0uON0exBr4fK8hCIJYPKGGrVgAuOmmm9DY2IinnnoKNTU1mDRpEjZu3Ijhw4dL/r1HqCCwU2Yrlk2eUKYqlp2vizXokCzj6+bR2LFjMXbsWPHzoqIiVFVV4emnn8bFF1/c42MidVwhmlDRhPyi+8rmVGo8H1uxcrQ7CfzjYut0Il2BM4WhaLW70OX0VimrqXhi2bJlWLZsmezflwV2Jxv4LZ5oVaJ4wqjsVmxTm79wgs45dTdr1iysWbOm16+bTCaYTHz+juIVK5qYNDQZk/NSlF5OVOAzPRLlWMsTpcaKyZmxizHoxa0wnnvZsYrYJFMM4oz8T51QWoGvYKLW1oVOh3I92/rS6jtjJ++sWGW3Yht9hRN0vq5nBw8eRE5OjtLL0AxBELA2oGiCyIMydhxKZcUTUXDGDvCeKWztcnFdQCH2sFPJ+TqlpSYYYYnzVnefbGzH+JyBF2JIQRAEMbiS84yd0lWxWu1hBwBtbW04duyY+PmJEydQUVGBtLQ0DBs2DGVlZaiursbrr78OAFi+fDlGjBiBiRMnwuFwYM2aNdiwYQM2bNig1EvQnC9ONOEHsWhiqNLLiRqSZ+zCHUK+bds2FBYWwmw2Y+TIkXj55Ze73WfDhg2YMGECTCYTJkyYgHfffVeq5SvCvxWrTGAnZ7sTAEiJ875eK8e97NTU6oQXPJ+z63C4wXonK1E80e5ww6NA8+YmjfawA4B9+/Zh6tSpmDp1KgBv8dDUqVPxu9/9DgBQU1MTNCfZ4XDg4YcfxuTJkzFnzhx8/vnn+Oijj3Dttdcqsn4tWhtQNCFnZjzaSRrYhTuE/MSJE1iwYAHmzJmDgwcP4tFHH8X9998f9A5q165duOmmm1BSUoIvv/wSJSUluPHGG7Fnzx4pX4qs/Fux8mewBEFQJGMH+DOFPFJjc2KljeQ4sGPZOoNeh7hY+bbWA/+4KTF9QqvNiQFg7ty5EASh28fq1asBAKtXr8bWrVvF+z/yyCM4duwYOjs70dTUhB07dmDBggXKLF6Dmtsd+OfX3qKJRTOkL9gifpIGduEOIX/55ZcxbNgwLF++HOPHj8fixYtx55134umnnxbvs3z5clx++eUoKyvDuHHjUFZWhnnz5mH58uVSvhRZiVuxCmTsOp1uON3eTIJcgZ1FBb3s1FYRy4MR6ayAgr/ALvB8nZxFBOZYPfS+b6dEZWxjm685sQYDO8KXDQdOw+H2Fk2cT5MmZCVZYDeQIeS7du3qdv8rrrgC+/btg9Pp7PM+Ug82l5O4FavAGTuWNYvR6xAvU5GAOgI7dfWw48GIjHgAwMlGHgM7+efEAt4Rb0oWUIhn7DitPifaQEUTypIssBvIEPLa2toe7+9yudDQ0NDnfXp7TkB93cJTE/xbk3IPUQ/chpUrk0FbsdpUIG7F8tfyRInCCUbJAgotb8USfuyhoglFSV48Ec4Q8t7uf+7t4T6n2rqFs2ICjyD/RAZrh7zn6wD/61WqIXMoaCs2fKx4oqHNLm598kKJqROMkmPF/Bk7CuyIdNZR0YSiJAvsBjKEPDs7u8f7x8TEID09vc/79PacgLdbuNVqFT+qqqoG8pJkY4zRixeD3Ofs5GxOzFh8GTuu+9jRVmzYks2x4lmuU418Ze3aFNqKBZTtZRfYoJgQKTQFFE3QNqwyJAvsBjKEvKioqNv9P/nkE0yfPh2xsbF93qe35wQiO9xcLmw7Vu7KWLkrYgEghfMzdl1Ot5jhGUJbsWEp4LQy1ubLICoxt1IcKyZzVazd5UarL5ik4gkilXcCiiZo0oQyJN2K7W8IeVlZGW677Tbx/kuXLsWpU6dQWlqKQ4cOYdWqVVi5ciUefvhh8T4PPPAAPvnkE/zpT3/C4cOH8ac//QmffvopHnzwQSlfiuyUKqBQJLDzvVa5t51Dxc7XmWL0UT9fM1y89rKz+QL15DgFMnZGlrGTtyq2ud17fRn0OiTTIHYigcCiCWpxohxJf6v1N4T83IaRBQUF2LhxIx566CG8+OKLyM3NxXPPPYfrrrtOvM/s2bPx5ptv4je/+Q1++9vfYtSoUVi/fj1mzpwp5UuRnVJNipUI7MSqWF4DO3a+LtlE8zXDVJDBZ8sT9iZCmYydMmfs/OPEjNDr6eeYRB4rmkgwGvDTC3KVXk7Ukvztal9DyFnjyECXXHIJDhw40OdzXn/99bj++usjsTxuKTUvVpmMHduKdcDjEbj7oyOer6Nt2LCxXnYnOGt5wrbWlchcKVU80dim3XFihA+saOKnFwylogkFSV4VSwYmRczYaf+MHfteHgFoU6Abf3/qbFQRO1BiLzveMnbiGbvoKZ7Q8jgxorymoEkTVDShJArsOMV++crdAkSJwM4ca4A51vujaOWwgKKO5sQOGMvYNXc4ufp/y9qvyFn9zYjFE7JvxVJgR6TDiibOH2qhSRMKo8COU2wrtkmh4gm5/+D5e9nx88ef8bc6oa3YcCWYYpDlaxHD03asrZOHPnbyFk80tdM4MSKNwKKJm2fw3Sc2GlBgxyn/vFjtb8UCAefsOvlrUswCuyGUsRsQHmfGttp9b2AULJ5QbiuWfo5JZAUWTdCkCeVRYMcppdqd2BQK7Nj343GsGJ2xGxwW2PHUpJhl7CwKtDtRrCq2jaZOEGms3UNFEzyhwI5TqQoUTwiC4M/YxSsT2PG4FVtPVbGDMizdW0BxqomPjJ0gCOIZOyXanShdPEFbsSSSmtod2PQNFU3whAI7TvknTzjEeblS63S64XR7v5dSW7G8Zeycbo946JzGiQ3MsDRvYFfJScau3eGGx3dJKdruROYKcKqKJVLYsJ+KJnhDgR2nWMbO7RHELvlSY0GVQa9DgtEgy/dkWHsXuauA+9PQ5s3Wxeh1SIunP4gDMdyXsats4iOwY9m6GL1OrMaWU6JCxRPsZ5m2YkmkCIIg9q6jubD8oMCOU+ZYA+J9wZVcwU5g4YTcExZ43Yo96xsnlpFo4q5xslqwjF1dqx2dDnmDmZ6w83XJCvycA0CCr92JnFuxTrdHfINIxRMkUnb/0IQfGmjSBG8osOMYy9rJ1fKE9RmTexsWCKyK5SuwEwsnaBt2wFLijeKMXR6ydq0KNicG/Bk7h8sDp9sjy/dkRVh6HZCiwPVNtMk/aSKXiiY4QoEdx9IS5J0Xq1QPO8Dfx463M3Y0TiwyhnG0HcumTihxvg7wn7ED5KuMbfL9DkmNpzmxJDKCiyaGK7waEogCO46xLFZzuzzBjlI97AK/J0/TCYDA5sSUsRuM4Wms5YnylbFsTqxSGbtYgx7GGO+vXrm2Y6lwgkQaFU3wiwI7jimVsVN2K5av4on6VuphFwlcZew6lc3YAfIXULA3h6kU2JEIoKIJvlFgxzG5z9ixP3hKnMHhtXiizkZbsZEgtjzhIbBTOGMHyF9AwbZiqbKbRAIVTfCNAjuORWPGzu7yoMupfOUk4z9jRxm7wRjOUS878YydgkUEiSbv95YtsPNNnaCMHYkEf9EETZrgEQV2HEuV+Ywdq0hNkXnqBODdmjL4DnXLFciGos63FZuVTBm7wWBbsaebO+H2yNNwuzdKn7EDgCSZx4qxayotgSpiyeAEFk3cOpO2YXlEgR3H2LvrJpkCnRYF253odDpxC5iX7Vi3R/CPE6PiiUHJscQh1qCDw+1Bra+FjFK4OGPnCypZ6xWpseMcqbQVSwYpsGhi0lAqmuARBXYcY+dhmuXqYydm7JT55S8WUHAS2DW22+ERAJ2O5msOlkGvQ16qb2aswpWxPJyxY9tXrTJNlfFn7OjnmAxcYNHEIsrWcYsCO46lKnTGTomtWO/35WusWF3A1IkYA10qg5XvO2dXpXABRSsPZ+x8QSW1OyFqElg0sXAKFU3wiv5acYxtmzR3OCEI0p9LYgGVEluxgP9MIS/TJ+qo1UlEsQKKUwoXUPCwFcvO2LXJlbGjwI5EwFoqmlAFCuw4xjJnbo8gbh9JxeMR/Bk7hQK7lHh5M5T9YRk7KpyIjOG+AopTimfslN+KTZIxYycIAhrpjB0ZpMY2Oz6moglVoMCOY+ZYAxKM3n5XUp+za7W7wIoVldqi4q144qyNWp1EEi9bsazdiVKZaSDgjJ0MgV2n0w27yzuTljJ2ZKA2HKCiCbWgwI5zclXGslFecbEGmGMNkn6v3rDXys0ZO9qKjSgxY6fgVqzD5UGX0xvkKFo84dsGlmMrlp2vM8boEW9U5tom6uYtmqgCQEUTakCBHedSZSooULpwIvB7N/OWsVPhVuwf/vAHzJ49G/Hx8UhJSVF6OQD80yesnU7FZgIHthdR8oyQvypW+n8H1gczLd4InU4n+fcj2rPrh0acoKIJ1aDAjnNixk7iJsVsRquS21Mpcd7XqtQf/XOpeU6sw+HADTfcgF/84hdKL0UUb4xBRqL33/JUkzItT9j5ugSjQdFKZznP2LFsP02dIAPFsnVXT6WiCTWg/0OcSxOnT0ibsVOyOTEjTtrgZitWvcUTTz75JABg9erVyi7kHMPS4tDQZkdVUycm56XI/v15GCcG+DN2cmzF+itiaeoECV9g0cSiGbQNqwaUseOcXGfslBwnxlg42or10NQJSYgFFM3KnLPjoSI28PvLUTzRKAZ29HNMwseKJibnUdGEWlDGjnOynbHzPT/bDlUCe63WTgcEQVD0PFBThwMujwCdDuL2odbZ7XbY7Xbxc5vNFvHvkZ+qbGUsDz3sgOAGxVL/rIsZOwXftBF1CiyauIWydapBGTvO+c/YybMVq2TGjgV2TreAdodbsXUAwFnfPNP0BCNiOZk68cQTT0Cn0/X5sW/fvgE/f3l5OSwWi/iRn58fwdV75afFAQCqmjsj/tyh4CZjZ/JeZ4IAdEj8s05n7MhABRZN/JSKJlSDMnac88+Llbp4wnfGTsHAzhyrhzFGD4fLg5YOh6KHdNn5uiFJ/Jyvu/fee3HzzTf3eZ8RI0YM+PnLyspQWloqfm6z2SIe3LGM3WmlMnacnLEzx+ph0Ovg9gho7XIhQcKfdZo6QQYqsGhCyp9REln0f4pzqb4Dz5L3sROnTij3y1+n0yE1PhZnbXa0dDiRl6rYUlDny9hlcXS+LiMjAxkZGZI9v8lkgskk7etlZ+xOt3TC4xGg18u73W7jJGOn0+mQaIqBtdOJNrsTgHRvIJpo6gQZgMY2OzZ9UwOAiibUhgI7zqXJ1LTXykFVLOD943PWZle8MrZO5VMnKisr0dTUhMrKSrjdblRUVAAAzjvvPCQmJiq2rhyLGQa9Dg6XB/Vtdtkrjnk5YwdADOxaJa6MZdcSZexIODYcOA2nW6CiCRWiwI5zqeL8VKekGQ7Wx07JM3aAP7BUeqwY24rN5GgrNhy/+93v8Pe//138fOrUqQCALVu2YO7cuQqtCogx6JFjMeN0cyeqmjpkD+z8Z+yUD+zk6mVHGTsSrqBJE5StUx1JT4U3NzejpKREPIxdUlKClpaWXu/vdDrx7//+7zj//PORkJCA3Nxc3HbbbThz5kzQ/ebOndvt0Hh/Z4/UigVa7CyOVHjoYwfIVwXcn7McbsWGY/Xq1RAEoduHkkEdk5fKCijkP2fnP2On/HtaMbCT8Lr2eASxfVB6IgV2JDQ0aULdJA3sFi1ahIqKCmzatAmbNm1CRUUFSkpKer1/R0cHDhw4gN/+9rc4cOAA3nnnHXz//ff46U9/2u2+S5YsQU1NjfjxyiuvSPlSFGOKMYhFBFKdsxMEgYs+doHfn5eMHU/FE1rhb3kif2UsG+HFy1YsIG0vu9YuF9weAYDy1zZRj7V7KgFQ0YRaSfZ/7NChQ9i0aRN2796NmTNnAgD++te/oqioCEeOHMHYsWO7PcZisWDz5s1Btz3//POYMWMGKisrMWyYPyUcHx+P7OxsqZbPldSEWLTZXWjucKAACRF//i6nBw6XdzB6isLbNSkBW89K4rF4QivEJsUKVMbaOvkongCARF9wKWXGjr0ZTDTFwBRjkOz7EO1obLPj429p0oSaSZax27VrFywWixjUAcCsWbNgsViwc+fOkJ/HarVCp9N1G2T+xhtvICMjAxMnTsTDDz+M1tbWSC2dO+I5O4l62bGK2Bi9DglGZX/5p4oZO+W2YgVBQH0bmzpBGbtI8/eykz+wa7Xz0e4ECMjYSRnYsfN1UTBObPv27Vi4cCFyc3Oh0+nw3nvv9fuYbdu2obCwEGazGSNHjsTLL78s/UI59z/7qWhC7SR721pbW4vMzMxut2dmZqK2tjak5+jq6sKvf/1rLFq0CMnJyeLtt956KwoKCpCdnY1vvvkGZWVl+PLLL7tl+xg5OupLiQV2UjUpZoUTlrhYRac9AAFbsZ3KZeyaO5xwur3bV0OiZOqEnJTcimUZu2QOMnb+4gnpftb9Uye0f76uvb0dU6ZMwc9//nNcd911/d7/xIkTWLBgAZYsWYI1a9bg//7v/7Bs2TIMGTIkpMdrkSAIeHMvTZpQu7B/uz3xxBPigPHe7N27FwB6DBJCHZ/jdDpx8803w+Px4KWXXgr62pIlS8T/njRpEkaPHo3p06fjwIEDmDZtWrfnKi8v73fNPPO3PJHmD4BYOMHBGRz/VqxyGTtWOJGWYIQxho+pE1rCtmJrrJ1wuj2yTfYQBIGrM3ZJJumrYqNp6sT8+fMxf/78kO//8ssvY9iwYVi+fDkAYPz48di3bx+efvrpqA3sdh33Fk0kmmJo0oSKhR3Yhdr9/quvvsLZs2e7fa2+vh5ZWVl9Pt7pdOLGG2/EiRMn8NlnnwVl63oybdo0xMbG4ujRoz0GdnJ01JeSmLGTKNgRx4lxsD3lr4pVLmPnb3VC2TopDEk0iRNGalq6MCw9Xpbv2+5ww1dHwEW7EzYvVo6t2GjI2IVr165dKC4uDrrtiiuuwMqVK+F0OhEb2/1nRO27P/1Z+4WvaOKCXCqaULGw/8+F2v2+qKgIVqsVX3zxBWbMmAEA2LNnD6xWK2bPnt3r41hQd/ToUWzZsgXp6en9fq9vv/0WTqcTOTk5PX5djo76UmLnzqQ7Y8d62Cn/yz+FgzN2LGNH5+ukodfrkJcahx/q21HV3CFbYMeydbEGHcyxymdiE2XI2NE4sd7V1tZ2SzJkZWXB5XKhoaGhx78nat/96Utg0QRtw6qbZL/dxo8fjyuvvBJLlizB7t27sXv3bixZsgRXXXVVUEXsuHHj8O677wIAXC4Xrr/+euzbtw9vvPEG3G43amtrUVtbC4fD+wvq+PHjeOqpp7Bv3z6cPHkSGzduxA033ICpU6fioosukurlKIpto0h2xo6jjB0L7Kyd3obMSqinjJ3kxJmxMhZQ+CtilT9L6l2H9H3s/MUTFNj15NyfA0EQerydKSsrg9VqFT+qqqokX6NcWNHEFCqaUD1Jc61vvPEG7r//fjHd/dOf/hQvvPBC0H2OHDkCq9UKADh9+jQ++OADAMAFF1wQdD/WMd9oNOJf//oXnn32WbS1tSE/Px8/+clP8Pjjj8Ng0GY5f7rUgV0nR2fsfLNqPYJ3i0qJNYkZOwrsJCNWxspYQOE/X8fHFlOiyfuzLeVWLI0T6112dna3Qr66ujrExMT0ulOk9t2f3ngnTXi3YSlbp36S/oZLS0vDmjVr+rwPe4cEeM/mBX7ek/z8fGzbti0i61OLNIkDO9buhAVVSjLG6JFgNKDd4UZzh0PRwC7bQluxUhErY2XM2LHMNA+tTgD/GTtJiydonFivioqK8OGHHwbd9sknn2D69Ok9nq/Tsl3HG3GysQOJphiaNKEByh80If1K97XcaGiz93PPgbGK48T4yGQoXRlba/P+O8s9xzSaKNGk2D9dhY8gJ0ksnpCw3Ynv2o6GjF1bWxsqKipQUVEBwNvOpKKiApWV3kxUWVkZbrvtNvH+S5cuxalTp1BaWopDhw5h1apVWLlyJR5++GEllq8oKprQFgrsVIBtxdq6XOKEiEhq4ah4AlC+l91ZK5s6QYGdVPzzYuXbimUFOakcHDkAgtud9LdTMVCNvjeDaVHQoHjfvn2YOnUqpk6dCgAoLS3F1KlT8bvf/Q4AUFNTIwZ5AFBQUICNGzdi69atuOCCC/D73/8ezz33XNS1OmmgognNodBcBSxxsTDodXB7BDR3OCIecPDUxw4IbHkif8bO7fFPncimwE4ybCu2vtWOLqcb5ljpz8fyVCQE+LdiPQLQ6XQj3hjZX8cutwc23/m9aNiKnTt3bp8B8urVq7vddskll+DAgQMSrop/G6hoQnMoY6cCer1O/MUsxXYsb3/w/C1P5M/YNbbZ4fYI0OuAjETt/zFUSkp8rNjuQ67KWHHCCidBTlysAXpf8aUUlbGs76VOx082nvDF4/EXTSyaSdk6raDATiVYkCFFAYWVs7NHLLBrViCwO+s7X5eRaEKMTBMRopFOp5N9O5b9PPGyFavT6fzzYiUooGhu979hM+iVb+9C+LP7Byqa0CL6y6US6b7ArrEtsoGd0+0Rq/J4ydgpuRVbSxWxsskTe9nJE9ixIqEUTgI7wD8BQ4qWJ43t7HwdH2/YCH/e8GXrrpmaG/GjAEQ5FNipRFqCtzK2McIZO1tAgQIvbSAsccptxfp72FFgJzXWy+60TJWxrMqal8w0IG2TYpbdT0/QXt81MngNbXZ84iuaWDRjuMKrIZFEgZ1KsMrYxgifsWOVp0nmGG62a1IVbHfi72FHfwylJnfGjrezpEDgWLHIv4lpFqdO8PN6CT/ESRP5KZiQ2/c8dqIuFNiphD+wi2yw08Lh9hT7Q2RVoN1Jra/VCVXESo+dsZOteKKDv2a9iWIvOym2YtnUCXqTQoJ5PALeZEUTM/IVXg2JNArsVII1KY70VqyV9bDjYOoEY4lTMGPH5sRSYCc5//QJ6TN2DpcH7Q43AL7exCSapJs+0SwGdvy8XsKHXVQ0oWkU2KmEWDzRHuGtWB4zdqzdSbsCZ+woYyebPN8Zu6Z2B9olHKsF+Fud6HRAspmfn3Upz9hRxo70Zi0VTWgaBXYqkS7RvNhmcZwYP3/sWBVfq12aSRt9OdtKUyfkkmyOFX/uqlukzdpZA37O9ZycJQWkzdj5iyf4ycYT5VHRhPZRYKcS4lZshM/YNfkygDz98k82+/tuybkd2+V0ixlMytjJQ+xlJ3FlLCsS4ul8HeBvd2KTsCo2laNrmyiPiia0jwI7lWBZrDa7C11Od8Set4nD7ZrASRuRDmT7wipizbF6JMfR9oQc/AUU0mbs2HkznjLTAGXsiLyoaCI6UGCnEsnmGMQavFmsSG7HssCJtwPWUm0994VNnchKNkOn42e7TsvyxZYn8mTseDpLCvirYtu6InueVBAEMdtNDYoJQ0UT0YECO5XQ6XTiL+hIZrF4zNgB/j9GkS4W6QubOkHn6+Tj34qVNmPHY6sTAEiSKGPXanfB6RYAUGBH/KhoIjpQYKci6eL0icgFO/7Ajq9f/mkSzsbtTZ2NKmLlJjYpbpE4Y8dhkRAgXR+7Jt+bv3ijAeZYQ0Sfm6gTFU1EDwrsVESKebFNvkwGe25eKLEVy5oTZyXzlb3Usvw0Xy87iTN2rPqbt4ydVGfsmmgblpyDiiaiBwV2KpIe4e1Jl9sjZjJ4+wPA1tMgZ/FEq/+MHZHHUN9WrLXTCVuEz5kFEhtxc3bGjlXFSpWx4+26JsrweASs823D3jpjmMKrIVKjwE5FIj19gmUxdDr+Mhn+jJ18Z+zOWumMndwSTTFiQ+pqCStjm9v5LJ4QGxTbXRAEIWLPSxk7EmjXD4041diBJFMMrpqSo/RyiMQosFORSBdPsG3OlDh/3zhesGIOWbdi2Rk7CwV2cvJvx0p3zs5fFctXoMO2Yt0eAV3OyDXjFs/OcvZ6iTLW7mFFE0OpaCIKUGCnIhkRLihgW7o8vqv3V8XKE9gJgiD2saPiCXnJ0cvOKlbF8pWxizcawDrrtNojtxXNa1EUkV9Dmx2ffOctmriFtmGjAgV2KiJWxbZFZnvS38CUv2KBdJmrYq2dTth948uGJPH376Fl/l52Em7FspnIcXwFOjqdTmx5YuuM3Dk7MbDjrCiKyI+KJqIPBXYqwn5JR6qggOd39WxNLR1OuNzSz4tlzYlT42OpPYTMxF52EjUp7nK60emb1mLhLGMH+Ndk7ZQgY0dbsVGNiiaiEwV2KpIR4XNn4tQJDt/Vp8YbxS0qlm2REjUnVk6exBk7FjAZ9Dokm/k7X8SyiKxyNxIaOX7TRuRDRRPRiQI7FWEBWKfTjQ7H4LdteJ4ladDrkOJrJivHdixVxConP813xq6pI6KVoUxgc2IeR8WxpsmRzNix2bi89ack8qKiiehEgZ2KJBgNMMV4/5dFojKWBUy8tTph5BwrVmOlwgmlDE3xZuxa7a6IBjcMm5nKW6sTRgzsIpiZ5v3aJtKrb7Xj42+paCIaUWCnIjqdLqBJ8eADOxYw8fquPl3Glic1Vu82YE6K+gO7kydP4q677kJBQQHi4uIwatQoPP7443A45GsdE444o0EsWJFiAkWLWDjBaWDnCzhbIhTU2l1ucZIFj4VRRB4bDpyGyyPgAiqaiDqUm1WZ9EQTzli7IlIZy5q28noOJ03GsWJnfBm7XEuc5N9LaocPH4bH48Err7yC8847D9988w2WLFmC9vZ2PP3000ovr0f5qXGob7WjqrkD5+dZIvrc7Owar9mrSG/FsuvaoNchOY5+xUejwKKJRZStizp01auMOC82Ihk7vg9YR7oKuC81LdrJ2F155ZW48sorxc9HjhyJI0eOYMWKFfwGdmnxOFDZgkoJmhSz4hseK2KByAd2LBPvLUDi70whkR4VTUQ3CuxUJlLTJzweQTx7xOt2jZxjxdgZuxwNZOx6YrVakZaW1ud97HY77Hb/v7XNZpN6WaJhEk6fYFuxvGbsUiJ8xo5l7HgsiiLyoKKJ6EZn7FQmIzEyTYptXU64Pd4KxNQEPjMZcm3F2rqc4pmkXA1k7M51/PhxPP/881i6dGmf9ysvL4fFYhE/8vPzZVqhv0lxlQQtT1pY8QSvZ+ykythxel0TaVHRBKHATmXYWLH6QQZ2bBs2yRQDUwyfDXnTxSBW2sCupsWbrbPExXL97vaJJ56ATqfr82Pfvn1Bjzlz5gyuvPJK3HDDDVi8eHGfz19WVgar1Sp+VFVVSflyguT5Wp5ImbHjvio2Ymfs+M7EE2n9z34qmoh2kgZ2zc3NKCkpETMAJSUlaGlp6fMxd9xxR7c/VrNmzQq6j91ux3333YeMjAwkJCTgpz/9KU6fPi3hK+EH67PG5poOlBpGDqXLlLE7wypiLXxn6+69914cOnSoz49JkyaJ9z9z5gwuvfRSFBUV4dVXX+33+U0mE5KTk4M+5MK2YqubO+HxRLaXnb/dCZ8/65GuiuV5ogyRVlDRxEzK1kUrSdMTixYtwunTp7Fp0yYAwN13342SkhJ8+OGHfT7uyiuvxGuvvSZ+bjQG/4J68MEH8eGHH+LNN99Eeno6fvnLX+Kqq67C/v37YTDwmX2KFBbY1dkGmbFr4/+Xv1xbsbWsIjaF7/N1GRkZyMjICOm+1dXVuPTSS1FYWIjXXnsNej3fyfkcSxxi9Do43B6cbe2K6FlHlgmLlowdy8ancnxtE2nsPN6IyiZf0cRkKpqIVpIFdocOHcKmTZuwe/duzJw5EwDw17/+FUVFRThy5AjGjh3b62NNJhOys7N7/JrVasXKlSvxj3/8A5dddhkAYM2aNcjPz8enn36KK664IvIvhiORztjxfMCara25wwGPR4BeL02Fn1gRy3nGLlRnzpzB3LlzMWzYMDz99NOor68Xv9bbdaU0g16H3JQ4VDZ1oLKxI6KBHcvYcVs84VuXw+VBl9M96FnF/qIoPl8vkc7aL04BAP5tGhVNRDPJ3sbv2rULFotFDOoAYNasWbBYLNi5c2efj926dSsyMzMxZswYLFmyBHV1deLX9u/fD6fTieLiYvG23NxcTJo0qd/n1YJMXyPXdoe/CelAsEpTnjN2LOPgESK3TdWTMyrJ2IXqk08+wbFjx/DZZ58hLy8POTk54gfPxMrYCBdQBI4U41GC0QCD701LSwQqY9WQjSeRV99qxyffngVARRPRTrLArra2FpmZmd1uz8zMRG1tba+Pmz9/Pt544w189tln+O///m/s3bsXP/7xj8U2DLW1tTAajUhNTQ16XFZWVq/Pa7fbYbPZgj7UKsEUgyST953YYLJ2/h52/B6wjjXoxaHtUrY8YVMntDJO7I477oAgCD1+8CxfggKKLqcbdpcHAL9bkzqdLqLbsSxjR4FddGFFE1OHpWB8DhVNRLOwA7twKvN6ao4pCEKfTTNvuukm/OQnP8GkSZOwcOFC/POf/8T333+Pjz76qM919fW8SrZxkEJmsjcYG0xg5z9gzWcWg5GjMpZVxWqhObGa5aVGvpcdC3Ji9DokGPk9f5sSwcCOMnbRJ7BogrJ1JOxN+HvvvRc333xzn/cZMWIEvvrqK5w9e7bb1+rr65GVlRXy98vJycHw4cNx9OhRAN4zQg6HA83NzUFZu7q6OsyePbvH5ygrK0Npaan4uc1mU3Vwl5VsxvH69kEVUDSpIGMHeP84nWhoj8ikjZ4IgiBWxWphnJia+bdiIxfYNbT6zpsl8j2FIdkX2LGeewPlcnvQ5HsONn+XaJ9YNGGOwcLJuUovhygs7MAu1Mq8oqIiWK1WfPHFF5gxYwYAYM+ePbBarb0GYD1pbGxEVVWVeD6osLAQsbGx2Lx5M2688UYAQE1NDb755hv8+c9/7vE5TCYTTCbt/JKLRAGFGoongIBJGxIFdi0dTnQ5vVt12RopnlCrfHH6ROTO2NW1eq+RzCS+/99Gaiu2qd0BQQD0On6LRUjkiUUTU4cijuPMNJGHZGfsxo8fjyuvvBJLlizB7t27sXv3bixZsgRXXXVVUEXsuHHj8O677wIA2tra8PDDD2PXrl04efIktm7dioULFyIjIwP/9m//BgCwWCy466678Mtf/hL/+te/cPDgQfzsZz/D+eefL1bJap1/KzYSGTu+f/mLvewk2opl2br0BOOgqxHJ4OSnejOmtbYudDndEXnO+lbvNcJ79oq1YhlsYMcal6clmMSCDKJtVDRBziVpc6s33ngD559/PoqLi1FcXIzJkyfjH//4R9B9jhw5AqvVCgAwGAz4+uuvcfXVV2PMmDG4/fbbMWbMGOzatQtJSUniY/7yl7/gmmuuwY033oiLLroI8fHx+PDDDzXfw47J8mUfzrYOLGMnCEJA8QTfgV2axPNi6XwdP9ISjOI5uOqWyGTt6nyBXSbngV2kMnYNvjdAGRw3HieRRUUT5FySNrpJS0vDmjVr+rxPYKVeXFwcPv74436f12w24/nnn8fzzz8/6DWqkb9J8cACu3aHGw5fpWA6538ApN6KrRGnTtD5OqXpdDrkp8XjcG0rqpo6MGpI4qCfk23F8p6xi1hgp5IMJYkMKpogPeG7HT3pUbZlcFuxbFvTHKvnvoklCzylmj4h9rCj83VciHRlbH2UZezYVuyQRL5fL4mM/zveQJMmSDcU2KkQOwhea+saUG+yRt+2phqGhLOqXananYhTJzTSnFjtIt2kuE7MYPEduFvEqtjIZOwyOA9kSWSwbB1NmiCBKLBTIVY84XB5BvQOn53D4X0bFvBnWlgmItJYxk4r48TULtJNitVSPBG5M3a+wE4F1zYZnLrWLrFoYtFM2oYlfhTYqZApxoBUXxXdQLZja1U0aYGdJ2xqd8DuikylZCB2xk4r48TULt+3FVsZgcBOEATVFE+webG2iBVP8P16yeAFFk2My6aiCeJHgZ1KDaaXXY2KslSp8bGINXjbNrDsS6R4PAJqff8Waghyo8HwdF9g19gx6BFoti6XWCSklozdYGcis4wd769XKi+99BIKCgpgNptRWFiIHTt29HrfrVu39jg56fDhwzKueGA8HgFvflEFAFhERRPkHBTYqVTmIAI7MZhRQSWoTqcTzxQOpm9fTxrbHXC6Beh01JyYF/lp8dDpgFa7a9CV0PW+ithkcwz3PQoDt2IHE9CyNz/RmLFbv349HnzwQTz22GM4ePAg5syZg/nz56OysrLPxx05cgQ1NTXix+jRo2Va8cCJRRPmGFxFkybIOSiwU6ks3zvyugFkscQRWirp3ZblO1M40PYuvWHbsEMSTYg10KXAA3OsQRztdrKhfVDPxUbuqSF7xRoUuz0C2h0DO3IQOE4sGgO7Z555BnfddRcWL16M8ePHY/ny5cjPz8eKFSv6fFxmZiays7PFDzX0Q127xxusXkuTJkgP6K+ZSg1mK1Zt24+RGKHWk+pmqojl0YgM73bsiUEGdqzghvdxYoA3oDXGeH8dD3RebFOHf5wY743HI83hcGD//v0oLi4Our24uBg7d+7s87FTp05FTk4O5s2bhy1btvR5X7vdDpvNFvQht7rWLmz+zjdpgoomSA8osFOpLHGsWHjBjiAI4hk7tRQMiIFdhM/YsWHzrMUG4cOI9AQAwMnG6MnYAYOvjG1o9U+TibZxYg0NDXC73cjKygq6PSsrC7W1tT0+JicnB6+++io2bNiAd955B2PHjsW8efOwffv2Xr9PeXk5LBaL+JGfnx/R1xEKVjQxjYomSC+o8Y1K+c/YhRfsNHc4YfcdKGdtU3gnVcaODZtnM0oJHwoyfIFdw+AqY/0ZO3X8nKfExaK+1T7wwK4tes/XMTpdcEArCEK325ixY8cGzS0vKipCVVUVnn76aVx88cU9PqasrAylpaXi5zabTdbgLrBogiZNkN5Qxk6lBjpWjJ0ry0g0whSjjrMZ/jN20mTs8iljxxWWsRvsViy7NtTyBkbM2A2wSbFaevZJISMjAwaDoVt2rq6urlsWry+zZs3C0aNHe/26yWRCcnJy0IecqGiChIICO5Vi5+PqWu3weEKvohOH3qugIpZhQWxtxDN2vsAulQI7nozI8G/FDqZCtE5lgc6gt2KjOGNnNBpRWFiIzZs3B92+efNmzJ49O+TnOXjwIHJy+B3NRUUTJBS0FatSGYlG6HSAyyOgqcMR8i/zGhtrdcL/gXJmoOcJ+yIIAk77iifYtAPCh2Fp8dDrgA6HG/WtdvHYQbj8c2LV8bNuiY9UYBddhRNMaWkpSkpKMH36dBQVFeHVV19FZWUlli5dCsC7jVpdXY3XX38dALB8+XKMGDECEydOhMPhwJo1a7BhwwZs2LBByZfRKyqaIKGiwE6lYgx6ZCSaUN9qR621K+TAjk2dUENzYob9YW/tcqHD4YrITMT6VjvsLg/0OvUUkUQLY4weQ1PjUNXUiRMN7QMO7NSasRtok+Jonzpx0003obGxEU899RRqamowadIkbNy4EcOHDwcA1NTUBPW0czgcePjhh1FdXY24uDhMnDgRH330ERYsWKDUS+jT2/uoaIKEhgI7FctK9gZ2da1dACwhPUaNW7FJphjExRrQ6XSjzmbHiIzB/9iykVU5ljjqYcehEekJqGrqxMnGdswcmR724+0ut5j5UkvxRKS2YtUSyEph2bJlWLZsWY9fW716ddDnjzzyCB555BEZVjV4Ho+AN/d6g9KbqWiC9IP+oqlY1gAmMqhpnBij0+nEreNIbcf6CyfUE+BGE1YZe2KAlbFsG9Zo0IsBE+9SBhnYRfPUCa37/FgDqpo6kWSOwUIqmiD9oMBOxXJ8kyNYo91QsAIENQV2gD/rEqledv5WJ1Q4wSOxl90AK2MDt2F7a3fBG/GM3QCrYqO5eELr1n1BRRMkdBTYqZjYFiLERq6CIOBMCztjp65M1UDbu/RGrIilVidcKsgYXJNiMXulom3JlDhv0cNAMnZuj4Am32zdjKToLJ7QKiqaIOGiwE7Fws1qtAQ0J86yqOcPHhD5yljaiuVbYMuTcNr5MHWt6mpODADJYvFE+CPFmtod8AiATgekxVNgpyVUNEHCRYGdio3I8DdyDaXfFztfp6bmxEzWACdt9Ia2YvmWlxoHg16HLqcHZ1vDD+brVRjYDaZBMduGTU8wIoaKgTQjsGhi0czhCq+GqAX9BlCxc/t99YdNnVBTDzsmM4JjxZxuj/hvQXNi+RRr0Iuj3gYygaLeFwyqqUI0xXfGrtXugsvtCeuxVDihTYFFEz85n9/GyYQvFNipGOv3BYT2x89fEau+7cespMhtxZ5p6YRHAEwxelX94Y82w9MHPjNWbc2JAe8WqkGvgyAAje3hbcdS4YQ2UdEEGQgK7FROPGcXwiHzWhW2OmH87U7sgxozBfi3YfNS41RTMRmNBlNAobbmxACg1+vEqRHhvoGJ9qkTWkRFE2SgKLBTuXD6fZ1R81asL/PS6XSj1e4a1HP5CydoG5ZnI9K9/38GshVbZ1PfGTvA/3NeF+ZZ0mifOqFFVDRBBooCO5ULpzKWZexyVbgVG2c0INnsnTgx2JYnYqsTKpzg2nmZSQCAo2dbw3qc2yOodgoDC0TrwuzX2KDCDCXpHRVNkMGgwE7lwtmuYoGdGjN2QOQqY6t8DZ2p1QnfxuV4A7tTTR1oDyNLW93cCZdHgDFGL/7MqEVmMgvswnvzUk9n7DSFiibIYFBgp3Kh9vsSBEHcilXjGTsgMLCLTMaOKmL5lpFoQkaiCYIAfB9G1u54QxsA71auQa+uM5RD2FZsmBk7NY4KJL1jRRPXTcujogkSNgrsVC7Ufl/WTie6nL7mxCrLYjCZYpPiQWbsfIFdHm3Fcm+8L2t3uDb0wO6Hem/2emRGoiRrkhJrxB3OGTtBEMSxgrkplIVWu8CiiZtn5Cu8GqJGFNipXKj9vtjXhiSZYI5V5zvASGTs2u0usZUEFU/wb3yO99D4oRpbyI/5od6bsRs5JEGSNUmJFU/Uh7EV29LhRKfTDUC9xyyIHxVNkMGiwE4DxO3YPipjvznj/cM4MVe9vyiyIxDYVfqydcnmGLHTP+HXuGxfxq5mABm7IerL2A2keKLaN/85I1G9b9qIFxVNkEigwE4DQimg+Oa0FQAwKdciy5qkwLaZWLuSgThW583mnJepvj/64fjpT3+KYcOGwWw2IycnByUlJThz5ozSywoby1gcqrWF3L/whwYVZ+x8W7H1rfaQZ+Se8QV2rFk5US8qmiCRQIGdBhQEzIztzTdnfIHdUPVm7AoyvFunJxs6BtykOFoCu0svvRRvvfUWjhw5gg0bNuD48eO4/vrrlV5W2EZlJiBGr0NrlwtnrP1natvsLvEM5igVnrHLSDRBpwNcHgHNHaFNn2AZu6EptA2rdmv3UNEEGbwYpRdABq+/XnZ2l1usKpw0VL0Zu7zUeOh03j/eje2OAbV2YIHdaF+PNK166KGHxP8ePnw4fv3rX+Oaa66B0+lEbKx6tqBNMQacl5mIw7WtOFxjw9B+igNO+LZh0xOMsMSr53UysQY90uKNaGx34KzNjvQQfsZZxk6N/SmJX52tC58e8k2amEGTJsjASZqxa25uRklJCSwWCywWC0pKStDS0tLnY3Q6XY8f//Vf/yXeZ+7cud2+fvPNN0v5UrjGMnanGjvg7mH75ujZNjjdAlLiY/v9w8gzc6xB/OMVSkPmnogZuyz1ZXMGqqmpCW+88QZmz56tqqCOYefsQimgUPM2LDMkKbxedmdafI3HVXxtE+Dt/d6iicLhqRibre03nkRakgZ2ixYtQkVFBTZt2oRNmzahoqICJSUlfT6mpqYm6GPVqlXQ6XS47rrrgu63ZMmSoPu98sorUr4UruWmxMFo0MPh9ojv3gN9Xe0/X6f22aihbDv3xuX2iH/4z1Phwfpw/fu//zsSEhKQnp6OyspKvP/++33e3263w2azBX3wYByrjA2h5clxFbc6YTKTw+tlx7ZiKbBTL49HEHvXLaJsHRkkyQK7Q4cOYdOmTfjb3/6GoqIiFBUV4a9//Sv+93//F0eOHOn1cdnZ2UEf77//Pi699FKMHDky6H7x8fFB97NY1LvFOFgGvU6cotBTwPONL7CbqOLzdcxw3/zQgQyGP9XUAadbQFysQZWZyyeeeKLXjDb72Ldvn3j/X/3qVzh48CA++eQTGAwG3HbbbX2eTSwvLxez6xaLBfn5fPTQ8lfG9h9osp9/NWfsWGVsfYiBHXszl0fFE6q141gDTjd3Itkcg59MpqIJMjiSnbHbtWsXLBYLZs6cKd42a9YsWCwW7Ny5E2PHju33Oc6ePYuPPvoIf//737t97Y033sCaNWuQlZWF+fPn4/HHH0dSUvSmrycNteB4fTt2Hm/ExWOGBH2NtTpRc0Us468ADr8ylm3DjspMgF5lEwkA4N577+33yMGIESPE/87IyEBGRgbGjBmD8ePHIz8/H7t370ZRUVGPjy0rK0Npaan4uc1m4yK4m+DL2J1oaEeX091nSw9/DzsVZ+zYVmwIbX3sLreY2aOMnXqt3XMKAHDttDxqWUMGTbLArra2FpmZmd1uz8zMRG1tbUjP8fe//x1JSUm49tprg26/9dZbUVBQgOzsbHzzzTcoKyvDl19+ic2bN/f4PHa7HXa7/90vL1tMkXTZ+Cy8X3EGm7+rxa/njxNvd7o94tmk81VcOMH0VyjSF7UXTrBAbSBYpi7wOjiXyWSCycTfrNEhSSakJRjR1O7A92dbMTkvpcf7CYKgqYxdKFuxbP6zOVaPVBUWixBWNFEHgIomSGSEvRUbznZQT+e5BEEI+ZzXqlWrcOutt8JsDi7jX7JkCS677DJMmjQJN998M/7nf/4Hn376KQ4cONDj8/C6xRRJl4wdgliDDsfr28WsBeANZhwuD5JMMZqYjTpCbHnSHnbLk2hpdfLFF1/ghRdeQEVFBU6dOoUtW7Zg0aJFGDVqVK/ZOp7pdLqQGhXX2rrQ4XAjRq9T9c96OGfsAs/Xqf38bLR6a18V3FQ0QSIo7MDu3nvvxaFDh/r8mDRpErKzs3H27Nluj6+vr0dWVla/32fHjh04cuQIFi9e3O99p02bhtjYWBw9erTHr5eVlcFqtYofVVVV/b9QlUk2x2LWyHQAEEvmAf/5ugm5yarcfjxXflo89Dqg3eFGQ1tofb6Yo3XeoEDrgV1cXBzeeecdzJs3D2PHjsWdd96JSZMmYdu2bVxm5ELBGhV/6+vH2BM2cWJYWjxiDept0ZkZRlUsq4hV45lRwoomvH+PqGiCRErYW7GhbgcVFRXBarXiiy++wIwZMwAAe/bsgdVqxezZs/t9/MqVK1FYWIgpU6b0e99vv/0WTqcTOTk9HzrldYsp0i4bn4UdRxvw6Xd1uPviUQCAb9n5Og1swwLevma5KXE43dyJk43tYmuI/ng8Ao7Xef/wj9Z4YHf++efjs88+U3oZEVU4PBWr/u8EPj/W0Ot91DwjNhCbF1tns/e7w1HdzJoTU2CnRtuP1qO6hYomSGRJ9rZ2/PjxuPLKK7FkyRLs3r0bu3fvxpIlS3DVVVcFFU6MGzcO7777btBjbTYb3n777R6zdcePH8dTTz2Fffv24eTJk9i4cSNuuOEGTJ06FRdddJFUL0cVLpvgzYTuO9WEJt+ge9bqRAvn6xh2zi6clifVLZ3odLphNOhVvU0XreaMyYBB7z1qUNlL4cxxFc+IDcTGitldHti6XH3e9wy1OlE11uKEiiZIJEm6X/HGG2/g/PPPR3FxMYqLizF58mT84x//CLrPkSNHYLUGb6+8+eabEAQBt9xyS7fnNBqN+Ne//oUrrrgCY8eOxf3334/i4mJ8+umnMBii+8IYmhKHCTnJ8AjAZ4frcKCyWdyKVfMosXOxc3anwmh5ws7XFWQkIEbF23TRKtkci+nDUwEAW47U9XifH1jhRIa6M3bmWAOSzN7NlPp+tmPPWCmwU6uzVDRBJCLpSLG0tDSsWbOmz/v0dAD+7rvvxt13393j/fPz87Ft27aIrE+LLp+Qhe9qbFix9RhON3fC7vKgcHiqqhu2nstfGRt6y5NoKZzQskvHZWLPiSZsOVKH22ePCPqa2yPgO9/5u1Ea+H+cmWRCa5d37u15fVRx+4snaE6s2rxNRRNEIpS60JjLfduxx+vbYXd5cNn4TLx+5wxNFE4wA9mKjZbCCS378Thv+6RdxxvR6XAHfW3n8QY0tDmQGh+LKb20Q1GTLLEytveMnSAI/ubEKXS8QE2oaIJIiQI7jZmYmyxOZ7jzogK8UjIdCSZJE7OyGyHOxg295YnYwy6KZsRqzejMRAxNiYPd5cGuH4KLKN49WA0AuGpyLowx6v+15m9S3HvLk6Z2B7qcHuh0QJZF+8VhWkJFE0RK6v8NSILodDr8486ZePPuWfjdwgkwaChTx+SnxYktT+rb+u/1JQgCjtJWrOrpdDpcOs47VeWzw/5zdh0OFzZ94216fs3UoYqsLdJC6WXHWp0MSTTBFBPd54vVhoomiJQosNOgYenxYk87LWItT4DQztmdbOxAa5cLRoNeHElG1OnSsd7t2C2H68Vs7ebvzqLD4cawtHhMG5ai4OoiJ5TpE9VUEatKgUUTi2bSNiyJPArsiCqJM2NDOGe390QTAGBKvoUyGyo3e1QGjDF6VLd0itvrbBv2mqlDNTN9YUgI82LZ+TrqYacurGhi+vBUjMmiogkSeRTYEVViBRQ/hBDY7fEFdjMK0iRdE5FenNGAIl82+t61B7H5u7PYcdR73u6aC3KVXFpEsSbFtX0EdixjNzSVAju1cAcWTVC2jkiEAjuiSuNyvO90D1Y293vfvSe9gd2FIyiw04IHLxuN1PhYHDnbiiWv74PbI2BKforqGxMHYmdBK5s60GbvuUnx92e9ld6sWIrwb4evaMISF4sF51PRBJEGBXZEldgZwoNVLehyunu9X621C5VNHdDrvGOpiPpNHZaKf/1yLq6d5i+U+DcNZesA71ZsdrIZggB85xsLGEgQBHxZ1QIAmmjvEi3W7mFFE0OpaIJIhgI7okojMxKQmWSCw+XBgT6ydl/4snUTcpORZI6Va3lEYmkJRjxz4wV48+5Z+O1VE/CzWcOVXlLEsfnObCxgoJONHbB1uWCK0VNzW5U4a+vCvw7TpAkiPQrsiCrpdDoxa7f7h6Ze7/fFiUYAtA2rVbNGpuOuHxVockwcm+/8TQ+BHcvWTcxNRqwGX7sWvbWXiiaIPOg3AlGtolG+wO54Y6/32XvCm82bSYUTRGXOz/POd+4pY1fBtmHzU2RcERkot0fAm3upaILIgwI7olpF4jm75m4jpgCgpcOBI74D5tMpY0dUhm3FHq9vQ/s5BRRfnW4BQOfr1CJw0gQVTRCpUWBHVGt4ejyyk81wuoUez9ntPem9bdSQBGQk0sgloi6ZSWZkJZsgCMChGn8BhdPtwTe+ggrK2KnDuj00aYLIhwI7olo6nU7cjt3Vw3Ysa3NC/euIWp3fQwHFkdpWOFweJJtjMIJanXAvsGiCtmGJHCiwI6rGtmN3/dA9sGPBHgV2RK0m5nYP7L5k27D5KZqZtKFlVDRB5EaBHVE1Vhn7ZVULOhz+c0hbj9Th62orYg06zB6VodTyCBmUnipjqX+delDRBFECBXZE1fLT4jA0JQ4uj4A9vrYnLrcHf/joEADg9qIRyEo2K7lEQgbs/DxvYHesrk184/JllTfIm+z7GvF76aWXUFBQALPZjMLCQuzYsaPP+2/btg2FhYUwm80YOXIkXn755YiuZztNmiAKoMCOqJpOp8PFY4YAAH71P1/h6NlWrPuiEkfr2pAaH4v75o1WeIWEDFxWshlDkkzw+Aoo2u0uHK3zVnpfQIUTQdavX48HH3wQjz32GA4ePIg5c+Zg/vz5qKys7PH+J06cwIIFCzBnzhwcPHgQjz76KO6//35s2LAhYmtaR5MmiAIosCOq96srxmJ8TjIa2uy45a+78czm7wEApZePgSWOpk0QdWPbsQcrW7D9+3p4BCDHYkYmZaKDPPPMM7jrrruwePFijB8/HsuXL0d+fj5WrFjR4/1ffvllDBs2DMuXL8f48eOxePFi3HnnnXj66acjsp6gogmaNEFkRIEdUb20BCPWLp6JibnJaGhzoLnDidGZiTS2h2gC62f3Hx8dwi/eOACAtmHP5XA4sH//fhQXFwfdXlxcjJ07d/b4mF27dnW7/xVXXIF9+/bB6XT2+Bi73Q6bzRb00RtWNHHhiFSMpqIJIiMK7IgmpCYY8cbimZiSnwKjQY/HF07U5JgpEn3mjh0i/ndcrAETc5Nx149GKrgi/jQ0NMDtdiMrKyvo9qysLNTW1vb4mNra2h7v73K50NDQ0ONjysvLYbFYxI/8/Pxe1/QpzYUlColRegGEREpKvBHv/mI2WjqdSEswKr0cQiJi2rBU7C6bB70OGJJkohYnfTj330YQhD7/vXq6f0+3M2VlZSgtLRU/t9lsvQZ3b/+/Inx66Cx+PC4zpLUTEikU2BFN0et1FNQRzcm20Hm6vmRkZMBgMHTLztXV1XXLyjHZ2dk93j8mJgbp6ek9PsZkMsFkCm2KjTFGT5WwRBG0V0UIIUTVjEYjCgsLsXnz5qDbN2/ejNmzZ/f4mKKiom73/+STTzB9+nTExlLRFVEvCuwIIYSoXmlpKf72t79h1apVOHToEB566CFUVlZi6dKlALzbqLfddpt4/6VLl+LUqVMoLS3FoUOHsGrVKqxcuRIPP/ywUi+BkIigrVhCCCGqd9NNN6GxsRFPPfUUampqMGnSJGzcuBHDhw8HANTU1AT1tCsoKMDGjRvx0EMP4cUXX0Rubi6ee+45XHfddUq9BEIiQiew06JRxGazwWKxwGq1Ijk5WenlEA1T88+amtdO1EWtP2tqXTdRn3B+1mgrlhBCCCFEIyiwI4QQQgjRCArsCCGEEEI0ggI7QgghhBCNoMCOEEIIIUQjKLAjhBBCCNEICuwIIYQQQjSCAjtCCCGEEI2gwI4QQgghRCMosCOEEEII0YionBXLpqjZbDaFV0K0jv2MqXFyH10nRC5qvU7oGiFyCecaicrArrW1FQCQn5+v8EpItGhtbYXFYlF6GWGh64TITW3XCV0jRG6hXCM6QW1vkSLA4/HgzJkzSEpKgk6nC/qazWZDfn4+qqqqaKizhKLl31kQBLS2tiI3Nxd6vbpOPtB1oqxo+jdW63VC14jyouXfOZxrJCozdnq9Hnl5eX3eJzk5WdM/JLyIhn9nNWUgAtF1wodo+TdW43VC1wg/ouHfOdRrRD1vjQghhBBCSJ8osCOEEEII0QgK7M5hMpnw+OOPw2QyKb0UTaN/Z3Wj/3/So39jdaP/f/Kgf+fuorJ4ghBCCCFEiyhjRwghhBCiERTYEUIIIYRoBAV2hBBCCCEaQYHdOV566SUUFBTAbDajsLAQO3bsUHpJmlFeXo4LL7wQSUlJyMzMxDXXXIMjR44ovSwSJrpGpEXXiTbQdSIdukb6RoFdgPXr1+PBBx/EY489hoMHD2LOnDmYP38+KisrlV6aJmzbtg333HMPdu/ejc2bN8PlcqG4uBjt7e1KL42EiK4R6dF1on50nUiLrpG+UVVsgJkzZ2LatGlYsWKFeNv48eNxzTXXoLy8XMGVaVN9fT0yMzOxbds2XHzxxUovh4SArhH50XWiPnSdyIuukWCUsfNxOBzYv38/iouLg24vLi7Gzp07FVqVtlmtVgBAWlqawishoaBrRBl0nagLXSfyo2skGAV2Pg0NDXC73cjKygq6PSsrC7W1tQqtSrsEQUBpaSl+9KMfYdKkSUovh4SArhH50XWiPnSdyIuuke5ilF4Ab3Q6XdDngiB0u40M3r333ouvvvoKn3/+udJLIWGia0Q+dJ2oF10n8qBrpDsK7HwyMjJgMBi6vaOqq6vr9s6LDM59992HDz74ANu3b0deXp7SyyEhomtEXnSdqBNdJ/Kha6RntBXrYzQaUVhYiM2bNwfdvnnzZsyePVuhVWmLIAi499578c477+Czzz5DQUGB0ksiYaBrRB50nagbXSfSo2ukb5SxC1BaWoqSkhJMnz4dRUVFePXVV1FZWYmlS5cqvTRNuOeee7B27Vq8//77SEpKEt/RWiwWxMXFKbw6Egq6RqRH14n60XUiLbpG+iGQIC+++KIwfPhwwWg0CtOmTRO2bdum9JI0A0CPH6+99prSSyNhoGtEWnSdaANdJ9Kha6Rv1MeOEEIIIUQj6IwdIYQQQohGUGBHCCGEEKIRFNgRQgghhGgEBXaEEEIIIRpBgR0hhBBCiEZQYEcIIYQQohEU2BFCCCGEaAQFdoQQQgghGkGBHQnyxBNP4IILLlB6GYRwi64RQvpH14lyaPJEFNHpdH1+/fbbb8cLL7wAu92O9PR0mVZFCD/oGiGkf3Sd8I0CuyjCBiUDwPr16/G73/0OR44cEW+Li4uDxWJRYmmEcIGuEUL6R9cJ32grNopkZ2eLHxaLBTqdrttt56bP77jjDlxzzTX4z//8T2RlZSElJQVPPvkkXC4XfvWrXyEtLQ15eXlYtWpV0Peqrq7GTTfdhNTUVKSnp+Pqq6/GyZMn5X3BhISJrhFC+kfXCd8osCP9+uyzz3DmzBls374dzzzzDJ544glcddVVSE1NxZ49e7B06VIsXboUVVVVAICOjg5ceumlSExMxPbt2/H5558jMTERV155JRwOh8KvhpDIo2uEkP7RdSITgUSl1157TbBYLN1uf/zxx4UpU6aIn99+++3C8OHDBbfbLd42duxYYc6cOeLnLpdLSEhIENatWycIgiCsXLlSGDt2rODxeMT72O12IS4uTvj4448j/2IIkQBdI4T0j64T/sQoHVgS/k2cOBF6vT+5m5WVhUmTJomfGwwGpKeno66uDgCwf/9+HDt2DElJSUHP09XVhePHj8uzaEJkRNcIIf2j60QeFNiRfsXGxgZ9rtPperzN4/EAADweDwoLC/HGG290e64hQ4ZIt1BCFELXCCH9o+tEHhTYkYibNm0a1q9fj8zMTCQnJyu9HEK4Q9cIIf2j62RgqHiCRNytt96KjIwMXH311dixYwdOnDiBbdu24YEHHsDp06eVXh4hiqNrhJD+0XUyMBTYkYiLj4/H9u3bMWzYMFx77bUYP3487rzzTnR2dtK7LkJA1wghoaDrZGCoQTEhhBBCiEZQxo4QQgghRCMosCOEEEII0QgK7AghhBBCNIICO0IIIYQQjaDAjhBCCCFEIyiwI4QQQgjRCArsCCGEEEI0ggI7QgghhBCNoMCOEEIIIUQjKLAjhBBCCNEICuwIIYQQQjSCAjtCCCGEEI34/1A1ANJtwH0wAAAAAElFTkSuQmCC", - "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -315,101 +197,57 @@ } ], "source": [ - "f = plt.figure()\n", - "model.plot()\n", - "plt.close()" + "model.initial_values = ([0.0] + thetaHat['x'].tolist(), t[0])\n", + "\n", + "solution = model.integrate(t[1::])\n", + "\n", + "f, axarr = plt.subplots(layout='constrained')\n", + "axarr.plot(t, solution[:,0])\n", + "axarr.set_title(\"Height, y\")\n", + "axarr.set_xlabel(\"Time\");" ] }, { "cell_type": "markdown", - "id": "1e1407cf", + "id": "85032ca8", "metadata": {}, "source": [ + "## Unknown parameters\n", "\n", - "Now we are ready to setup the estimation. Like before, we set up the\n", - "second boundary condition by pretending that it is an observation. We\n", - "have all the initial conditions defined by the first boundary condition." + "Now we consider the case where initial conditions are known, but we wish to estimate the unknown parameter $g$ which satisfies the BVP.\n", + "Like before, we set up the second boundary condition by pretending that it is an observation.\n", + "This time we omit the `target_state` argument to let the solver know that our initial conditions are fixed.\n", + "We declare $g$ as a model parameter and then solve as before." ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 6, "id": "110edf3a", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " message: Optimization terminated successfully.\n", - " success: True\n", - " status: 0\n", - " fun: 4.6125586631762084e-15\n", - " x: [ 1.349e+01]\n", - " nit: 5\n", - " jac: [ 7.657e-08]\n", - " hess_inv: [[ 1.759e+00]]\n", - " nfev: 12\n", - " njev: 6\n" - ] - } - ], + "outputs": [], "source": [ - "obj = SquareLoss(15.0,\n", - " ode=model,\n", - " t0=t[0], x0=[1.0, 0.0, 0.0], \n", - " t=t[-1], y=0.0,\n", - " state_name='y')\n", - "\n", - "obj = SquareLoss(theta=theta,\n", - " ode=model,\n", - " t0=t[0], x0=initialState,\n", - " t=t[-1], y=[-2],\n", - " state_name=['y'], target_state=['z'])\n", - "\n", - "xhatObj = minimize(obj.cost,[15])\n", + "stateList = ['y', 'v']\n", + "paramList = ['g']\n", "\n", - "print(xhatObj)\n", + "ode1 = Transition(transition_type=TransitionType.ODE, origin='y', equation='v')\n", + "ode2 = Transition(transition_type=TransitionType.ODE, origin='v', equation='-g')\n", "\n", - "model.parameters = [('p', xhatObj['x'][0])]\n", + "model = SimulateOde(stateList, paramList, ode=[ode1, ode2])\n", "\n", - "model.initial_values = ([1.0, 0.0, 0.0], t[0])\n", + "model.parameters = [('g', 5.0)]\n", + "theta = [5.0]\n", + "initialState = [0.0, 15.0]\n", "\n", - "solution = model.integrate(t[1::])" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "653c998f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "f = plt.figure()\n", + "t = np.linspace(0, 3, 100)\n", "\n", - "model.plot()\n", + "obj = SquareLoss(theta=theta,\n", + " ode=model,\n", + " t0=t[0], x0=initialState,\n", + " t=t[-1], y=[0],\n", + " state_name=['y'])\n", "\n", - "plt.close()" + "thetaHat = minimize(fun=obj.cost, x0=theta)" ] }, { @@ -417,26 +255,34 @@ "id": "f3719cf8", "metadata": {}, "source": [ - "\n", - "The plot of the solution shows the path that satisfies all boundary\n", - "condition. The last subplot is time, which is redundant here but\n", - "the `DeterministicOde.plot` method is not yet able to recognize the time\n", - "component. Possible speed up can be achieved through the use of\n", - "derivative information or via the root finding method that tackles the\n", - "gradient directly, instead of the cost function.\n", - "\n", - "#TODO add meth/fun/class refs for root finding method, derivative" + "We see that the result of $g=10ms^{-2}$ is recovered" ] }, { - "cell_type": "markdown", - "id": "cb79c4f6", + "cell_type": "code", + "execution_count": 7, + "id": "1be53116", "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: Optimization terminated successfully.\n", + " success: True\n", + " status: 0\n", + " fun: 1.1241808584714344e-15\n", + " x: [ 1.000e+01]\n", + " nit: 4\n", + " jac: [-1.068e-11]\n", + " hess_inv: [[ 2.469e-02]]\n", + " nfev: 10\n", + " njev: 5\n" + ] + } + ], "source": [ - "\n", - "**Reference**\n", - "\n", - "[1] " + "print(thetaHat)" ] } ], diff --git a/docs/notebooks/paramfit/params_via_abc.ipynb b/docs/notebooks/paramfit/params_via_abc.ipynb index 8592329b..73d76ac7 100644 --- a/docs/notebooks/paramfit/params_via_abc.ipynb +++ b/docs/notebooks/paramfit/params_via_abc.ipynb @@ -13,15 +13,14 @@ "id": "05daf2f1", "metadata": {}, "source": [ - "An exercise central to the study of infectious diseases is inference of epidemic parameters from incidence data.\n", - "In this chapter we demonstrate how PyGOM uses Approximate Bayesian Computation to offer estimates for parameters with credible intervals.\n", + "Here we demonstrate how PyGOM uses Approximate Bayesian Computation to estimate posterior distributions for parameters.\n", "\n", - "As an example, we use a synthetic data set produced by PyGOM's `solve_stochast ` function.\n", + "As an example, we use a synthetic data set produced by PyGOM's {func}`solve_stochast ` function.\n", "This is a stochastic epidemic simulation of an SEIR model with parameters:\n", "\n", "$\\beta=0.35,\\quad \\alpha=0.5,\\quad \\gamma=0.25,\\quad n_{\\text{pop}}=10^4,\\quad I(t=0)=5$\n", "\n", - "Loading in the data file" + "Loading in the data file:" ] }, { @@ -43,7 +42,7 @@ "id": "0ba66de0", "metadata": {}, "source": [ - "We inspect the time series of the infected and removed populations." + "We inspect the time series of the infected and removed populations:" ] }, { @@ -80,7 +79,9 @@ "axarr[0].scatter(t, sol_i_r[:,0])\n", "axarr[1].scatter(t, sol_i_r[:,1])\n", "axarr[0].set_title('I')\n", - "axarr[1].set_title('R')" + "axarr[1].set_title('R')\n", + "axarr[0].set_xlabel('Time')\n", + "axarr[1].set_xlabel('Time');" ] }, { @@ -89,21 +90,15 @@ "metadata": {}, "source": [ "```{note}\n", - "We typically do not have access to information regarding the total infected population. More commonly reported is the number of new cases in a given time period (or infection times). Furthermore, we are unlikely to know the removed population, unless, for example, the disease results in death.\n", + "We typically do not have access to information regarding the total infected population. More commonly reported is the number of new cases in a given time period (or infection times).\n", + "Furthermore, we are unlikely to know the removed population, unless, for example, the disease results in death.\n", + "Nevertheless, the purpose of this chapter is to demonstrate model fitting given a data set and so these departures from reality shouldn't undermine the key messages.\n", + "```\n", "\n", - "The purpose of this chapter is to demonstrate model fitting given a set of data and so these departures from reality shouldn't undermine the key messages.\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "ba9907fd", - "metadata": {}, - "source": [ "In the next sections, we are going to use PyGOM to obtain estimates for unknown values $\\beta$, $\\alpha$ and $\\gamma$ (assuming that the total population $N$ and initial number of infecteds $I(t=0)$ are known).\n", "\n", "```{note}\n", - "Again, it is rather unrealistic to know $I(t=0)$ or $N$\n", + "Again, it is rather unrealistic to know $I(t=0)$ or $N$, but we proceed in this way for the sake of simplicity in our example.\n", "```" ] }, @@ -114,10 +109,10 @@ "source": [ "## Fitting an SEIR model (with Infected and Removed known)\n", "\n", - "To obtain parameter estimates from data, we must provide a candidate model and specify the unknown parameters which we are interested in. Information regarding the candidate model is contained in `abc.create_loss()`, which requires:\n", - "1) A `SimulateOde` object which describes the system of ODE's\n", - "2) The loss function, which describes how we assume observations are distributed about the mean value (calculated via the `SimulateOde` object)\n", - "3) `abc.Parameter` which tells us which parameters we are interested in and their prior distributions.\n", + "To obtain parameter estimates from data, we must provide a candidate model and specify the unknown parameters which we are interested in. Information regarding the candidate model is contained in {func}`abc.create_loss`, which requires:\n", + "1) A {class}`SimulateOde` object which describes the system of ODEs\n", + "2) The loss function, which describes how we assume observations are distributed about the mean value calculated from the {class}`SimulateOde` object.\n", + "3) `abc.Parameter` which informs which parameters we are interested in and their prior distributions.\n", "4) The data to which we are fitting\n", "\n", "We start by specifying the ODE system. In this first example, we are going to assume (correctly) that the underlying process is an SEIR model.\n", @@ -147,8 +142,8 @@ "id": "da9675c6", "metadata": {}, "source": [ - "The `Parameter` class is used to specify the parameters we wish to infer and their prior probability distributions.\n", - "We can choose from any of the distributions included in Pygom, here we use a uniform distribution." + "The {class}`Parameter` class is used to specify the parameters we wish to infer and their prior probability distributions.\n", + "We can choose from any of the distributions included in PyGOM, here we take uniform distributions." ] }, { @@ -170,8 +165,9 @@ "id": "11aa81ca", "metadata": {}, "source": [ - "Finally, we must decide how observations are produced from the underlying model.\n", - "If we assume that each data point is the result of a random draw from a poisson process with mean equal to the SEIR model output at that timepoint, we use the option `PoissonLoss` as our loss function when calling `create_loss` below. Now we combine everything together, including the initial conditions which we are assuming are known." + "Finally, we must specify how observations are produced from the underlying model.\n", + "If we assume that each data point is the result of a random draw from a poisson process with mean equal to the SEIR model output at that timepoint, we use the option `PoissonLoss` as our loss function when calling `create_loss` below.\n", + "Now we combine everything together, including the initial conditions which we are assuming to be known." ] }, { @@ -188,7 +184,7 @@ "\n", "objSEIR = abc.create_loss(\"PoissonLoss\", # Loss function\n", " parameters, # Unknown parameters and prior distributions\n", - " ode_SEIR, # Model\n", + " ode_SEIR, # Model\n", " x0, t[0], # Initial conditions and timepoints\n", " t[1:], sol_i_r[1:,:], # Data timepoints and I, R values\n", " ['I', 'R']) # Names of compartments in data\n", @@ -201,7 +197,7 @@ "id": "4009b7ba", "metadata": {}, "source": [ - "A sequential Monte Carlo method (ABC-SMC) is used for param inference. This approach considers a series of generations, with each generation using a smaller threshold than the previous. The first generation is equivalent to the standard ABC algorithm, in the sense that parameters are sampled from prior distributions. In subsequent generations, candidate parameters are proposed by perturbing weighted samples from the previous generation. Here, we use a multivariate normal distribution with optimal local covariance matrix to perform the perturbation.\n", + "A sequential Monte Carlo method (ABC-SMC) is used for parameter inference. This approach considers a series of generations, with each generation using a smaller threshold than the previous. The first generation is equivalent to the standard ABC algorithm, in the sense that parameters are sampled from prior distributions. In subsequent generations, candidate parameters are proposed by perturbing weighted samples from the previous generation. Here, we use a multivariate normal distribution with optimal local covariance matrix to perform the perturbation.\n", "\n", "The ABC-SMC method requires a couple of additional arguments to `get_posterior_sample`:\n", "- G - the number of generations\n", @@ -228,7 +224,9 @@ "id": "c950e11a", "metadata": {}, "source": [ - "If we want to run the method for a few more generations, there is no need to start from the beginning. Instead, we can use `continue_posterior_sample` along with the `next_tol` attribute to set the tolerance. Let's perform 2 additional iterations." + "If we want to run the method for a few more generations, there is no need to start from the beginning.\n", + "Instead, we can use {func}`continue_posterior_sample` along with the `next_tol` attribute to set the tolerance.\n", + "Let's perform 2 additional iterations." ] }, { @@ -256,7 +254,7 @@ "metadata": {}, "outputs": [], "source": [ - "abcSEIR.plot_posterior_histograms();\n", + "abcSEIR.plot_posterior_histograms()\n", "abcSEIR.plot_pointwise_predictions();" ] }, @@ -266,7 +264,8 @@ "metadata": {}, "source": [ "The posterior draws are contained within `abcSIR.res`.\n", - "This can be useful if output needs to be saved, or for calculation credible intervals." + "This can be useful if output needs to be saved, or for calculation credible intervals.\n", + "We see here that the 95% credible intervals are consistent with the true parameter values." ] }, { @@ -289,7 +288,8 @@ "## Fitting an SEIR model (with only Infected known)\n", "\n", "We now fit the same model, but assume we only have access to data concerning the infected component.\n", - "All that changes code-wise is that we omit the recovered time series when inputting the data and specify that we only have information for the infected population in the last argument of `create_loss`. We run the ABC algorithm for 8 generations." + "All that changes code-wise is that we omit the recovered time series when inputting the data and specify that we only have information for the infected population in the last argument of `create_loss`.\n", + "We do this and run the ABC algorithm for 8 generations." ] }, { @@ -416,11 +416,12 @@ "id": "c6542afd", "metadata": {}, "source": [ - "We still see good estimates, even though we have constrained the model with one fewer state.\n", + "We still see estimates in agreement with the true parameter values, even though we have constrained the model with one fewer state.\n", "\n", "## Fitting an SIR model (with only Infected known)\n", "\n", - "Of course, we may not know the underlying mechanisms and might instead attempt to fit an SIR model to the infected data.\n" + "Of course, we may not know the underlying mechanisms and might instead attempt to fit an SIR model to the infected data.\n", + "We follow similar steps as before, but now specifying and SIR model." ] }, { @@ -456,7 +457,8 @@ "id": "4f3d6704", "metadata": {}, "source": [ - "Although we see smaller CI's this actually reflects the difficulty in model fitting and is not an indication of precision." + "Although we see smaller credible intervals, this actually reflects the restriction in model fitting, rather than increased precision.\n", + "We see that our inappropriate model choice here results in poorer parameter estimates." ] }, { @@ -499,7 +501,8 @@ "id": "061f2654", "metadata": {}, "source": [ - "The remaining code remains the same as before. Again we still need to pass variables even if they are unknown. In this case i0." + "The remaining code is the same as before.\n", + "Again, we still need to pass variables even if they are unknown - in this case the initial number of infected individuals." ] }, { @@ -522,6 +525,14 @@ "abcSEIR3 = abc.ABC(objSEIR3, parameters)" ] }, + { + "cell_type": "markdown", + "id": "ca183311", + "metadata": {}, + "source": [ + "We run the algorithm for 8 generations:" + ] + }, { "cell_type": "code", "execution_count": 18, @@ -638,6 +649,15 @@ "print(f'gamma={np.median(abcSEIR3.res[:,2]):.3f} ({np.quantile(abcSEIR3.res[:,2], 0.025):.3f}, {np.quantile(abcSEIR3.res[:,2], 0.975):.3f})')\n", "print(f'I0={np.median(abcSEIR3.res[:,3]):.3f} ({np.quantile(abcSEIR3.res[:,3], 0.025):.3f}, {np.quantile(abcSEIR3.res[:,3], 0.975):.3f})')" ] + }, + { + "cell_type": "markdown", + "id": "c76a2d1b", + "metadata": {}, + "source": [ + "Whilst credible intervals are consistent with our parameters, they are wider than before.\n", + "This is because with increased numbers of parameters there are more ways for our model to fit the data." + ] } ], "metadata": { diff --git a/docs/notebooks/paramfit/params_via_optimization.ipynb b/docs/notebooks/paramfit/params_via_optimization.ipynb index 9aea1023..c73c3d9a 100644 --- a/docs/notebooks/paramfit/params_via_optimization.ipynb +++ b/docs/notebooks/paramfit/params_via_optimization.ipynb @@ -4,25 +4,24 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Parameter Estimation: Optimization\n", + "# Parameter Estimation: Maximum likelihood\n", "\n", "In the previous section, we've seen how to use Markov Chain Monte Carlo methods to estimate the posterior probability distribution of parameters.\n", - "These methods have generally replaced older techniques which use algorithms to infer the most likely parameter values, with confidence intervals provided after making assumptions about the local likelihood landscape.\n", - "PyGOM has the capability to estimate parameters in this way in addition to ABC.\n", - "Although perhaps outdated, including these methods could still be practical if trying to reproduce work from older publications, for example.\n", + "These methods have generally replaced techniques which use algorithms to infer the maximum likelihood estimates (MLE) of parameter values, with confidence levels provided after making assumptions about the local likelihood landscape.\n", + "PyGOM has the capability to estimate parameters in this way and although perhaps outdated, including these methods could still be practical if trying to reproduce work from older publications, for example.\n", "\n", "## Example: SEIR model (with I and R known)\n", "\n", - "We now solve the same problem as in the previous section,this time via optimization of the cost fucntion.\n", - "As a reminder: We have an SEIR model where time series of $I$ and $R$ are known and we wish to estimate $\\beta$, $\\alpha$ and $\\gamma$ with true values 0.35, 0.5 and 0.25 respectively.\n", - "The total population, $N=10,000$ and the initial number infected, $i_0=5$, are both known.\n", + "We now solve the same problem as in the previous section, this time via minimisation of the cost function.\n", + "As a reminder: We have data from an SEIR system where the time series of $I$ and $R$ are known and we wish to estimate parameters $\\beta$, $\\alpha$ and $\\gamma$ with true values 0.35, 0.5 and 0.25 respectively.\n", + "We assume that the total population, $N=10,000$ and the initial number infecteds, $i_0=5$, are both known.\n", "\n", - "We start by loading the data again" + "We start by loading the data again:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "efea520f", "metadata": {}, "outputs": [], @@ -48,7 +47,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "857371e4", "metadata": {}, "outputs": [], @@ -65,12 +64,12 @@ "id": "80c83797", "metadata": {}, "source": [ - "We provide an initial guess in `theta` and pass all relevant info, including initial conditions `x0`, to build an object of class `PoissonLoss`" + "We provide an initial guess in `theta` and pass all other required information, including initial conditions `x0`, to build an object of class {class}`PoissonLoss`" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "88ad9325", "metadata": {}, "outputs": [], @@ -110,7 +109,7 @@ "## Gradient calculations\n", "\n", "How the parameter optimizer will navigate parameter space will depend on the gradient of the cost function with respect to the parameters.\n", - "PyGOM can calculate the gradient in two different ways, which are explained in more detail in {doc}`.gradient`\n", + "PyGOM can calculate the gradient in two different ways.\n", "First, let's compare the outputs of the two methods when evaluated at the initial condition, `theta`:" ] }, @@ -161,7 +160,7 @@ "```{note}\n", "Note how we ran the two gradient functions once before timing it, that is because we only find the properties (Jacobian, gradient) of the ODEs during runtime.\n", "\n", - "The amount of time taken for both method is dependent on the number of observations as well as the number of states.\n", + "The amount of time taken for both methods is dependent on the number of observations as well as the number of states.\n", "The effect on the adjoint method as the number of observations differs can be quite evident.\n", "This is because the adjoint method is under a discretization which loops in Python where as the forward sensitivity equations are solved via an integration.\n", "As the number of observation gets larger, the affect of the Python loop becomes more obvious.\n", @@ -181,15 +180,15 @@ "id": "543ec840", "metadata": {}, "source": [ - "## Optimized result\n", + "## Optimised result\n", "\n", - "We now employ optimization procedures which should progress from the initial guess (if the initial guess is sensible enough) to the parameter set which minimises our cost function.\n", + "We now employ optimisation procedures which should progress from the initial guess (if the initial guess is sensible enough) to the parameter set which minimises our cost function.\n", "It is particularly important to set the boundaries for the parameters here, since we know that they are required to be positive." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "ff093f77", "metadata": {}, "outputs": [], @@ -210,10 +209,26 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "83eca0ba", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: Optimization terminated successfully\n", + " success: True\n", + " status: 0\n", + " fun: 1651.128217170814\n", + " x: [ 3.537e-01 5.384e-01 2.559e-01]\n", + " nit: 17\n", + " jac: [-4.531e+00 -3.594e-01 4.575e+00]\n", + " nfev: 29\n", + " njev: 17\n" + ] + } + ], "source": [ "from scipy.optimize import minimize\n", "\n", @@ -231,15 +246,26 @@ "id": "912700fc", "metadata": {}, "source": [ - "We see that parameter values in agreement with the underlying model are recovered and there is visual agreement with data when plotted below" + "We see that parameter values are in agreement with the underlying model and there is visual agreement with data when plotted below" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "c826a9db", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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Eh4eLr/++qvRU5vTa6+9JpGRkdLY2Ch9fX2Bx8jIiIiI+Hw+2bdvn1y4cEG8Xq80NDRIZmam3HfffXLjxg2DZ6+3b98+aWxslCtXrsjFixclLy9PIiIiAj04cuSIREZGSm1trbS3t8vzzz8vcXFxytUxaXx8XNatWyf79+/XjZuhJz6fT9ra2qStrU0AyNGjR6WtrS3w7a/B9KKkpETi4+Olvr5eWltbJTs7W1JTU+X27dvK1OL3+yU/P1/i4+Pl+++/1x1Do6OjIiLyyy+/yNtvvy3Nzc3i9Xqlrq5ONmzYIA8++KBStQS7X5mhL5OGh4dl9erV8uGHH057vUp9me88LGKuY8aqzJjzVsp4Eea8Kn1hxjPjjaxlEjN+cXuz4hfzIiIffPCBJCQkiMPhkLS0NN2tX1QFYMbHyZMnRURkZGREcnJy5N577xW73S7r1q2ToqIi6enpMXbiMygoKJC4uDix2+3idrtl27Zt0tHREXh+YmJCKisrxeVyidPplE2bNkl7e7uBM57b119/LQCks7NTN26GnjQ0NMy4XxUVFYlIcL3466+/pLS0VKKioiQsLEzy8vIMqXGuWrxe76zHUENDg4iI9PT0yKZNmyQqKkocDockJSXJ66+/LoODg0rVEux+ZYa+TDpx4oSEhYXJ0NDQtNer1Jf5zsMi5jpmrMxsOW+ljBdhzqvSF2Y8M97IWiYx4xe3N9p/J0tEREREREREJrGi/888ERERERERkRlxMU9ERERERERkMlzMExEREREREZkMF/NEREREREREJsPFPBEREREREZHJcDFPREREREREZDJczBMRERERERGZDBfzRERERERERCbDxTwRERERERGRyXAxT0RERERERGQyXMwTERERERERmcx/ANqx/JRc1uIQAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "pars=res.x\n", "\n", @@ -261,7 +287,33 @@ "id": "f79d99fc", "metadata": {}, "source": [ - "The problem is only partially solved, however, since we must now do more work to estimate CI's." + "## Confidence intervals of estimated parameters\n", + "\n", + "Point estimates of parameters found via MLE provide the *best* fit, but are incomplete without some measure of their uncertainty.\n", + "With the ABC method of the previous section, credible intervals fall out as part of the fitting process, since the output is parameter probability distributions.\n", + "For parameter estimates found via optimisation, we need to make some assumptions about the shape of the likelihood function in the neighbourhood of the MLE to obtain confidence levels.\n", + "\n", + "```{warning}\n", + "PyGOM has built in functions using different methods to solve this problem.\n", + "These are, however, under development.\n", + "The location and names of the relevant code can be found below and they should be carefully inspected before being employed.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "1ab2d9b6", + "metadata": {}, + "outputs": [], + "source": [ + "#from pygom import confidence_interval as ci\n", + "\n", + "## Different methods for CIs:\n", + "# ci.asymptotic\n", + "# ci.profile\n", + "# ci.bootstrap\n", + "# ci.geometric" ] } ], diff --git a/docs/notebooks/paramfit/profile.ipynb b/docs/notebooks/paramfit/profile.ipynb index 8e8d3def..00f54623 100644 --- a/docs/notebooks/paramfit/profile.ipynb +++ b/docs/notebooks/paramfit/profile.ipynb @@ -30,9 +30,11 @@ ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 1, "id": "efed1abf", "metadata": {}, + "outputs": [], "source": [ "from pygom import NormalLoss, common_models\n", "\n", @@ -61,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "b8425085", "metadata": {}, "outputs": [], @@ -119,9 +121,20 @@ ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 3, "id": "9f93e2ba", "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0.30563305 0.15211495]\n", + "[0.69392383 0.51349773]\n" + ] + } + ], "source": [ "from pygom import confidence_interval as ci\n", "\n", @@ -129,14 +142,7 @@ "\n", "xL, xU = ci.asymptotic(objSIR, alpha, xhat, lb=boxBoundsArray[:,0], ub=boxBoundsArray[:,1])\n", "\n", - "print(xL)" - ] - }, - { - "cell_type": "markdown", - "id": "7eae33a2", - "metadata": {}, - "source": [ + "print(xL)\n", "print(xU)" ] }, @@ -210,7 +216,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "7dab2b66", "metadata": {}, "outputs": [], @@ -237,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "e58e47ee", "metadata": {}, "outputs": [], @@ -324,20 +330,24 @@ ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 6, "id": "eb9240d7", "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0.21802959 0.04961695]\n", + "[1.26151364 1.06296231]\n" + ] + } + ], "source": [ "xLGeometric, xUGeometric, xLList, xUList = ci.geometric(objSIR, alpha, xhat, full_output=True)\n", "\n", - "print(xLGeometric)" - ] - }, - { - "cell_type": "markdown", - "id": "f09236cc", - "metadata": {}, - "source": [ + "print(xLGeometric)\n", "print(xUGeometric)" ] }, @@ -384,20 +394,31 @@ ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 7, "id": "d33c189c", "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING:root:Number of iterations (10) is low. Consider using more.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0.49842726 0.33142003]\n", + "[0.50466089 0.33727478]\n" + ] + } + ], "source": [ "xLBootstrap, xUBootstrap, setX = ci.bootstrap(objSIR, alpha, xhat, iteration=10, lb=boxBoundsArray[:,0], ub=boxBoundsArray[:,1], full_output=True)\n", "\n", - "print(xLBootstrap)" - ] - }, - { - "cell_type": "markdown", - "id": "90e0585e", - "metadata": {}, - "source": [ + "print(xLBootstrap)\n", "print(xUBootstrap)" ] }, @@ -420,14 +441,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "c585db79", "metadata": { "vscode": { "languageId": "javascript" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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CDI15s779u2Lvn37lrq+nZ0d7OzslPVt27bhn3/+wejRo1X1dDodnJ2dK6yfRERE9Hip1tcgrVmzBk899RTc3NxU5Tdv3oSbmxsaNGiAAQMGICkpyUg9JCIiourIqEeQHoRer8fu3bvx1Vdfqcq9vLwQGRmJ1q1bIysrC4sXL0bnzp2RkpKCZs2aFdlWTk4OcnJylPWsrKxK7TsRERFVbdX2CFJkZCRq166NwYMHq8o7duyIF154AT4+PujatSs2bdqE5s2bY+nSpcW2FR4erpy+s7OzQ8OGDSu590RERFSVVcuAJCL4/PPPERwcDHNz8xLr1qhRA0888QTOnTtXbJ3Q0FBkZmYqS1paWkV3mYiIiKqRanmKLSEhAefPn8fYsWPvW1dEkJycjNatWxdbx8LCAhYWFhXZRSIiIqrGjBqQbt68ifPnzyvrFy9eRHJyMuzt7dGoUSOEhobi8uXLWLdunWq7NWvWwN/fH61atTJoMywsDB07dkSzZs2QlZWFJUuWIDk5GZ988kmlj4eIiIgeDUYNSCdPnkTPnj2V9WnTpgEAQkJCEBkZCb1ej9TUVNU2mZmZiImJweLFi4ts8/r163j55ZeRnp4OOzs7+Pr64vDhw+jQoUPlDYSIiIgeKToREWN3oqrJysqCnZ0dMjMzYWtra+zuUCVyn/HNfev8/n7/h9ATIiJ6UBX5+V0tL9ImIiIiqkwMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGkYNSIcPH8bAgQPh6uoKnU6Hbdu2lVg/Pj4eOp3OYDlz5oyqXkxMDLy9vWFhYQFvb29s3bq1EkdBREREjxqjBqTs7Gz4+Phg2bJlZdru7Nmz0Ov1ytKsWTPlscTERAwbNgzBwcFISUlBcHAwhg4diuPHj1d094mIiOgRZWrMnfft2xd9+/Yt83aOjo6o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EPLz85Gfn4+DBw9i8uTJGD58eEX3kYiIiOihKtddbO+99x4uXbqEwMBAmJrebaKgoAAjR47kNUhERERU7ZUrIJmbmyM6Ohrz5s1DSkoKrKys0Lp1a7i5uVV0/4iIiIgeunIFpELNmzdH8+bNK6ovRERERFVCuQJSfn4+IiMjceDAAWRkZKCgoED1+MGDByukc0RERETGUK6ANHnyZERGRqJ///5o1aoVdDpdRfeLiIiIyGjKFZA2btyITZs2oV+/fhXdHyIiIiKjK9dt/ubm5mjatGlF94WIiIioSihXQHr99dexePFiiEhF94eIiIjI6Mp1iu3IkSM4dOgQdu/ejZYtW8LMzEz1+JYtWyqkc0RERETGUK6AVLt2bTz99NMV3RciIiKiKqFcAWnt2rUV3Q8iIiKiKqNc1yABQF5eHvbv349Vq1bhxo0bAIA///wTN2/erLDOERERERlDuY4gXbp0CX369EFqaipycnLQq1cv2NjY4IMPPsDt27excuXKiu4nERER0UNTriNIkydPRvv27fHPP//AyspKKX/66adx4MCBCuscERERkTGU+y627777Dubm5qpyNzc3XL58uUI6RkRERGQs5TqCVFBQgPz8fIPyP/74AzY2Ng/cKSIiIiJjKldA6tWrFyIiIpR1nU6HmzdvYvbs2fz5ESIiIqr2ynWK7eOPP0bPnj3h7e2N27dvY8SIETh37hzq1q2LqKioiu4jERER0UNVroDk6uqK5ORkREVF4dSpUygoKMDYsWPx/PPPqy7aJiIiIqqOyhWQAMDKygpjxozBmDFjKrI/REREREZXroC0bt26Eh8fOXJkuTpDREREVBWUKyBNnjxZtX7nzh3cunUL5ubmqFmzJgMSERERVWvluovtn3/+US03b97E2bNn0aVLF16kTURERNVeuX+LTatZs2Z4//33DY4uleTw4cMYOHAgXF1dodPpsG3btvtuk5CQAD8/P1haWqJx48ZF/qxJTEwMvL29YWFhAW9vb2zdurUsQyEiIqLHXIUFJAAwMTHBn3/+Wer62dnZ8PHxwbJly0pV/+LFi+jXrx+6du2KpKQkvP3223jttdcQExOj1ElMTMSwYcMQHByMlJQUBAcHY+jQoTh+/HiZx0NERESPJ52ISFk32rFjh2pdRKDX67Fs2TI0bNgQu3fvLntHdDps3boVgwcPLrbOW2+9hR07duD06dNK2bhx45CSkoLExEQAwLBhw5CVlaXqQ58+fVCnTp1Sn/7LysqCnZ0dMjMzYWtrW+axUPXhPuOb+9b5/f3+D6EnRET0oCry87tcF2lrQ4xOp0O9evXw5JNP4qOPPnqgDpUkMTERQUFBqrLevXtjzZo1uHPnDszMzJCYmIipU6ca1Ln3m7+JiIiISlKugFRQUFDR/SiV9PR0ODk5qcqcnJyQl5eHq1evwsXFpdg66enpxbabk5ODnJwcZT0rK6tiO05ERETVSrm/KNJYdDqdar3wDOG95UXV0ZbdKzw8HGFhYRXYy5JVx9M6j2qfK6qdihp7dZznqoZzSI+a6vicro591ipXQJo2bVqp6y5atKg8uyiSs7OzwZGgjIwMmJqawsHBocQ62qNK9woNDVWNKSsrCw0bNqywfhMREVH1Uq6AlJSUhFOnTiEvLw+enp4AgF9//RUmJiZo166dUq+kozblERAQgJ07d6rK9u3bh/bt28PMzEypExcXp7oOad++fejUqVOx7VpYWMDCwqJC+0pERETVV7kC0sCBA2FjY4MvvvgCderUAXD3yyNHjx6Nrl274vXXXy9VOzdv3sT58+eV9YsXLyI5ORn29vZo1KgRQkNDcfnyZeWnTcaNG4dly5Zh2rRpeOmll5CYmIg1a9ao7k6bPHkyunXrhgULFmDQoEHYvn079u/fjyNHjpRnqERERPQYKtf3IH300UcIDw9XwhEA1KlTB++9916Z7mI7efIkfH194evrC+DuqTtfX1/MmjULAKDX65GamqrU9/DwQGxsLOLj49G2bVvMmzcPS5YswbPPPqvU6dSpEzZu3Ii1a9eiTZs2iIyMRHR0NPz9/cszVCIiInoMlesIUlZWFv766y+0bNlSVZ6RkYEbN26Uup0ePXqgpK9hioyMNCjr3r07Tp06VWK7Q4YMwZAhQ0rdDyIiIqJ7lesI0tNPP43Ro0fj66+/xh9//IE//vgDX3/9NcaOHYtnnnmmovtIRERE9FCV6wjSypUrMX36dLzwwgu4c+fO3YZMTTF27FgsXLiwQjtIRERE9LCVKyDVrFkTy5cvx8KFC3HhwgWICJo2bQpra+uK7h8RERHRQ/dAP1ar1+uh1+vRvHlzWFtbl3g9EREREVF1Ua6AdO3aNQQGBqJ58+bo168f9Ho9AODFF18s9S3+RERERFVVuQLS1KlTYWZmhtTUVNSsWVMpHzZsGPbs2VNhnSMiIiIyhnJdg7Rv3z7s3bsXDRo0UJU3a9YMly5dqpCOERERERlLuY4gZWdnq44cFbp69Sp/soOIiIiqvXIFpG7duik//wHc/c21goICLFy4ED179qywzhEREREZQ7lOsS1cuBA9evTAyZMnkZubizfffBM///wz/v77b3z33XcV3UciIiKih6pcR5C8vb3x448/okOHDujVqxeys7PxzDPPICkpCU2aNKnoPhIRERE9VGU+gnTnzh0EBQVh1apVCAsLq4w+ERERERlVmY8gmZmZ4aeffoJOp6uM/hAREREZXblOsY0cORJr1qyp6L4QERERVQnlukg7NzcXn332GeLi4tC+fXuD32BbtGhRhXSOiIiIyBjKFJB+++03uLu746effkK7du0AAL/++quqDk+9ERERUXVXpoDUrFkz6PV6HDp0CMDdnxZZsmQJnJycKqVzRERERMZQpmuQRES1vnv3bmRnZ1doh4iIiIiMrVwXaRfSBiYiIiKiR0GZApJOpzO4xojXHBEREdGjpkzXIIkIRo0apfwg7e3btzFu3DiDu9i2bNlScT0kIiIiesjKFJBCQkJU6y+88EKFdoaIiIioKihTQFq7dm1l9YOIiIioynigi7SJiIiIHkUMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBoMSEREREQaDEhEREREGgxIRERERBpGD0jLly+Hh4cHLC0t4efnh2+//bbYuqNGjYJOpzNYWrZsqdSJjIwsss7t27cfxnCIiIjoEWDUgBQdHY0pU6Zg5syZSEpKQteuXdG3b1+kpqYWWX/x4sXQ6/XKkpaWBnt7e/z3v/9V1bO1tVXV0+v1sLS0fBhDIiIiokeAUQPSokWLMHbsWLz44oto0aIFIiIi0LBhQ6xYsaLI+nZ2dnB2dlaWkydP4p9//sHo0aNV9XQ6naqes7PzwxgOERERPSKMFpByc3Pxww8/ICgoSFUeFBSEo0ePlqqNNWvW4KmnnoKbm5uq/ObNm3Bzc0ODBg0wYMAAJCUlVVi/iYiI6NFnaqwdX716Ffn5+XByclKVOzk5IT09/b7b6/V67N69G1999ZWq3MvLC5GRkWjdujWysrKwePFidO7cGSkpKWjWrFmRbeXk5CAnJ0dZz8rKKseIiIiI6FFh9Iu0dTqdal1EDMqKEhkZidq1a2Pw4MGq8o4dO+KFF16Aj48Punbtik2bNqF58+ZYunRpsW2Fh4fDzs5OWRo2bFiusRAREdGjwWgBqW7dujAxMTE4WpSRkWFwVElLRPD5558jODgY5ubmJdatUaMGnnjiCZw7d67YOqGhocjMzFSWtLS00g+EiIiIHjlGC0jm5ubw8/NDXFycqjwuLg6dOnUqcduEhAScP38eY8eOve9+RATJyclwcXEpto6FhQVsbW1VCxERET2+jHYNEgBMmzYNwcHBaN++PQICArB69WqkpqZi3LhxAO4e2bl8+TLWrVun2m7NmjXw9/dHq1atDNoMCwtDx44d0axZM2RlZWHJkiVITk7GJ5988lDGRERERNWfUQPSsGHDcO3aNcydOxd6vR6tWrVCbGyscleaXq83+E6kzMxMxMTEYPHixUW2ef36dbz88stIT0+HnZ0dfH19cfjwYXTo0KHSx0NERESPBqMGJACYMGECJkyYUORjkZGRBmV2dna4detWse19/PHH+Pjjjyuqe0RERPQYMvpdbERERERVDQMSERERkQYDEhEREZEGAxIRERGRBgMSERERkQYDEhEREZEGAxIRERGRBgMSERERkQYDEhEREZEGAxIRERGRBgMSERERkQYDEhEREZEGAxIRERGRBgMSERERkQYDEhEREZEGAxIRERGRBgMSERERkQYDEhEREZEGAxIRERGRBgMSERERkQYDEhEREZEGAxIRERGRBgMSERERkQYDEhEREZEGAxIRERGRBgMSERERkQYDEhEREZEGAxIRERGRBgMSERERkQYDEhEREZEGAxIRERGRBgMSERERkQYDEhEREZGG0QPS8uXL4eHhAUtLS/j5+eHbb78ttm58fDx0Op3BcubMGVW9mJgYeHt7w8LCAt7e3ti6dWtlD4OIiIgeIUYNSNHR0ZgyZQpmzpyJpKQkdO3aFX379kVqamqJ2509exZ6vV5ZmjVrpjyWmJiIYcOGITg4GCkpKQgODsbQoUNx/Pjxyh4OERERPSKMGpAWLVqEsWPH4sUXX0SLFi0QERGBhg0bYsWKFSVu5+joCGdnZ2UxMTFRHouIiECvXr0QGhoKLy8vhIaGIjAwEBEREZU8GiIiInpUGC0g5ebm4ocffkBQUJCqPCgoCEePHi1xW19fX7i4uCAwMBCHDh1SPZaYmGjQZu/eve/bJhEREVEhU2Pt+OrVq8jPz4eTk5Oq3MnJCenp6UVu4+LigtWrV8PPzw85OTlYv349AgMDER8fj27dugEA0tPTy9QmAOTk5CAnJ0dZz8rKKu+wiIiI6BFgtIBUSKfTqdZFxKCskKenJzw9PZX1gIAApKWl4cMPP1QCUlnbBIDw8HCEhYWVp/tERET0CDLaKba6devCxMTE4MhORkaGwRGgknTs2BHnzp1T1p2dncvcZmhoKDIzM5UlLS2t1PsnIiKiR4/RApK5uTn8/PwQFxenKo+Li0OnTp1K3U5SUhJcXFyU9YCAAIM29+3bV2KbFhYWsLW1VS1ERET0+DLqKbZp06YhODgY7du3R0BAAFavXo3U1FSMGzcOwN0jO5cvX8a6desA3L1Dzd3dHS1btkRubi42bNiAmJgYxMTEKG1OnjwZ3bp1w4IFCzBo0CBs374d+/fvx5EjR4wyRiIiIqp+jBqQhg0bhmvXrmHu3LnQ6/Vo1aoVYmNj4ebmBgDQ6/Wq70TKzc3F9OnTcfnyZVhZWaFly5b45ptv0K9fP6VOp06dsHHjRrzzzjt499130aRJE0RHR8Pf3/+hj4+IiIiqJ6NfpD1hwgRMmDChyMciIyNV62+++SbefPPN+7Y5ZMgQDBkypCK6R0RERI8ho//UCBEREVFVw4BEREREpMGARERERKTBgERERESkwYBEREREpMGARERERKTBgERERESkwYBEREREpMGARERERKTBgERERESkwYBEREREpMGARERERKTBgERERESkwYBEREREpMGARERERKTBgERERESkwYBEREREpMGARERERKTBgERERESkwYBEREREpMGARERERKTBgERERESkwYBEREREpMGARERERKTBgERERESkwYBEREREpMGARERERKTBgERERESkwYBEREREpMGARERERKTBgERERESkwYBEREREpMGARERERKRh9IC0fPlyeHh4wNLSEn5+fvj222+Lrbtlyxb06tUL9erVg62tLQICArB3715VncjISOh0OoPl9u3blT0UIiIiekQYNSBFR0djypQpmDlzJpKSktC1a1f07dsXqampRdY/fPgwevXqhdjYWPzwww/o2bMnBg4ciKSkJFU9W1tb6PV61WJpafkwhkRERESPAFNj7nzRokUYO3YsXnzxRQBAREQE9u7dixUrViA8PNygfkREhGp9/vz52L59O3bu3AlfX1+lXKfTwdnZuVL7TkRERI8uox1Bys3NxQ8//ICgoCBVeVBQEI4ePVqqNgoKCnDjxg3Y29urym/evAk3Nzc0aNAAAwYMMDjCRERERFQSowWkq1evIj8/H05OTqpyJycnpKenl6qNjz76CNnZ2Rg6dKhS5uXlhcjISOzYsQNRUVGwtLRE586dce7cuWLbycnJQVZWlmohIiKix5dRT7EBd0+H3UtEDMqKEhUVhTlz5mD79u1wdHRUyjt27IiOHTsq6507d0a7du2wdOlSLFmypMi2wsPDERYWVs4REBER0aPGaEeQ6tatCxMTE4OjRRkZGQZHlbSio6MxduxYbNq0CU899VSJdWvUqIEnnniixCNIoaGhyMzMVJa0tLTSD4SIiIgeOUYLSObm5vDz80NcXJyqPC4uDp06dSp2u6ioKIwaNQpfffUV+vfvf9/9iAiSk5Ph4uJSbB0LCwvY2tqqFiIiInp8GfUU27Rp0xAcHIz27dsjICAAq1evRmpqKsaNGwfg7pGdy5cvY926dQDuhqORI0di8eLF6Nixo3L0ycrKCnZ2dgCAsLAwdOzYEc2aNUNWVhaWLFmC5ORkfPLJJ8YZJBEREVU7Rg1Iw4YNw7Vr1zB37lzo9Xq0atUKsbGxcHNzAwDo9XrVdyKtWrUKeXl5mDhxIiZOnKiUh4SEIDIyEgBw/fp1vPzyy0hPT4ednR18fX1x+PBhdOjQ4aGOjYiIiKovo1+kPWHCBEyYMKHIxwpDT6H4+Pj7tvfxxx/j448/roCeERER0ePK6D81QkRERFTVMCARERERaTAgEREREWkwIBERERFpMCARERERaTAgEREREWkwIBERERFpMCARERERaTAgEREREWkwIBERERFpMCARERERaTAgEREREWkwIBERERFpMCARERERaTAgEREREWkwIBERERFpMCARERERaTAgEREREWkwIBERERFpMCARERERaTAgEREREWkwIBERERFpMCARERERaTAgEREREWkwIBERERFpMCARERERaTAgEREREWkwIBERERFpMCARERERaTAgEREREWkwIBERERFpMCARERERaTAgEREREWkYPSAtX74cHh4esLS0hJ+fH7799tsS6yckJMDPzw+WlpZo3Lgx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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import pylab as P\n", "\n", @@ -473,16 +505,27 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "6cef48a9", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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rERERKQWa1XJULCGlYiIiNRirSoZCv4UIiIiIrVYq0qGggkrERERsVaVDBoTViIionqOtapk6FjDSkREVM+xVpUMHX8iERER1XOsVSVDx4SViIionildr5odm81aVTJoLAkgIiKqR+T1qkVPiuCzxQcJwQkwkhrBSGYEmZdMsY21qmRImLASERHVI2XVq7be0xqm9qasVSWDxJ9ORERE9UhZ9arWftasVSWDxYSViIiojuLcqlRXMGElIiKqgzi3KtUlrGElIiKqgzi3KtUl/DlFRERUB3FuVapLmLASERHVAZxbleoylgQQERHVcpxbleo6JqxERES1HOdWpbqOP7OIiIhqEXVTVXFuVarrmLASERHVEmVNVcV6VarrmLASERHVEqUv/efeyEXRkyIA4NyqVKdJhBCipoOoSVlZWbC1tUVmZiZsbGxqOhwiIqJyZUZlKupUASDgdABsu9oiPy1fMbdqblIu61XrEOYq7GElIiIyWNpMVcW5Vaku4ywBREREBohTVRH9gwkrERGRAeJUVUT/4E8yIiIiA8Spqoj+wYSViIjIAHBpVaKysSSAiIiohrFelah8TFiJiIhqGOtVicrHn2lERETViEurEmmPCSsREVE14dKqRLphwkpERFRNuLQqkW4M7pMQHh4OT09PyGQydOjQASdPniy3/datW+Hn5wcLCws4OztjwoQJSE9Pr6ZoiYiIylb68r+RuVGZl/79jvnB/4Q/bLvawv+EP/yO+bEEgOj/GVTCumPHDsyePRuLFi1CdHQ0evTogf79+yMxMVFt+1OnTmHcuHGYOHEi4uLisHPnTly4cAGTJk2q5siJiIiUqbv8H909GvGvxiu149KqRBUzqIR11apVmDhxIiZNmgQfHx989tlncHNzw5o1a9S2P3v2LJo2bYpZs2bB09MT3bt3x+TJk3Hx4sVqjpyIiEiZusv/xbnFMJbx0j+RtgzmE5Kfn49Lly4hKChIaXtQUBCioqLU3qdr1664c+cODh48CCEE7t+/j127dmHgwIFlPk5eXh6ysrKU/hEREembupH/vtt84X/Sn5f+ibRkMAlrWloaioqK4OTkpLTdyckJKSkpau/TtWtXbN26FaNHj4aZmRkaN24MOzs7rF69uszHCQsLg62treKfm5ubXp8HERHVT5quVFWcU8xL/0RaMpiEVU4ikSj9LYRQ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g0lY5SQSidLfQgiVbeps374dS5cuxY4dO+Do6Fhmu3fffReZmZmKf0lJSZWOmdTLOpeFS90vaZSsOgU7of3p9pyyioiIiFQYzLRWDRs2hLGxsUpvampqqkqva2k7duzAxIkTsXPnTrz44ovltpVKpZBKpZWOl8qnSb2qRTsLNBrWCA79HZioEhERUZkMpofVzMwMHTp0QEREhNL2iIgIdO3atcz7bd++HePHj8e2bdswcODAqg6TNKBJvar9S/boGNsRnks9mawSERFRuQymhxUA5s6di+DgYAQGBqJLly746quvkJiYiClTpgB4djn/7t272Lx5M4Bnyeq4cePw+eefo3PnzoreWXNzc9ja2tbY86iPss5l4enfT3E3/C6yz3IRACIiItIfg0pYR48ejfT0dCxbtgzJyclo06YNDh48CA8PDwBAcnKy0pys69atQ2FhIaZPn47p06crtoeEhGDTpk3VHX69pc10VU7BThxURURERFoxqHlYawLnNqscbWYAaLaqGS//ExERaYm5ioH1sFLtommyyhIAIiIiqgyDGXRFtQuTVSIiIqouTFhJK9rOrcpklYiIiCqLJQGkkaxzWbg69yqyo8qfAcC6izVcp7rCooUF61WJiIhIL5iwUoU0nQWAl/+JiIioKjBhpXKxVpWIiIhqGmtYqUyaJqusVSUiIqKqxB5WUpF1LgtX511F9uny61U5tyoRERFVByaspKDpwCqAK1YRERFR9WHCSgA0H1hl0c4Crb5qxV5VIiIiqjZMWIkDq4iIiMigcdBVPceBVURERGTo2MNaT3FgFREREdUWTFjrGQ6sIiIiotqGCWs9woFVREREVBsxYa0nOLCKiIiIaisOuqoHOLCKiIiIajP2sNZxmiSrHFhFREREhowJax2l6SwAHFhFREREho4Jax2j6SwAHFhFREREtQUT1jpE01kAOLCKiIiIahMmrHUEZwEgIiKiuoqzBNQBnAWAiIiI6jL2sNZiXF6ViIiI6gMmrLWUpvWqnAWAiIiIajsmrLWQJiUAnAWAiIiI6gomrLWMJskqB1YRERFRXcJBV7WIJskqB1YRERFRXcMe1lpAk8FVHFhFREREdRUTVgOnyeAqlgAQERFRXcaSAAMWP47JKhERERETVgOVvD4ZqVuYrBIRERGxJMAAaVIGwPlViYiIqL5gwmpAOLiKiIiI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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "fig = plt.figure()\n", "\n", - "CS = plt.contour(xi, yi, zi, linewidth=0.5)\n", + "#CS = plt.contour(xi, yi, zi, linewidth=0.5)\n", "\n", - "plt.clabel(CS, fontsize=10, inline=1)\n", + "#plt.clabel(CS, fontsize=10, inline=1)\n", "\n", "l1 = plt.scatter(xLList[0][:,0], xLList[0][:,1], marker='o', c='m', s=10);\n", "\n", @@ -521,7 +564,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "dc31f543", "metadata": {}, "outputs": [], @@ -580,9 +623,11 @@ ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "id": "67ae8521", "metadata": {}, + "outputs": [], "source": [ "targetState = \\['I', 'R'\\]\n", "\n", @@ -630,8 +675,16 @@ "name": "python3" }, "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", "name": "python", - "version": "3.9.15" + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" }, "vscode": { "interpreter": { diff --git a/docs/notebooks/unroll/unrollSimple.ipynb b/docs/notebooks/unroll/unrollSimple.ipynb index 6f32bdfa..771c0889 100644 --- a/docs/notebooks/unroll/unrollSimple.ipynb +++ b/docs/notebooks/unroll/unrollSimple.ipynb @@ -6,10 +6,11 @@ "source": [ "# Deducing transitions from equations\n", "\n", - "Given a set of equations, PyGOM is able to attempt to distinguish the implied flows between compartments.\n", + "Deducing rate of change equations from transitions is as simple as adding up all the different flows in and out of each state.\n", + "For the more difficult reverse problem, PyGOM is able to attempt to distinguish the implied flows between compartments given a set of equations.\n", "It may be that multiple underlying flow configurations can separately explain a given ODE system, so this functionality should be used with caution.\n", "Here we demonstrate how this works in practice for two potentially tricky problems.\n", - "The first of which is a system where the total population count is not conserved and the second is a system where a flow out of compartment is split.\n", + "The first of which is a system where the total population count is not conserved and the second is a system where a flow out of some of the compartments is split.\n", "\n", "## SIR with births and deaths\n", "\n", @@ -26,18 +27,18 @@ "\n", "Here we encounter an issue when thinking in terms of compartments.\n", "The total number of living individuals, $N$, is not a distinct category, rather, $S$, $I$ and $R$ are a subset of it.\n", - "Thus, whilst valid to define system of ODEs as we have done above, PyGOM will run into difficulties as it will try to treat $N$ as a compartment.\n", + "Thus, whilst valid to define a system of ODEs as we have done above, PyGOM will run into difficulties as it will interpret $N$ as a compartment.\n", "One solution could be to define $N$ as a time dependent parameter, however PyGOM does not have this functionality.\n", "\n", - "Instead, we have to be careful in ensuring that what we pass to PyGOM's transition calculating function, `get_unrolled_obj()`, consists only of state equations.\n", + "Instead, we must be careful to ensure that we only pass state equations to PyGOM's transition calculating function, {func}`get_unrolled_obj()`.\n", "The implication for the current example is that we eliminate the final equation and substitute $N=S+I+R$ everywhere else.\n", "\n", - "Let's set up the PyGOM model as usual." + "Let's set up the {class}`.SimulateOde` object as usual." ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "id": "52daed16", "metadata": {}, "outputs": [], @@ -66,27 +67,10 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "16280343", "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}0 & 0 & 0\\\\0 & 0 & 0\\\\0 & 0 & 0\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[0, 0, 0],\n", - "[0, 0, 0],\n", - "[0, 0, 0]])" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "model.get_transition_matrix()" ] @@ -96,15 +80,14 @@ "id": "669529c7", "metadata": {}, "source": [ - "we see that it is empty. This is because {class}`.SimulateOde` was not initialized using transitions, but by ODEs.\n", - "TODO: perhaps this should be done automatically?\n", - "\n", + "we see that it is empty.\n", + "This is because {class}`.SimulateOde` was not initialized using transitions, but by ODEs.\n", "We can populate the transition matrix by calling an algorithm to extract the flow information:" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "id": "768a4cd0", "metadata": {}, "outputs": [], @@ -122,27 +105,10 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "id": "5750fc80", "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}0 & \\frac{I S \\beta}{I + R + S} & 0\\\\0 & 0 & I \\gamma\\\\0 & 0 & 0\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[0, I*S*beta/(I + R + S), 0],\n", - "[0, 0, I*gamma],\n", - "[0, 0, 0]])" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "model.get_transition_matrix()" ] @@ -152,152 +118,19 @@ "id": "a373d4c1", "metadata": {}, "source": [ - "Birth and death processes are not between states, rather into and out of the system and so do not appear in the transition matrix.\n", + "Birth and death processes are not between states, rather into and out of the system and so do not appear in the transition matrix.\n", "We could always get around this by defining another class (perhaps **U**nliving) as a limitless reservoir where births may come from and deaths may flow into.\n", - "Instead, we can view the birth and death processes by inspecting a graph of the transitions." + "Alternatively, we can view the birth and death processes by inspecting a graph of the transitions." ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "id": "8251b87f", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "S\n", - "\n", - "S\n", - "\n", - "\n", - "\n", - "I\n", - "\n", - "I\n", - "\n", - "\n", - "\n", - "S->I\n", - "\n", - "\n", - "I*S*β/(I + R + S)\n", - "\n", - "\n", - "\n", - "S*μ\n", - "S*μ\n", - "\n", - "\n", - "\n", - "S->S*μ\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "R\n", - "\n", - "R\n", - "\n", - "\n", - "\n", - "I->R\n", - "\n", - "\n", - "I*γ\n", - "\n", - "\n", - "\n", - "I*μ\n", - "I*μ\n", - "\n", - "\n", - "\n", - "I->I*μ\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "R*μ\n", - "R*μ\n", - "\n", - "\n", - "\n", - "R->R*μ\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "B*S\n", - "B*S\n", - "\n", - "\n", - "\n", - "B*S->S\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "B*I\n", - "B*I\n", - "\n", - "\n", - "\n", - "B*I->S\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "B*R\n", - "B*R\n", - "\n", - "\n", - "\n", - "B*R->S\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "model.get_transition_graph()" + "model.get_transition_graph();" ] }, { @@ -305,9 +138,13 @@ "id": "98da24d0", "metadata": {}, "source": [ - "## SLIAR model\n", + "## SLIAR epidemic model\n", "\n", - "Now we turn to a problem that does not have a one to one mapping between all the transitions and the terms in the ODEs. In this model, **S**usceptible individuals may be infected and enter a **L**atent phase. The rate at which individuals leave this state is $\\kappa$, after which a fraction $p$ become **I**nfective and the remaining $(1-p)$ become **A**symptomatic. Both these classes are capable of onward transmission, however, those in the **A** class have infectivity reduced by a factor $\\delta$ relative to the **I** class. All **A**symptomatics eventually become **R**emoved at a rate $\\eta$, whereas a fraction, $f$, of the infectives recover, the remaining $(1-f)$ going on to die (both at a rate $\\alpha$).\n", + "Now we turn to a problem that does not have a one to one mapping between all the transitions and the terms in the ODEs.\n", + "In this model, **S**usceptible individuals may be infected and enter a **L**atent phase.\n", + "The rate at which individuals leave this state is $\\kappa$, after which a fraction, $p$, become **I**nfective and the remaining, $(1-p)$, become **A**symptomatic.\n", + "Both these classes are capable of onward transmission, however, those in the **A** class have infectivity reduced by a factor $\\delta$ relative to the **I** class.\n", + "All **A**symptomatics eventually become **R**emoved at a rate $\\eta$, whereas a fraction, $f$, of the infectives recover, the remaining $(1-f)$ going on to die (both at a rate $\\alpha$).\n", "\n", "The equations are as follows:\n", "\n", @@ -323,34 +160,15 @@ "For **L**, this is composed of two transitions, one to **I** and the other to **A** but the ODE of **L** only reflects the total flow going out of the state.\n", "Similarly for **I**, the outflow, $\\alpha I$, is partitioned as $f \\alpha I$ into state **R** with the rest assumed dead, though not explicitly stated in the equations.\n", "\n", - "We define out PyGOM model" + "We set up the {class}`.SimulateOde` object for this case:" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "id": "280c4be4", "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}- S \\beta \\left(A \\delta + I\\right)\\\\- L \\kappa + S \\beta \\left(A \\delta + I\\right)\\\\- I \\alpha + L \\kappa p\\\\- A \\epsilon + L \\kappa \\left(1 - p\\right)\\\\A \\epsilon + I \\alpha f\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[ -S*beta*(A*delta + I)],\n", - "[-L*kappa + S*beta*(A*delta + I)],\n", - "[ -I*alpha + L*kappa*p],\n", - "[ -A*epsilon + L*kappa*(1 - p)],\n", - "[ A*epsilon + I*alpha*f]])" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from pygom import SimulateOde, Transition, TransitionType\n", "\n", @@ -374,32 +192,13 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "id": "1b6cb187", "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}0 & A S \\beta \\delta + I S \\beta & 0 & 0 & 0\\\\0 & 0 & L \\kappa p & - L \\kappa p + L \\kappa & 0\\\\0 & 0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0 & A \\epsilon\\\\0 & 0 & 0 & 0 & 0\\end{matrix}\\right]$" - ], - "text/plain": [ - "Matrix([\n", - "[0, A*S*beta*delta + I*S*beta, 0, 0, 0],\n", - "[0, 0, L*kappa*p, -L*kappa*p + L*kappa, 0],\n", - "[0, 0, 0, 0, 0],\n", - "[0, 0, 0, 0, A*epsilon],\n", - "[0, 0, 0, 0, 0]])" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "model = model.get_unrolled_obj()\n", - "model.get_transition_graph()" + "model.get_transition_graph();" ] }, { @@ -407,130 +206,17 @@ "id": "00742616", "metadata": {}, "source": [ - "we notice that the $L$ outflow has been captured, but the outflow from $I$ is assumed to be a full death process of which a fraction are born into the recovered state.\n", - "This demonstrates the difficulty in such calculations.\n", + "we notice that the **L** outflow has been captured, but the outflow from **I** is assumed to be a full death process of which a fraction are born into the recovered state.\n", + "The appearance of multiple consistent configurations demonstrates the difficulty in performing such reverse engineering.\n", "One work-around is if we explicitly introduce a dead state" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "id": "59ce2a8a", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "S\n", - "\n", - "S\n", - "\n", - "\n", - "\n", - "L\n", - "\n", - "L\n", - "\n", - "\n", - "\n", - "S->L\n", - "\n", - "\n", - "A*S*β*δ + I*S*β\n", - "\n", - "\n", - "\n", - "I\n", - "\n", - "I\n", - "\n", - "\n", - "\n", - "L->I\n", - "\n", - "\n", - "L*κ*p\n", - "\n", - "\n", - "\n", - "A\n", - "\n", - "A\n", - "\n", - "\n", - "\n", - "L->A\n", - "\n", - "\n", - "-L*κ*p + L*κ\n", - "\n", - "\n", - "\n", - "R\n", - "\n", - "R\n", - "\n", - "\n", - "\n", - "I->R\n", - "\n", - "\n", - "I*α*f\n", - "\n", - "\n", - "\n", - "D\n", - "\n", - "D\n", - "\n", - "\n", - "\n", - "I->D\n", - "\n", - "\n", - "-I*α*f + I*α\n", - "\n", - "\n", - "\n", - "A->R\n", - "\n", - "\n", - "A*ε\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "stateList = ['S', 'L', 'I', 'A', 'R', 'D']\n", "paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'epsilon']\n", @@ -542,7 +228,7 @@ " Transition(origin='D', equation='(1-f)*alpha*I', transition_type=TransitionType.ODE)]\n", "model = SimulateOde(stateList, paramList, ode=odeList)\n", "model = model.get_unrolled_obj()\n", - "model.get_transition_graph()" + "model.get_transition_graph();" ] } ], diff --git a/pygom/model/epi_analysis.py b/pygom/model/epi_analysis.py index 0a89462e..db2ed800 100644 --- a/pygom/model/epi_analysis.py +++ b/pygom/model/epi_analysis.py @@ -75,8 +75,8 @@ def R0(ode, disease_state): F, V = disease_progression_matrices(ode, disease_state) ## index = ode.get_state_index(disease_state) e = R0_from_matrix(F, V) - DFE_eqn = DFE(ode, disease_state) - e = [eig.subs(DFE_eqn) for eig in e] + #DFE_eqn = DFE(ode, disease_state) + #e = [eig.subs(DFE_eqn) for eig in e] if ode.parameters is not None: e = [eig.subs(ode.parameters) for eig in e] From 8a7c464dec70df9b1e350ab0fbf7951fa8317814 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 6 Jun 2024 08:05:42 +0100 Subject: [PATCH 025/123] Add forgotten files and undo R0 test edits which were crashing test cases --- docs/md/building_doc.md | 18 +++++++++ docs/md/installation.md | 77 +++++++++++++++++++++++++++++++++++++ pygom/model/epi_analysis.py | 4 +- 3 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 docs/md/building_doc.md create mode 100644 docs/md/installation.md diff --git a/docs/md/building_doc.md b/docs/md/building_doc.md new file mode 100644 index 00000000..7e127a3d --- /dev/null +++ b/docs/md/building_doc.md @@ -0,0 +1,18 @@ +# Building the documentation locally + +The documentation which you are currently reading may be built locally. +First, install additional packages: + +```bash +pip install -r docs/requirements.txt +``` + +Then build the documentation from command line + +```bash +jupyter-book build docs +``` + +The html files will be saved in the local copy of your repository under: + + pygom/docs/_build/html \ No newline at end of file diff --git a/docs/md/installation.md b/docs/md/installation.md new file mode 100644 index 00000000..3968c77c --- /dev/null +++ b/docs/md/installation.md @@ -0,0 +1,77 @@ +# Installation + +Installation instructions may be found on the GitHub project README, but we include them here also. + +## From source + +Source code for PyGOM can be downloaded from the GitHub repository: https://github.com/ukhsa-collaboration/pygom + +```bash +git clone https://github.com/ukhsa-collaboration/pygom.git +``` + +Please be aware that there may be redundant files within the package as it is under active development. + +```{note} +The latest fully reviewed version of PyGOM will be on the master branch and we recommend that users install the version from there. +``` + +Activate the relevant branch for installation via Git Bash: + +```bash +git activate relevant-branch-name +``` + +Package dependencies can be found in the file `requirements.txt`. +An easy way to install these to create a new [conda](https://conda.io/docs) environment via: + +```bash +conda env create -f conda-env.yml +``` + +which you should ensure is active for the installation process using: + +```bash +conda activate pygom +``` + +Alternatively, you may add dependencies to your own environment. + +```bash +pip install -r requirements.txt +``` + +The final prerequisite, if you are working on a Windows machine, is that you will also need to install: +- [Graphviz](https://graphviz.org/) +- [Visual C++](https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0) +- [Visual C++ Build Tools](https://go.microsoft.com/fwlink/?LinkId=691126) + +You you should be able to install the PyGOM package via command line: + +```bash +python setup.py install +``` + +If you anticipate making your own frequent changes to the PyGOM source files, it might be more convenient to install in develop mode instead: + +```bash +python setup.py develop +``` + +## From PyPI + +Alternatively, the latest release can be installed from [PyPI](https://pypi.org/project/pygom/): + +```bash +pip install pygom +``` + +# Testing the package + +Test files should then be run from the command line to check that installation has completed successfully + +```bash +python setup.py test +``` + +This can take some minutes to complete. \ No newline at end of file diff --git a/pygom/model/epi_analysis.py b/pygom/model/epi_analysis.py index db2ed800..0a89462e 100644 --- a/pygom/model/epi_analysis.py +++ b/pygom/model/epi_analysis.py @@ -75,8 +75,8 @@ def R0(ode, disease_state): F, V = disease_progression_matrices(ode, disease_state) ## index = ode.get_state_index(disease_state) e = R0_from_matrix(F, V) - #DFE_eqn = DFE(ode, disease_state) - #e = [eig.subs(DFE_eqn) for eig in e] + DFE_eqn = DFE(ode, disease_state) + e = [eig.subs(DFE_eqn) for eig in e] if ode.parameters is not None: e = [eig.subs(ode.parameters) for eig in e] From 707755c740143744bcf19c47782dbcb09724a465 Mon Sep 17 00:00:00 2001 From: j-c-gibson <163280363+j-c-gibson@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:24:09 +0100 Subject: [PATCH 026/123] Update README.md Fix incorrect git command and give more command line details --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 57cf9fa8..bea3a03e 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,17 @@ Please be aware that there may be redundant files within the package as it is un > [!NOTE] > The latest fully reviewed version of PyGOM will be on the `master` branch and we generally recommend that users install this version. However, the current version being prepared for release (featuring up-to-date documentation) is hosted on the `feature/prep-doc` branch. +When running the following command line commands, ensure that your current working directory is the one where the PyGOM source files were downloaded to. This should be found from your home directory: + + cd pygom + Activate the relevant branch for installation via Git Bash, if you have been recruited to test code for the new release then this is the `feature/prep-doc` branch: - git activate feature/prep-doc + git checkout feature/prep-doc Package dependencies can be found in the file, `requirements.txt`. -An easy way to install these to create a new [conda](https://conda.io/docs) environment via: +An easy way to install these to create a new [conda](https://conda.io/docs) environment in Anaconda Prompt via: conda env create -f conda-env.yml From 0c82e643be8428c0c5a704d3e170de064541e2c3 Mon Sep 17 00:00:00 2001 From: wardo5 Date: Wed, 19 Jun 2024 10:06:04 +0100 Subject: [PATCH 027/123] Update setup.py --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index 0128ec87..bdc51203 100644 --- a/setup.py +++ b/setup.py @@ -32,6 +32,7 @@ Extension("pygom.model._tau_leap", ["pygom/model/_tau_leap.pyx"], include_dirs=[numpy.get_include()], + extra_compile_args=['-std=c99'], # extra_compile_args=['-fopenmp'], # extra_link_args=['-fopenmp']), ) @@ -45,6 +46,7 @@ Extension("pygom.model._tau_leap", ["pygom/model/_tau_leap.c"], include_dirs=[numpy.get_include()], + extra_compile_args=['-std=c99'], # extra_compile_args=['-fopenmp'], # extra_link_args=['-fopenmp']), ) From f582b044e4622c0e67a07095de73d8575dd91776 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 20 Jun 2024 10:40:28 +0100 Subject: [PATCH 028/123] Fix numpy version and Inf deprecation --- pygom/loss/confidence_interval.py | 8 ++++---- pygom/model/stochastic_simulation.py | 6 +++--- requirements.txt | 2 +- setup.py | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pygom/loss/confidence_interval.py b/pygom/loss/confidence_interval.py index 769d0126..b44b7799 100644 --- a/pygom/loss/confidence_interval.py +++ b/pygom/loss/confidence_interval.py @@ -301,8 +301,8 @@ def profile(obj, alpha, theta=None, lb=None, ub=None, full_output=False): funcFgradient = _profileFgradient(theta, i, alpha, obj) funcFhessian = _profileFhessian(theta, i, alpha, obj) - lbT = np.ones(p)*-np.Inf if lb is None else lb.copy() - ubT = np.ones(p)*np.Inf if ub is None else ub.copy() + lbT = np.ones(p)*-np.inf if lb is None else lb.copy() + ubT = np.ones(p)*np.inf if ub is None else ub.copy() ubT[i] = theta[i] @@ -318,8 +318,8 @@ def profile(obj, alpha, theta=None, lb=None, ub=None, full_output=False): xhatL, lbT, ubT, True) ## re-adjust the bounds for the other side - lbT = np.ones(p)*-np.Inf if lb is None else lb.copy() - ubT = np.ones(p)*np.Inf if ub is None else ub.copy() + lbT = np.ones(p)*-np.inf if lb is None else lb.copy() + ubT = np.ones(p)*np.inf if ub is None else ub.copy() lbT[i] = theta[i] diff --git a/pygom/model/stochastic_simulation.py b/pygom/model/stochastic_simulation.py index 3c69527c..07adab7b 100644 --- a/pygom/model/stochastic_simulation.py +++ b/pygom/model/stochastic_simulation.py @@ -421,7 +421,7 @@ def firstReaction(x, t, state_change_mat, transition_func, seed=None): rates = transition_func(x, t) # find our jump times jump_times = _newJumpTimes(rates, seed=seed) - if np.all(jump_times == np.Inf): + if np.all(jump_times == np.inf): return x, t, False # first jump min_index = np.argmin(jump_times) @@ -461,7 +461,7 @@ def nextReaction(x, t, state_change_mat, dependency_graph, if anew > 0: jump_times[i] = (aold/anew)*(jump_times[i] - t) + t else: - jump_times[i] = np.Inf + jump_times[i] = np.inf # done :) return new_x, t, True, rates, jump_times else: @@ -630,7 +630,7 @@ def _newJumpTimes(rates, seed=None): distribution """ - tau = [rexp(1, r, seed=seed) if r > 0 else np.Inf for r in rates] + tau = [rexp(1, r, seed=seed) if r > 0 else np.inf for r in rates] return np.array(tau) diff --git a/requirements.txt b/requirements.txt index 3133a4b3..47c88f15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ dask[complete]>=0.13.0 graphviz>=0.4.9 matplotlib>=1.0.0 -numpy>=1.6.0 +numpy>=2.0.0 pandas>=0.15.0 python-dateutil>=2.0.0 scipy>=1.4.1 diff --git a/setup.py b/setup.py index 0128ec87..69c7520d 100644 --- a/setup.py +++ b/setup.py @@ -74,7 +74,7 @@ setup_requires = [ 'setuptools-scm>=3.2.0', 'setuptools_scm_git_archive', - 'numpy>=1.12.0' + 'numpy>=2.0.0' ] setup( From 2ec2dc327d9ff9ecae11b6b658e18fb096104b72 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 20 Jun 2024 11:33:47 +0100 Subject: [PATCH 029/123] Numpy >=2.0 requires python >=3.9. Also add 3.12 to tests. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 420d7ffd..5f267a59 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] # macos-latest - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v2 From 7c6d233749cc989adbce539ec5795995911231b6 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Fri, 21 Jun 2024 16:06:07 +0100 Subject: [PATCH 030/123] Remove DeterministicOde class from common models --- docs/md/common_models.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/md/common_models.md b/docs/md/common_models.md index 08965ee7..68943565 100644 --- a/docs/md/common_models.md +++ b/docs/md/common_models.md @@ -1,13 +1,11 @@ # Pre-defined examples - common epi models -We have defined a set of models {mod}`common_models`, most of them commonly used in epidemiology. They are there -as examples and also to save time for users. Most of them are of the -compartmental type, and we use standard naming conventions i.e. **S** = -Susceptible, **E** = Exposed, **I** = Infectious, **R** = Recovered. +```{warning} +JG: I have not gone through every example here +``` -#TODO is R recovered, removed or dead? - -Extra state symbol will be introduced when required. +We have defined a set of models in the module {mod}`common_models`. +Most of these draw from commonly used models in epidemiology and are included primarily to save time for users, but also to serve as examples. {doc}`../notebooks/common_models/SIS` From 9d02f2db19d3ec237e8018a266a631c80a3e9309 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Fri, 21 Jun 2024 16:10:04 +0100 Subject: [PATCH 031/123] More doc tweaks --- docs/md/building_doc.md | 6 +- docs/md/installation.md | 4 +- docs/md/intro.md | 13 +- docs/md/solving.md | 2 +- docs/notebooks/epijson.ipynb | 39 +-- docs/notebooks/extract_info.ipynb | 18 +- docs/notebooks/insights.ipynb | 2 +- docs/notebooks/model_params.ipynb | 8 +- docs/notebooks/model_solver.ipynb | 8 +- docs/notebooks/model_spec.ipynb | 71 ++--- docs/notebooks/paramfit/bvpSimple.ipynb | 96 ++---- docs/notebooks/paramfit/params_via_abc.ipynb | 276 +++--------------- .../paramfit/params_via_optimization.ipynb | 72 ++--- docs/notebooks/unroll/unrollSimple.ipynb | 32 +- 14 files changed, 183 insertions(+), 464 deletions(-) diff --git a/docs/md/building_doc.md b/docs/md/building_doc.md index 7e127a3d..4ea5e5eb 100644 --- a/docs/md/building_doc.md +++ b/docs/md/building_doc.md @@ -1,13 +1,13 @@ # Building the documentation locally -The documentation which you are currently reading may be built locally. -First, install additional packages: +The documentation, which you are currently reading, may be built locally. +First, install additional packages required specifically for the documentation: ```bash pip install -r docs/requirements.txt ``` -Then build the documentation from command line +Then, build the documentation from command line: ```bash jupyter-book build docs diff --git a/docs/md/installation.md b/docs/md/installation.md index 3968c77c..4543a6c0 100644 --- a/docs/md/installation.md +++ b/docs/md/installation.md @@ -1,6 +1,6 @@ # Installation -Installation instructions may be found on the GitHub project README, but we include them here also. +Installation instructions may be found on the [GitHub project README](https://github.com/ukhsa-collaboration/pygom/tree/feature/prep-doc) (currently on the `feature/prep-doc` branch), but we include them here also. ## From source @@ -44,7 +44,7 @@ pip install -r requirements.txt The final prerequisite, if you are working on a Windows machine, is that you will also need to install: - [Graphviz](https://graphviz.org/) - [Visual C++](https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0) -- [Visual C++ Build Tools](https://go.microsoft.com/fwlink/?LinkId=691126) +- Visual C++ Build Tools You you should be able to install the PyGOM package via command line: diff --git a/docs/md/intro.md b/docs/md/intro.md index 01054c30..8ef86486 100644 --- a/docs/md/intro.md +++ b/docs/md/intro.md @@ -4,7 +4,18 @@ PyGOM (Python Generic ODE Model) is a Python package which provides a simple interface for users to construct Ordinary Differential Equation (ODE) models, with a focus on compartmental models and epidemiology. This is backed by a comprehensive and easy to use tool–box implementing functions to easily perform common operations such as parameter estimation and solving for deterministic or stochastic time evolution. -The package source is freely available (hosted on [Github](https://github.com/ukhsa-collaboration/pygom)) and organized in a way that permits easy extension. With both the algebraic and numeric calculations performed automatically (but still accessible), the end user is freed to focus on model development. +The package source is freely available (hosted on [GitHub](https://github.com/ukhsa-collaboration/pygom)) and organized in a way that permits easy extension. With both the algebraic and numeric calculations performed automatically (but still accessible), the end user is freed to focus on model development. + +## What is new in this release? + +The main objective of the current release (0.1.8?) is to provide more comprehensive documentation on how to use PyGOM. + +The code underlying PyGOM's functionality is largely unchanged since the previous release, barring a few minor bug fixes. +The only significant changes which previous users should be aware of are: +- A move away from the {class}`DeterministicOde` class for deterministic simulations and instead employing {class}`SimulateOde` as our do-all class for deterministic or stochastic simulations as well as parameter fitting. +- Running simulations with random parameters does not require a special simulation function. Instead, PyGOM now recognises the parameter types handed to it (fixed or random) and acts accordingly. This means that stochastic simulations can now be performed with random parameters. + +Both these changes are outlined in more detail in the {doc}`Producing forecasts ` section. ## Using this documentation This documentation is built using [JupyterBook](https://jupyterbook.org/en/stable/intro.html). diff --git a/docs/md/solving.md b/docs/md/solving.md index 09df1175..8ad3ed93 100644 --- a/docs/md/solving.md +++ b/docs/md/solving.md @@ -1,6 +1,6 @@ # Producing forecasts -An exercise central to the study of infectious diseases (and indeed ODE models in general) is performing simulations to understand the evolution of the system in time. +An exercise central to the study of infectious diseases (and indeed ODE models in general) is performing simulations to understand the likely evolution of the system in time. PyGOM allows the user to easily obtain numerical solutions for both the deterministic and stochastic time evolution of their model. Furthermore, users may specify model parameters to take either fixed values or to be drawn randomly from a probability distribution. diff --git a/docs/notebooks/epijson.ipynb b/docs/notebooks/epijson.ipynb index 882abe8b..7ad54f4f 100644 --- a/docs/notebooks/epijson.ipynb +++ b/docs/notebooks/epijson.ipynb @@ -6,20 +6,14 @@ "source": [ "# Reading and using EpiJSON data\n", "\n", - "Epidemiology data is complicated due to the many different stages a\n", - "patient can go through and whether a modeling technique is applicable\n", - "depends heavily on the recording of data. [EpiJSON](https://github.com/Hackout2/EpiJSON) is a framework which\n", - "tries to captures all the information in a JSON format {cite}`Finnie2016`.\n", + "```{warning}\n", + "JG: Not entirely sure what is going on in this section.\n", + "```\n", "\n", - "PyGOM provides the functionality to process EpiJSON data. Due to\n", - "the nature of this package, modeling of ODEs, data files are processed with this in mind. The output is therefore in the cumulative form as\n", - "default, shown below, in a [`pandas.DataFrame`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html) format. \n", - "\n", - "#TODO unsure what this means\n", - "\n", - "\n", - "The input can be\n", - "in a string format, a file or already a `dict`." + "[EpiJSON](https://github.com/Hackout2/EpiJSON) is a framework which tries to capture epidemiological information in a JSON format {cite}`Finnie2016`.\n", + "PyGOM provides the functionality to process EpiJSON data with a view to preparing it for it's various modelling features previously discussed in this guide.\n", + "The input can be in a string format, a file or already a `dict`.\n", + "The output is in the cumulative form as default, shown below, in a [`pandas.DataFrame`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html) format. " ] }, { @@ -30,13 +24,10 @@ "outputs": [], "source": [ "from pygom.loss.read_epijson import epijson_to_data_frame\n", - "\n", "import pkgutil\n", "\n", "data = pkgutil.get_data('pygom', 'data/eg1.json')\n", - "\n", "df = epijson_to_data_frame(data)\n", - "\n", "print(df)" ] }, @@ -84,18 +75,14 @@ "id": "a5ac54c8", "metadata": {}, "source": [ - "Given an initialized object, all the operations are inherited from\n", - "{class}`.BaseLoss`. We demonstrated above how to calculate the cost\n", - "and the rest will not be shown for brevity. The data frame is stored\n", - "inside of the loss object and can be retrieved for inspection at any\n", - "time point.\n", + "Given an initialized object, all the operations are inherited from {class}`.BaseLoss`.\n", + "We demonstrated above how to calculate the cost and the rest will not be shown for brevity.\n", + "The data frame is stored inside of the loss object and can be retrieved for inspection at any time point.\n", "\n", "```{note}\n", - "Initial values for the states are required,\n", - "but the time is not. When the time is not supplied, then the first time\n", - "point in the data will be treated as $t0$. The input Death indicates which column of the data is used\n", - "and $R$ the corresponding state the data belongs to.\n", + "Initial values for the states are required, but the time is not.\n", + "When the time is not supplied, then the first time point in the data will be treated as $t0$.\n", + "The input Death indicates which column of the data is used and $R$ the corresponding state the data belongs to.\n", "```" ] }, diff --git a/docs/notebooks/extract_info.ipynb b/docs/notebooks/extract_info.ipynb index d81401e1..8c542c14 100644 --- a/docs/notebooks/extract_info.ipynb +++ b/docs/notebooks/extract_info.ipynb @@ -7,9 +7,10 @@ "source": [ "# Extracting model information\n", "\n", - "In the study of ODE systems, there are many calculations which are frequently performed and so PyGOM has some functionality to provide assistance.\n", - "We will again use the SIR model as our model system, but this time we will make use of the functions from PyGOM's `common_models`, where many predefined models are stored.\n", - "This means we can avoid having to build the model from scratch again." + "In the study of ODE systems, there are many calculations which are frequently performed and PyGOM has some functionality to provide assistance.\n", + "We will again use the SIR model as our example system, but this time we will make use of the from PyGOM `common_models` module, where many predefined models are stored.\n", + "This means we avoid having to build the model from scratch again, saving time and lines of code.\n", + "Here we initialise a `SIR_N` model, the suffix, $N$, indicating that we have standard incidence and thus $N$ appears in the denominator of the force of infection:" ] }, { @@ -20,7 +21,7 @@ "outputs": [], "source": [ "from pygom import common_models\n", - "ode = common_models.SIR_N_stochastic()" + "ode = common_models.SIR_N()" ] }, { @@ -87,7 +88,8 @@ "id": "9c7b5c60", "metadata": {}, "source": [ - "and even inspect the transitions graphically:" + "Where only the upper off diagonal triangle is necessary to fully define the system.\n", + "We can even inspect the transitions graphically:" ] }, { @@ -107,9 +109,7 @@ "source": [ "## Algebraic insights\n", "\n", - "We briefly outline some of the algebraic results which can be quickly accessed by PyGOM.\n", - "\n", - "Firstly, we can check if our system is linear" + "We briefly outline some of the algebraic results which can be quickly accessed by PyGOM. Firstly, we can check if our system is linear:" ] }, { @@ -168,6 +168,7 @@ "## Epidemiology specific insights\n", "\n", "Under development are functions to obtain numeric and algebraic expressions for the basic reproduction number, $R_0$.\n", + "Currently, these can be obtained in two steps, first by finding the disease progression matrix and then calculating $R_0$ from this.\n", "We must specify which state represents the *infectious state*, which in this case is the state **I**." ] }, @@ -189,7 +190,6 @@ "from pygom.model.epi_analysis import *\n", "\n", "F, V = disease_progression_matrices(ode, 'I')\n", - "\n", "e = R0_from_matrix(F, V)\n", "print(e)" ] diff --git a/docs/notebooks/insights.ipynb b/docs/notebooks/insights.ipynb index ee10c1b7..e9a43f3b 100644 --- a/docs/notebooks/insights.ipynb +++ b/docs/notebooks/insights.ipynb @@ -7,7 +7,7 @@ "source": [ "# ODE Insights\n", "\n", - "Now that our SIR model is encapsulated in the {class}`SimulateOde` class, it is ready to be studied using PyGOM's various functionalities.\n", + "Now that our SIR model is encapsulated in the {class}`.SimulateOde` class, it is ready to be studied using PyGOM's various functionalities.\n", "Before moving on to more complex methods such as parameter fitting and simulation, we can take advantage of several useful features of PyGOM which provide us with more analytical insights - the sort we might commonly find ourselves calculating, requiring pen and paper to do so." ] } diff --git a/docs/notebooks/model_params.ipynb b/docs/notebooks/model_params.ipynb index 964d8514..f6d64c5a 100644 --- a/docs/notebooks/model_params.ipynb +++ b/docs/notebooks/model_params.ipynb @@ -9,7 +9,7 @@ "\n", "Until now, we have only dealt with parameters when it was necessary to inform PyGOM which of our symbols refer to states and which to parameters.\n", "However, before PyGOM can find numerical solutions to the equations, it must be fed numerical parameter values.\n", - "PyGOM's ODE solvers accept parameters in two forms: fixed, where they remain constant or random, where they are drawn from a given distribution.\n", + "PyGOM's ODE solvers accept parameters in two forms: fixed, where they remain constant, or random, where they are drawn from a given distribution.\n", "We demonstrate these features on our model system, the SIR compartmental model.\n", "We start, as always, by encapsulating our ODE system in a PyGOM object, in this case loading a previously defined model." ] @@ -22,7 +22,7 @@ "outputs": [], "source": [ "from pygom import common_models\n", - "ode = common_models.SIR_N_stochastic()" + "ode = common_models.SIR_N()" ] }, { @@ -32,7 +32,7 @@ "source": [ "## Fixed parameters\n", "\n", - "Defining fixed parameters is for $\\beta$, $\\gamma$ and $N$ is simply done as follows:" + "Defining fixed parameters for $\\beta$, $\\gamma$ and $N$ is simply done via a list of tuples as follows:" ] }, { @@ -86,7 +86,7 @@ "metadata": {}, "source": [ "The values of the shape and rate parameters mean that $\\gamma$ and $\\beta$ have means of 0.25 and 0.3 and standard deviations of 0.025 and 0.03 respectively.\n", - "When changing parameters, it is a good idea to define a new `SimulateOde` object, since there may be some calculated variables leftover from the previous parameter set.\n", + "When changing parameters, it is a good idea to define a new {class}`.SimulateOde` object, since there may be some calculated variables leftover from the previous parameter set.\n", "We do not need to inform PyGOM that the parameters are random and define them in the same way as before:" ] }, diff --git a/docs/notebooks/model_solver.ipynb b/docs/notebooks/model_solver.ipynb index c8eeda8e..1f1f9ec3 100644 --- a/docs/notebooks/model_solver.ipynb +++ b/docs/notebooks/model_solver.ipynb @@ -127,7 +127,7 @@ "\n", "### Fixed parameters\n", "\n", - "First, we initialise a `SimulateOde` object with our fixed parameters, `fixed_param_set`:" + "First, we initialise a {class}`SimulateOde` object with our fixed parameters, `fixed_param_set`:" ] }, { @@ -241,7 +241,7 @@ "metadata": {}, "source": [ "```{note}\n", - "Note that a message may be printed above where PyGOM is trying to connect to an\n", + "A message may be printed above where PyGOM is trying to connect to an\n", "mpi backend, as our module has the capability to compute in parallel\n", "using the IPython.\n", "```" @@ -526,7 +526,7 @@ "metadata": {}, "source": [ "We see that the final size distribution is much more spread out, owing to increased variation in the parameters.\n", - "The cut off between failed and successful epidemics is less clear cut in this case and we set this by eye to be 2000.\n", + "The threshold value separating failed and successful epidemics is less clear cut in this case and we judge this by eye to be 2000.\n", "Again, eliminating the failed epidemics we plot the model output" ] }, @@ -593,7 +593,7 @@ "## Summary\n", "\n", "With two possible simulation methods and two possible parameter types, we have explored the four total model configurations.\n", - "We plot these results side by side for the infected compartment so provide a final illustration of their key qualitative differences." + "We plot these results side by side for the infected compartment to provide an illustration of their key qualitative differences." ] }, { diff --git a/docs/notebooks/model_spec.ipynb b/docs/notebooks/model_spec.ipynb index 7d0316e5..c4c6ce39 100644 --- a/docs/notebooks/model_spec.ipynb +++ b/docs/notebooks/model_spec.ipynb @@ -7,8 +7,8 @@ "source": [ "# Defining an ODE system\n", "\n", - "The starting point when using PyGOM to study an ODE system is to encapsulate the relevant information into a class {class}`.SimulateOde`.\n", - "Once defined as an object of this class, the system is prepared for the application of PyGOM's various features such as simulation and parameter fitting.\n", + "The starting point, when using PyGOM to study an ODE system, is to encapsulate the relevant information into a class {class}`.SimulateOde`.\n", + "Once defined as an instance of this class, the ODE system is prepared for the application of PyGOM's various features such as simulation and parameter fitting.\n", "\n", "## Equations vs Transitions\n", "\n", @@ -18,17 +18,19 @@ "$$\\frac{\\mathrm{d} \\mathbf{y}}{\\mathrm{d} t} = f(\\mathbf{y},\\boldsymbol{\\theta}, t)$$\n", "\n", "where $\\mathbf{y} = \\left(y_{1},\\ldots,y_{n}\\right)$ is a vector of the dependent variables, $\\boldsymbol{\\theta} = \\left(\\theta_{1},\\ldots, \\theta_{p}\\right)$ is the set of parameters and $f$ is a vector function giving the rates of change of each dependent variable.\n", + "Typically, as we have used here, rates of change are with respect to time, $t$, though other variables such as position are also common.\n", "\n", - "Compartmental models, whereby the dependent variables represent categories or states, have another interpretation in which we may instead consider transitions between the different groups\n", + "Compartmental models, whereby the dependent variables represent categories or states, have another interpretation in which we may instead consider transitions between the different groups:\n", "\n", "$$\\begin{aligned}\n", "y_i \\rightarrow y_j = f_{i,j}(\\mathbf{y},\\boldsymbol{\\theta}) \\\\\n", "\\end{aligned}$$\n", "\n", - "where $i, j = \\{1,\\ldots, n\\}$ and $f_{i,j}$ are functions governing the rate at which members of group $i$ transition to $j$.\n", + "where $i, j = \\{1,\\ldots, n\\}$ and $f_{i,j}$ are functions governing the rate at which members of group $i$ transition to group $j$.\n", + "Since flows are symmetric ($f_{i,j}=-f{i,j}$) and a group cannot flow into itself ($f_{i,i}=0$), we need only specify rates for one half of the transition matrix ($i>j$ or $j>i$).\n", "\n", "PyGOM allows the user flexibility in choosing which of these perspectives to use, or indeed combine, in order to build their models.\n", - "If given transitions, PyGOM will automatically convert these into equations and, as we'll see later, it can also attempt to reverse engineer transitions from equations.\n", + "If given transitions, PyGOM will automatically convert these into equations and, {doc}`as we'll see later`{unroll/unrollSimple}, it can also attempt to reverse engineer transitions from equations.\n", "\n", "## Example: SIR model\n", "\n", @@ -38,13 +40,13 @@ "```{warning}\n", "There is some ambiguity in the naming of the Recovered class which is also commonly referred to as Removed.\n", "In the latter sense, there is no distinction made between those who can no longer be infected due to infection acquired immunity and infection induced death.\n", - "However, for more complex models, the recovered class may become susceptible again due to immune waning and deaths versus recoveries are typically important to distinguish in real world applications.\n", + "However, for more complex models, the recovered class may become susceptible again due to the effects of immune waning and deaths versus recoveries are typically important to distinguish in real world applications.\n", "Therefore, in this tutorial, the Recovered class will be reserved solely for those who survive infection.\n", "```\n", "\n", - "The assumptions of the SIR model:\n", - "1) An average member of the population makes contact sufficient to transmit infection with $\\beta$ others per unit time (*standard* as opposed to *mass-action* incidence, where this would be $\\beta N$).\n", - "2) Contacts are well mixed throughout the population, so that the probability that a given contact is with an infected person is $\\frac{I}{N}$ where $N$ is the total population size.\n", + "The assumptions of the SIR model can be stated as:\n", + "1) An average member of the population makes contact sufficient to transmit or receive infection with $\\beta$ others per unit time. This fixed contact rate reflects what is referred to as *standard* incidence, as opposed to *mass-action* incidence, where contacts increase with population size as $\\beta N$ (where $N$ is the total population size).\n", + "2) The population interacts as if a well mixed continuum, such that a contact event is not between two individuals but the whole population on average.\n", "3) The infective class is depleted through recovery at a rate $\\gamma I$.\n", "4) No births, deaths (natural or from disease) or migration mean there is no entry into or departure from the population: $S(t)+I(t)+R(t)=N$.\n", "\n", @@ -56,25 +58,25 @@ "\\frac{\\mathrm{d} R}{\\mathrm{d} t} &= \\gamma I.\n", "\\end{aligned}$$\n", "\n", - "However, it is equally valid to view this system as the result of two transitions; infection, which takes subjects from susceptible to infected and recovery, which takes them from infected to recovered.\n", + "However, it is equally valid to view this system as the result of two transitions; infection, which takes subjects from susceptible to infected and recovery, which takes them from infected to recovered:\n", "\n", "$$\\begin{aligned}\n", "S \\rightarrow I &= \\frac{\\beta SI}{N} \\\\\n", "I \\rightarrow R &= \\gamma I\n", "\\end{aligned}$$\n", "\n", - "Advantages of specifying our system using the transition approach are firstly that transitions are a more intuitive language when thinking about compartmental models.\n", - "Perhaps more beneficial, though, is that when building models with transitions using PyGOM in enables the computer to do our book-keeping when converting transitions to ODE equations.\n", + "where the left hand side of each equation indicates the transition and the right hand side the rate at which it occurs.\n", + "One advantage of specifying our system using the transition approach is that many will find transitions a more intuitive language when thinking about compartmental models.\n", + "Perhaps more beneficial, though, is that when building models with transitions using PyGOM, it enables the computer to do our book-keeping when converting transitions to ODE equations.\n", "This reduces the error of, for example, including a flow out of one state, but forgetting to include it in the recipient state.\n", - "For instance, in this case, we had to remember to include $-\\frac{\\beta SI}{N}$ in the $S$ equation and the opposite sign in the $I$ equation.\n", + "For example, in the case above, when indicating infections with $-\\frac{\\beta SI}{N}$ in the $S$ equation, we had to remember to include the opposite sign in the $I$ equation.\n", "\n", "## Defining the model with PyGOM\n", "\n", - "Defining the system is handled by feeding {class}`.Transition` classes into the main class we referred to at the start, {class}`.SimulateOde`.\n", - "The {class}`.Transition` class has 4 types, which are specified by the `transition_type` argument.\n", - "This lets {class}`.SimulateOde` know in which format we are inputting our information.\n", - "This could be as `.Transitions` or `ODEs` as we've just been discussing, or as the other two available options, namely `Birth` and `Death` processes.\n", - "The {class}`.Transition` class accepts 3 or 4 parameters depending on which type is being defined as summarised in the below table:\n", + "Defining the system is handled by feeding {class}`.Transition` objects into the central class we referred to at the start, {class}`.SimulateOde`.\n", + "The {class}`.Transition` class has 4 types, which are specified by the `transition_type` argument, letting {class}`.SimulateOde` know in which format we are inputting our information.\n", + "This type could be `Transition` or `ODE`, as we've just been discussing, or one of two other available options, namely `Birth` and `Death` processes.\n", + "The {class}`.Transition` class accepts 3 or 4 parameters depending on which type is being defined, as summarised in the below table:\n", "\n", "| | Transition | Equation | Birth | Death |\n", "|:---------------:|:-------------------------------:|:---------------------------------:|:--------------------------------------:|:--------------------------------------:|\n", @@ -87,10 +89,11 @@ "Arguably, the state which the birth process populates could be defined as a destination rather than an origin, but this is not the convention adopted here.\n", "\n", "Furthermore, the {class}`.Transition` class may have been better named.\n", - "This is because one of the four possible input types is also called \"transition\", which would incorrectly imply that it has a special place within the class, given that it shares its name.\n", + "One of the four possible input types is also called \"transition\", which would incorrectly imply that it has a special place within the class, given that it shares its name.\n", "```\n", "\n", - "Let's see how this is implemented for our example SIR system." + "Let's see how this is implemented for our example SIR system.\n", + "We import the relevant modules and then define our transitions:" ] }, { @@ -104,14 +107,14 @@ "\n", "# Define SIR model through a list of ODEs\n", "odeList = [\n", - " Transition(transition_type=TransitionType.ODE, origin='S', equation='-beta*S*I'),\n", - " Transition(transition_type=TransitionType.ODE, origin='I', equation='beta*S*I - gamma*I'),\n", + " Transition(transition_type=TransitionType.ODE, origin='S', equation='-beta*S*I/N'),\n", + " Transition(transition_type=TransitionType.ODE, origin='I', equation='beta*S*I/N - gamma*I'),\n", " Transition(transition_type=TransitionType.ODE, origin='R', equation='gamma*I') \n", "]\n", "\n", "# Define SIR model through a list of transitions\n", "transList = [\n", - " Transition(transition_type=TransitionType.T, origin='S', destination='I', equation='beta*S*I'),\n", + " Transition(transition_type=TransitionType.T, origin='S', destination='I', equation='beta*S*I/N'),\n", " Transition(transition_type=TransitionType.T, origin='I', destination='R', equation='gamma*I')\n", "]" ] @@ -122,7 +125,7 @@ "metadata": {}, "source": [ "We now initialise two {class}`.SimulateOde` objects using these different approaches.\n", - "In addition to the ODE or transition information, we must specify which variables are parameters and which refer to states." + "In addition to the ODE or transition information, we must specify which variables are parameters and which refer to states:" ] }, { @@ -133,7 +136,7 @@ "outputs": [], "source": [ "stateList = ['S', 'I', 'R']\n", - "paramList = ['beta', 'gamma']" + "paramList = ['beta', 'gamma', 'N']" ] }, { @@ -141,7 +144,7 @@ "id": "b6a2bec7", "metadata": {}, "source": [ - "We define the model in two different ways:" + "We import the relevant module and define the model in two different ways:" ] }, { @@ -161,7 +164,7 @@ "id": "8e38d76b", "metadata": {}, "source": [ - "We can use the {func}`.get_ode_eqn` function to verify that the models are equivalent" + "We can use the {func}`.get_ode_eqn` function to verify that the models are equivalent:" ] }, { @@ -191,9 +194,11 @@ "source": [ "## Modifying models\n", "\n", - "Once a {class}`.SimulateOde` object has been defined it may be modified.\n", + "Once an instance of {class}`.SimulateOde` has been defined it may be modified.\n", "For example, let's say we wish to add birth and death processes to the the previously defined SIR model of `model_ode`.\n", - "We must update the parameters of the class to reflect any additions." + "Time dependent parameters can be complicated in PyGOM, so here we will assume that birth and death rates cancel out so that $N$ remains a constant parameter.\n", + "If we assume that the birth rate is proportional to the total population, $\\mu N$, then balance can be achieved with a death rate from each compartment also proportional to $\\mu$ giving a total death rate of $\\mu (S+I+R)=\\mu N$\n", + "We must update the parameters of the class to reflect any additions:" ] }, { @@ -203,7 +208,7 @@ "metadata": {}, "outputs": [], "source": [ - "model_ode.param_list = model_ode.param_list + ['mu', 'B']" + "model_ode.param_list = model_ode.param_list + ['mu']" ] }, { @@ -211,7 +216,7 @@ "id": "f9236e77", "metadata": {}, "source": [ - "We then include the additional processes" + "We then include the additional processes, where we assume that all new births enter the population as susceptibles:" ] }, { @@ -221,7 +226,7 @@ "metadata": {}, "outputs": [], "source": [ - "birthDeathList = [Transition(origin='S', equation='B', transition_type=TransitionType.B), \n", + "birthDeathList = [Transition(origin='S', equation='mu*N', transition_type=TransitionType.B), \n", " Transition(origin='S', equation='mu*S', transition_type=TransitionType.D), \n", " Transition(origin='I', equation='mu*I', transition_type=TransitionType.D), \n", " Transition(origin='R', equation='mu*R', transition_type=TransitionType.D)]\n", @@ -234,7 +239,7 @@ "id": "3685b2e1", "metadata": {}, "source": [ - "We can again use {func}`.get_ode_eqn` to verify that the equations are updated" + "We can again use {func}`.get_ode_eqn` to verify that the equations are updated correctly:" ] }, { diff --git a/docs/notebooks/paramfit/bvpSimple.ipynb b/docs/notebooks/paramfit/bvpSimple.ipynb index f57ab79b..0a746040 100644 --- a/docs/notebooks/paramfit/bvpSimple.ipynb +++ b/docs/notebooks/paramfit/bvpSimple.ipynb @@ -9,7 +9,7 @@ "In addition to finding solutions for an initial value problem (IVP) and estimating unknown parameters, PyGOM also allows users to solve boundary value problems (BVPs) with a little bit of imagination.\n", "Here, we show how a BVP can be solved by treating it as a parameter estimation problem.\n", "Essentially, this is done via a shooting method where the first boundary condition defines the initial condition of an IVP and the second boundary condition is an observation.\n", - "We use projectile motion as our example system, which we note is not specific to disease modelling scenarios, but then BVPs are not commonly useful in this domain anyway." + "We use projectile motion as our example system, which we note is not relevant to disease modelling scenarios, but then BVPs are not commonly useful in this domain anyway." ] }, { @@ -40,12 +40,13 @@ "First, assuming we know that the acceleration due to gravity is $g=-10ms^{-2}$, we must estimate the initial velocity ($v(t=0)$) required to ensure that the ball lands 3 seconds later.\n", "This could be trivially solved via a quick analytical solution of the above equations resulting in $v(0)=15ms^{-1}$.\n", "Here we focus on demonstrating PyGOM's functionality, so this value will instead serve as a target we hope to reproduce.\n", - "For some reason, PyGOM will treat model parameters as unknowns and we must specify parameters (in this case $g$) numerically in our equations:" + "Another artefact of PyGOM, which will soon require changing, is that model parameters are automatically treated as unknowns.\n", + "For this example, it means that we must specify parameters (in this case $g$) numerically in our equations:" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "f244ed16", "metadata": {}, "outputs": [], @@ -56,7 +57,7 @@ "paramList=[]\n", "\n", "ode1 = Transition(transition_type=TransitionType.ODE, origin='y', equation='v')\n", - "ode2 = Transition(transition_type=TransitionType.ODE, origin='v', equation='-10')\n", + "ode2 = Transition(transition_type=TransitionType.ODE, origin='v', equation='-10') # -g replaced explicitly by -10\n", "\n", "model = SimulateOde(stateList, paramList, ode=[ode1, ode2])" ] @@ -72,21 +73,10 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "46ea09e8", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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8Udc4AIAAIAKURYBAABQIcpiNdhsNv3f//2fbDab2VFcFtu4frCd6x7buH6wnese27h+OON2dpkLXAAAAFD7GFkEAABAhSiLAAAAqBBlEQAAABWiLAIAAKBClEUAAABUiLJYjtdff13R0dHy8vJSr1699O233152+fXr16tXr17y8vJSmzZtNG/evHpK2rBVZTuvW7dOFovlkseBAwfqMXHDEhcXp7FjxyoiIkIWi0XLli274jrsy1VX1e3Mvlx1sbGx6tOnj/z8/BQSEqLx48fr4MGDV1yP/bnyqrON2Zerbu7cubr66qtL784yYMAAffHFF5ddxxn2Y8ri/1i0aJFmzJihP/zhD4qPj9eQIUM0ZswYJSUllbt8YmKibrjhBg0ZMkTx8fF66qmn9Jvf/EaLFy+u5+QNS1W3848OHjyolJSU0kf79u3rKXHDk5OTo27dumnOnDmVWp59uXqqup1/xL5ceevXr9f06dO1efNmrV69WkVFRRo1apRycnIqXIf9uWqqs41/xL5ceS1bttSLL76obdu2adu2bbr22ms1btw47d27t9zlnWY/NlBG3759jWnTppV5rVOnTsaTTz5Z7vK///3vjU6dOpV57YEHHjD69+9fZxldQVW389q1aw1JxoULF+ohneuRZCxduvSyy7Av11xltjP7cs2lpaUZkoz169dXuAz7c81UZhuzL9eOpk2bGm+99Va57znLfszI4s8UFBRo+/btGjVqVJnXR40apY0bN5a7zqZNmy5ZfvTo0dq2bZsKCwvrLGtDVp3t/KMePXooPDxcI0aM0Nq1a+syZqPDvly/2JerLzMzU5IUFBRU4TLszzVTmW38I/bl6ikuLtZHH32knJwcDRgwoNxlnGU/piz+THp6uoqLixUaGlrm9dDQUKWmppa7TmpqarnLFxUVKT09vc6yNmTV2c7h4eF68803tXjxYi1ZskQdO3bUiBEjFBcXVx+RGwX25frBvlwzhmFo5syZGjx4sLp06VLhcuzP1VfZbcy+XD27d+9WkyZNZLPZNG3aNC1dulQxMTHlLuss+7F7vf2kBsRisZR5bhjGJa9dafnyXkdZVdnOHTt2VMeOHUufDxgwQMnJyfr73/+uoUOH1mnOxoR9ue6xL9fMww8/rF27dmnDhg1XXJb9uXoqu43Zl6unY8eOSkhIUEZGhhYvXqzJkydr/fr1FRZGZ9iPGVn8meDgYLm5uV0yupWWlnZJs/9RWFhYucu7u7urWbNmdZa1IavOdi5P//79dfjw4dqO12ixL5uHfblyHnnkEa1YsUJr165Vy5YtL7ss+3P1VGUbl4d9+co8PT3Vrl079e7dW7GxserWrZv+9a9/lbuss+zHlMWf8fT0VK9evbR69eoyr69evVoDBw4sd50BAwZcsvyqVavUu3dveXh41FnWhqw627k88fHxCg8Pr+14jRb7snnYly/PMAw9/PDDWrJkib755htFR0dfcR3256qpzjYuD/ty1RmGofz8/HLfc5r9uF4vp2kAPvroI8PDw8OYP3++sW/fPmPGjBmGr6+vcfz4ccMwDOPJJ580Jk6cWLr8sWPHDB8fH+Oxxx4z9u3bZ8yfP9/w8PAwPvnkE7O+QoNQ1e38z3/+01i6dKlx6NAhY8+ePcaTTz5pSDIWL15s1ldwellZWUZ8fLwRHx9vSDJefvllIz4+3jhx4oRhGOzLtaWq25l9ueoefPBBIyAgwFi3bp2RkpJS+sjNzS1dhv25ZqqzjdmXq27WrFlGXFyckZiYaOzatct46qmnDKvVaqxatcowDOfdjymL5XjttdeM1q1bG56enkbPnj3LTB0wefJkY9iwYWWWX7dundGjRw/D09PTiIqKMubOnVvPiRumqmznl156yWjbtq3h5eVlNG3a1Bg8eLCxcuVKE1I3HD9Oa/G/j8mTJxuGwb5cW6q6ndmXq6687SvJWLBgQeky7M81U51tzL5cdVOnTi39u9e8eXNjxIgRpUXRMJx3P7YYxg9nSgIAAAD/g3MWAQAAUCHKIgAAACpEWQQAAECFKIsAAACoEGURAAAAFaIsAgAAoEKURQAAAFSIsggAAIAKURYBAABQIcoiAAAAKkRZBAAAQIX+H4HuGNqfDzZXAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import numpy as np\n", "t = np.linspace(0, 3, 100) # Time-points at which to find solutions\n", @@ -108,15 +98,14 @@ "id": "5c225208", "metadata": {}, "source": [ - "Let's now use PyGOM to solve for the initial condition that satisfies the BVP.\n", - "We use $20ms^{-1}$ as our initial guess.\n", - "It is perhaps a bit inefficient that we have to specify this initial guess twice both in the `theta` parameter and also the initial condition.\n", - "We let the solver know which variable we are solving the initial condition for by specifying the `target_state`." + "Let's now use PyGOM to solve for the initial condition that satisfies the BVP, using $20ms^{-1}$ as our initial guess.\n", + "It is admittedly a bit inefficient that we have to specify this initial guess twice both in the `theta` parameter and also the initial condition.\n", + "We let the solver know which variable we are solving the initial condition for by specifying the `target_state`:" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "f73ab2a2", "metadata": {}, "outputs": [], @@ -140,32 +129,15 @@ "id": "4734f011", "metadata": {}, "source": [ - "We use the {func}`costIV` function to let the solver know we are considering an initial value problem" + "And we use the {func}`costIV` function to let the solver know we are considering an initial value problem:" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "b70c7c06", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " message: Optimization terminated successfully.\n", - " success: True\n", - " status: 0\n", - " fun: 4.987646893079144e-16\n", - " x: [ 1.500e+01]\n", - " nit: 4\n", - " jac: [ 1.122e-10]\n", - " hess_inv: [[ 5.556e-02]]\n", - " nfev: 10\n", - " njev: 5\n" - ] - } - ], + "outputs": [], "source": [ "thetaHat = minimize(fun=obj.costIV, x0=theta)\n", "print(thetaHat)" @@ -181,21 +153,10 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "cc728465", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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crlUXFzcblkDXVs+64yMDD311FN644039Oabb6pfv346/fTTNW/evI6IHHK4tjsO17Zv2Latu+++WyeeeKIGDx7c4uu4tn3jWD9vru+2W7t2reLi4hQZGalbb71Vs2bN0sCBA4/4Wn+6rsM69N0MsSzrkB/btn3Yc0d7/ZGex+Fa81n369dP/fr1a/7xhAkTlJeXp7/97W866aST2jVnqOLa7hhc275x++23a82aNZo/f/5RX8u1ffyO9fPm+m67fv36adWqVSotLdUbb7yh6667TnPnzm2xMPrLdR3UI4udO3eW0+k8bGSrqKjosLbepEuXLkd8fVhYmFJSUtota6Bry2d9JOPHj9fWrVt9HQ/i2jaNa7t17rjjDr3zzjv6/PPPlZ2d/Z2v5do+fq35vI+E6/vYREREqHfv3ho9erSmT5+uYcOG6Z///OcRX+tP13VQl8WIiAiNGjVKc+bMOeT5OXPmaOLEiUf8NRMmTDjs9R9//LFGjx6t8PDwdssa6NryWR/JypUrlZGR4et4ENe2aVzbx8a2bd1+++1688039dlnn6lHjx5H/TVc223Xls/7SLi+28a2bdXV1R3x5/zquu7wJTUdbMaMGXZ4eLj97LPP2hs2bLCnTZtmx8bG2rt27bJt27bvvfde+9prr21+/Y4dO+yYmBj7rrvusjds2GA/++yzdnh4uP3666+b+r8QMFr7Wf/jH/+wZ82aZW/ZssVet26dfe+999qS7DfeeMPU/4WAUlFRYa9cudJeuXKlLcl+6KGH7JUrV9q7d++2bZtr25da+1lzbbfdj370IzsxMdH+4osv7IKCguZHdXV182u4tn2nLZ8313fb3Hffffa8efPsnTt32mvWrLF/+ctf2g6Hw/74449t2/bv6zroy6Jt2/Zjjz1md+vWzY6IiLBHjhx5yJYA1113nX3yyScf8vovvvjCHjFihB0REWF3797dfuKJJzo4ceBqzWf94IMP2r169bKjoqLspKQk+8QTT7Rnz55tIHVgatq+4tuP6667zrZtrm1fau1nzbXddkf6nCXZzz33XPNruLZ9py2fN9d32/zwhz9s/n5MTU21Tz/99OaiaNv+fV1btt14tyQAAADwLUF9zyIAAACOD2URAAAALaIsAgAAoEWURQAAALSIsggAAIAWURYBAADQIsoiAAAAWkRZBAAAQIsoiwAAAGgRZREAAAAtoiwCAACgRf8PwFmKu+Rd1aIAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "model.initial_values = ([0.0] + thetaHat['x'].tolist(), t[0])\n", "\n", @@ -222,7 +183,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "110edf3a", "metadata": {}, "outputs": [], @@ -255,32 +216,15 @@ "id": "f3719cf8", "metadata": {}, "source": [ - "We see that the result of $g=10ms^{-2}$ is recovered" + "We see that the result of $g=10ms^{-2}$ is recovered:" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "1be53116", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " message: Optimization terminated successfully.\n", - " success: True\n", - " status: 0\n", - " fun: 1.1241808584714344e-15\n", - " x: [ 1.000e+01]\n", - " nit: 4\n", - " jac: [-1.068e-11]\n", - " hess_inv: [[ 2.469e-02]]\n", - " nfev: 10\n", - " njev: 5\n" - ] - } - ], + "outputs": [], "source": [ "print(thetaHat)" ] diff --git a/docs/notebooks/paramfit/params_via_abc.ipynb b/docs/notebooks/paramfit/params_via_abc.ipynb index 73d76ac7..9d2ca1f4 100644 --- a/docs/notebooks/paramfit/params_via_abc.ipynb +++ b/docs/notebooks/paramfit/params_via_abc.ipynb @@ -13,10 +13,8 @@ "id": "05daf2f1", "metadata": {}, "source": [ - "Here we demonstrate how PyGOM uses Approximate Bayesian Computation to estimate posterior distributions for parameters.\n", - "\n", - "As an example, we use a synthetic data set produced by PyGOM's {func}`solve_stochast ` function.\n", - "This is a stochastic epidemic simulation of an SEIR model with parameters:\n", + "Here we demonstrate how PyGOM uses Approximate Bayesian Computation (ABC) to estimate posterior distributions for parameters given a candidate model and some data.\n", + "As an example, we use synthetic data produced by PyGOM's {doc}`solve_stochast <../model_solver>` function, the result of a stochastic epidemic simulation of an SEIR model with parameters:\n", "\n", "$\\beta=0.35,\\quad \\alpha=0.5,\\quad \\gamma=0.25,\\quad n_{\\text{pop}}=10^4,\\quad I(t=0)=5$\n", "\n", @@ -25,7 +23,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "de300402", "metadata": {}, "outputs": [], @@ -42,36 +40,15 @@ "id": "0ba66de0", "metadata": {}, "source": [ - "We inspect the time series of the infected and removed populations:" + "We inspect the time series of the daily infected and removed populations:" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "7660a673", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 1.0, 'R')" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA/MAAAGbCAYAAACIxMC9AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABzV0lEQVR4nO3dfXyU1Z3///ckhARiMpLEZJKKkGKwxoAFrBCwSpEgWECrXS1UVivrDQg1ij8t9dsFthbE/lbsNpW6XSpqBPr97UqVlaaGorjcFSSyEEIVbVAoM0YgTLhLgsn1+yPONJNMMtckcz+v5+MxD83MmSvn4kpy5nOdcz4fi2EYhgAAAAAAQNRICHcHAAAAAACAfwjmAQAAAACIMgTzAAAAAABEGYJ5AAAAAACiDME8AAAAAABRhmAeAAAAAIAoQzAPAAAAAECUIZgHAAAAACDKEMwDAAAAABBlCOYB9Mjq1atlsVj03nvvhbsrAACgF1xjuuvRp08f5ebm6nvf+54OHToU7u4B6EKfcHcAAAAAQPi9+OKL+trXvqbGxkZt27ZNP/vZz/T222/rL3/5iwYMGBDu7gHogGAeAAAAgIqKinTNNddIksaPH6+WlhYtWrRIv//97/WDH/wgzL0D0BHL7AEAAAB04grsP/vsszD3BIA3BPMAAAAAOqmtrZUkDR06NMw9AeANy+wBAAAAqKWlRV988YV7z/xTTz2l66+/XtOnTw931wB4QTAPAAAAQGPGjPH4+sorr9Trr7+uPn0IGYBIxDJ7AAAAAHr55Ze1e/dubd68WQ888IAOHjyoGTNmhLtbALrAbTYAAAAAuvLKK91J7771rW+ppaVF//Ef/6H//M//1He/+90w9w5AR8zMAwAAAOjkmWee0YABA/TP//zPam1tDXd3AHRAMA8AAACgkwEDBmjhwoU6ePCg1qxZE+7uAOiAYB4AAACAV/Pnz9dll12mf/mXf1FLS0u4uwOgHYthGEa4OwEAAAAAAMxjZh4AAAAAgChDMA8AAAAAQJQhmAcAAAAAIMoQzAMAAAAAEGUI5gEAAAAAiDIE8wAAAAAARJk+4e5AT7S2turYsWNKS0uTxWIJd3cAAAgpwzB0+vRp5eXlKSEh9u7LM84DAOKZ2XE+KoP5Y8eOaeDAgeHuBgAAYXXkyBFdeuml4e5GwDHOAwDge5yPymA+LS1NUtvJpaenh7k3AACEVkNDgwYOHOgeD2MN4zwAIJ6ZHeejMph3LblLT09nkAcAxK1YXYLOOA8AgO9xPvY22gEAAAAAEOMI5gEAAAAAiDIE8wAAAAAARBmCeQAAAAAAooxfwfzKlSs1fPhwd0Ka4uJi/eEPf3C/bhiGFi9erLy8PPXr10/jx4/XgQMHPI7R1NSk+fPnKysrS6mpqZo+fbqOHj0amLMBAAAAACAO+BXMX3rppXr66af13nvv6b333tOECRN0yy23uAP2Z555Rs8++6zKysq0e/du2Ww2lZSU6PTp0+5jlJaWav369Vq3bp22bt2qM2fOaOrUqWppaQnsmQEAAAAAEKP8CuanTZumm2++WUOHDtXQoUP1s5/9TBdddJF27twpwzD03HPP6cknn9Rtt92moqIivfTSSzp37pzWrFkjSXI6nVq1apX+9V//VRMnTtSIESNUXl6u/fv3a9OmTUE5QQAA4t3ixYtlsVg8Hjabzf16oFbW1dfXa9asWbJarbJarZo1a5ZOnToVilMEACDu9HjPfEtLi9atW6ezZ8+quLhYtbW1cjgcmjRpkrtNcnKybrjhBm3fvl2StGfPHl24cMGjTV5enoqKitxtvGlqalJDQ4PHA0BgtLQa2vHxCb2+92/a8fEJtbQa4e4SgCC46qqrZLfb3Y/9+/e7XwvUyrqZM2dq7969qqioUEVFhfbu3atZs2aF9DwBAAgW1+fm9VVHtep//qr/2tP23/Xvh+dzdB9/37B//34VFxersbFRF110kdavX6/CwkJ3MJ6Tk+PRPicnR5988okkyeFwqG/fvhowYECnNg6Ho8vvuWzZMi1ZssTfrgLwoaLariUbamR3Nrqfy7WmaNG0Qk0uyg1jzwAEWp8+fTxm4106rqyTpJdeekk5OTlas2aNHnjgAffKuldeeUUTJ06UJJWXl2vgwIHatGmTbrrpJh08eFAVFRXauXOnRo8eLUn6zW9+o+LiYn3wwQe64ooruuxbU1OTmpqa3F9z0x4A0BstrYZ21Z6Uw3leJ8826+L+fXXqXO/+u+Pj46o8WCfn+Qtdft9Qf472O5i/4oortHfvXp06dUr/9V//pbvvvltbtmxxv26xWDzaG4bR6bmOfLVZuHChHn30UffXDQ0NGjhwoL9dB9BORbVdc8qr1PH+ocPZqDnlVVp510gCeiCGHDp0SHl5eUpOTtbo0aO1dOlSffWrX/W5su6BBx7wubLupptu0o4dO2S1Wt2BvCSNGTNGVqtV27dv7zaY56Y9AKAjswF5xkXJyr4oWbJIdQ2N2vaR76A7WOwh/hztdzDft29fXX755ZKka665Rrt379YvfvELPfHEE5LaZt9zc//e8bq6Ovdsvc1mU3Nzs+rr6z1m5+vq6jR27Nguv2dycrKSk5P97SqALrS0GlqyoaZTIC9JhiSLpCUbalRSaFNiQvc34wBEvtGjR+vll1/W0KFD9dlnn+mpp57S2LFjdeDAAffKuN6urHM4HMrOzu70vbOzs7tdfSdx0x4A4omZIN3MLHgkC9XnaL+D+Y4Mw1BTU5Py8/Nls9lUWVmpESNGSJKam5u1ZcsWLV++XJI0atQoJSUlqbKyUnfccYckyW63q7q6Ws8880xvuwLApF21Jz2W1ndkqO3O4q7akyoekhm6jgEIiilTprj/f9iwYSouLtaQIUP00ksvacyYMZICs7LOW3szx+GmPQBEv3gI0s0I5edov4L5H//4x5oyZYoGDhyo06dPa926dXrnnXdUUVEhi8Wi0tJSLV26VAUFBSooKNDSpUvVv39/zZw5U5JktVo1e/ZsLViwQJmZmcrIyNBjjz2mYcOGuffgAQi+TTXdz5K5VNY4COaBGJSamqphw4bp0KFDuvXWWyX1fmWdzWbTZ5991ul7ff75551m/QEA0a998B7Ope2Rqu501xNngeJXMP/ZZ59p1qxZstvtslqtGj58uCoqKlRSUiJJevzxx3X+/HnNnTtX9fX1Gj16tN566y2lpaW5j7FixQr16dNHd9xxh86fP68bb7xRq1evVmJiYmDPDIBXFdV2rdp22FTb3247rGsGDdDNw/OC2ykAIdXU1KSDBw/qm9/8ZsBW1hUXF8vpdGrXrl269tprJUl//vOf5XQ6u91KBwCITN3NtMfDDHtvZaelBP17WAzDiLo6VA0NDbJarXI6nUpPTw93d4Co0dJq6Lrlm7tdYt9RgkUqmzFSNw/veRIP12BQd7pR2WkpujY/g734QC/4Ow4+9thjmjZtmi677DLV1dXpqaee0pYtW7R//34NGjRIy5cv17Jly/Tiiy+6V9a98847+uCDD9w35OfMmaP//u//1urVq90r606cOKE9e/a4b8hPmTJFx44d0wsvvCBJuv/++zVo0CBt2LAhqOcHADDH11J4VzK53YdPavX2wzpFsO43iySbNUVbn5jQ48+7ZsfBXu+ZBxA9fO2V96bVkOauqdKvE3qWlZPyd0D4HT16VDNmzNDx48d1ySWXaMyYMdq5c6cGDRokKXAr61599VX98Ic/dGe9nz59usrKykJ7sgAAN5bCh8eiaYUhmbhiZh6II6/v/ZseXre3R+/N7cEdxq7K37mOQPk7oGdifRyM9fMDgGAheA+vQE1YMTMPoJPe7N3xNysn5e8AAABCo6XVUNnmj/TitlqWxoeANaWPSgpzVDwky709wZYe+q2kBPNAHLk2P0O51hQ5nI1eg2xf/MnKSfk7AACA4Og4A7+x2qFzzS3h7lbE6Rh0eyuX589/wxW0d4VgHogjiQkWLZpWqDnlVbJIfgf0/szsmw38Q1G2AwAAIBbE4wy8r4DclbRPFqmuoVEnz0Ze0B0sBPNAnJlclKuVd43slJSuO66snNfmZ5j+PmYD/8PHz5k+JgAAQDyJ5Rl4M0F6PATkvUEwD8ShyUW5Kim0eZSLO36mSfPXvu+1vSHp5qK29mb/oJpd0v/cpg91he0iEuEBAAC0460iUDQgSA8dgnkgTiUmWDrtVU9KtHQaNBIsbeXpVm07rFXbDpvO0ula0v9geZXPvpAIDwAA4O827rNr7hrfn6EigSt4H1dwCUF6iBHMA3BrP2NfWePQb7cdVmuHaXWHs1FzyqtMlZWbXJSrRyYWaMWmQ122IREeAACIV+2X0Z882zZ7vf2jz/Xa+8fC3TW3rmbamWEPP4J5AB4SEyy6Nj9Dj/7fvV5f97es3OCsVFPfl0R4AAAgXoQ7kV13AbormdzxM03KTiNYj2QE8wA6CWRZObOJ8PzJlA8AABCNXEH8C+9+HNJEdiyFj00E80CMcy3fciW6M/PHe1ONw9Sxfc2mt7Qaam01dHG/pG7vOidYpPqzzaa+JwAAQLQJdRDfPylBNw/LJXiPcQTzQAzzlgXVlp6sGddepsFZqV6D+4pqu1ZtO2zq+N3NpvuTgbXVkB5aU6WVCb734QMAAESLUAfxF/dL0g/GDda8CQUE73GAYB6IURXVds0pr+pUFs7R0OSRkK59dvqWVkNLNtT4PLavuvNdfW9fyGoPAACinWtVZGWNQ//3vaM60/RF0L4XM/DxjWAeiEGuoNxMMN0+O721X19TM+mGpEXTCr0OFv58747HtDsbtXpbre4Zl89ABAAAokook9oxAw+JYB6ISb4S2LXXPjv945O/Zuo9944b3OVyeH++tzc/ffOg/mNrrala9gAAAOEWyqX0Pxg7SJOuymUGHpII5oGY5G+ZN9es+MkzTabalxTaAva9vfGnlj0AAEA4hDKIH9A/SctuG8bnInggmAdiUE/LvGWk9lWuNUUOZ6PXZfK+9sr35nu3528tewAAgFAJZRDPcnp0h2AeiEHX5mfIlp4iR4N/s+Q2az8tmlaoOeVVskgeAb1r+Ohqr3z7793dDQGz/KllDwAAEGzBDOJdieyKh2Tp1LlmZVyUTEI7+EQwD8SgyhqHGr8wP8i0n3FPTLBo5V0jO5WVy/mypF3TF63a8fGJLgeXxARLtzcEDEkWi2SYjPQDsWwfAACgp4IZxKf2TdT913+VmXf0CME8EGN6UhauY3b6yUW5Kim0aVftSdWdbtTh4+e0dtenXZa066ik0KbSiUM7ZXO1WVP0vW8M9DiOL4FYtg8AANATFdV2/ei1/Tp1LrDZ6QniEQgE80AMaWk1tPgN/8vCectOn5hgUfGQTFVU2/Xcpg8716vvIkldRbW906x++/1e/73vmOl+5frYnw8AABAsG/fZNXdNVUCPyR54BBLBPBBDyjYf8nufvNR1dvruasZ7S1LX1aoA5/kLem7TIV1hS/Nrpt3X/nwAAIBg2LjvmOatfT8gx7ooOVF3XjNQEwtt7IFHQBHMAzGiotru1/J1yXd2el8149snqbs2P6PLVQHtA/8t/8+3fCbIs0h6+MaCbkvgAQAABEPbjHzvA3mW0iPYCOaBGOCaQfeHmez0ZpPP1Z1u9LkqwBX47/mkvssEee3bPvenQ1q3+1PNuPYyDc5KVXYaGV0BAEBwBWJGniAeoUIwD8QAXzPo3ti6SWDnYnZJ/OHj50yvCqg73ahbvv4VrxnzO3I0NJlOugcAANAbvZ2RJ4hHqBHMAzHAn/Jts8cNNr1ny0zN+Jy0vlq761PT3991g8CVMX/nxyf00Joqj6z3Xekq6R4AAEBPtbQa+rc/HdK//cm/7YouBPEIF4J5IAaYnUF/ZOJQPTyxwPRxu6sZ73KmuUVnm5pNHa9jdvrEBIsSEiymAnnJe9I9AACAnupN6TmCeIRbQrg7AKD3XDPo3Q0jtvRkzZtwud/HnlyUq5V3jZS1f5LX1882tZg+lrf9+f6sKpA8k+4BAAD01MZ9dj1YXuV3IG+RVHpjgfYtvkkPTxxKII+wIZgHYoBrBl1Sp4De8uVj8fSrejzYlBTalNInsVd9fGTiUK9L4/0pVdeevzcBAAAAXNoS3fWshvyvZo5QaQlBPMKPYB6IEa4ZdJvVMzi2WVN6vcd8V+3JHtWvd/ehm1UBZlYVeNPTmwAAACC+uRLdtXaVEKgLCRbp+ZkjdfPwvOB0DPATe+aBGOJKKrer9qTqTjcGrJxbT2fBXd+1u1UBZvbldzymrcPeewAAAF96m+iubMYI3TycBLyIHATzQIxoaTU8gvipw/MCtvyrp7PgZsrfSX9fVeCrVJ3rbLztvQcAAOhKbxLdJVikshkjCeQRcQjmgRhQUW3vFAgHsia7mRJ13vy/371a4wqyTLXtuKrg8PFzWrvrU4/l/WZvDgAAALhUVLcluuspZuQRqQjmgShXUW3XnPKqTkF2IGuy+7sU3uX42Sa/v0/xkEz31/MmXN62X995XifPNivjomRZ+/VVS6vBzDwAAPCppdXQ4jdqevTeAf2TtOy2YUwiIGIRzANRrKXV0JINNV6D60DXZDe7FL69ni7Pb79lwNsMfSBXHQAAgNhVtvmQ30l8LZIevrFA82+kfjwiG8E8EMV21Z7sNrBuX5O9/Yx3T00uylVrqzR3TfdL1XqTpM7bloGOArnqAAAAxKaKartWbPI/2d2vZo4gYz2iAqXpgChmNst8oGqyt7Qa+umb5paq9SRJnWvLgK+Zf+PLx+I3DqjF37oyAAAg5rlWL/qD0nOINgTzQBQzu4w9UDXZfa0EcCmdONTvGfPutgx0xdHQpLLNH/n1fQAAQOwz+5mlPRLdIdoQzANR7Nr8DNnSuw7ULWrbXx6omuxmZ/gHZ/X3+9g9GXQlacWmD1VRbff7fQAAIDa1tBp6ecdh0+0H9E/Sr+9iRh7Rhz3zQJRqaTVUtvkjNTR6r5cajJrswVwJ0JutAIFK8gcAAKKbv/XkvzvyUi3/7nA+QyAqEcwDUcjMQHVxEMqp+Ko335vEd73ZChDIJH8AACA6+VtP3paeTCCPqMYyeyAMWloN7fj4hF7f+zft+PiEX0ncXAOVrzvOyX0SVFJo621XPbjqzUt/n/l36e1KANeNgp4Op4FK8gcAAKJPTxLeLZ5+FYE8oppfwfyyZcv0jW98Q2lpacrOztatt96qDz74wKPNPffcI4vF4vEYM2aMR5umpibNnz9fWVlZSk1N1fTp03X06NHenw0QBSqq7bpu+WbN+M1OPbxur2b8ZqeuW77Z1L5vfwYqR0OTdtWe7G13O3HVm7dZPWfSbdaUXpWK6+5GgRmBSvIHAACij7+5d+4dN5jytoh6fi2z37Jlix566CF94xvf0BdffKEnn3xSkyZNUk1NjVJTU93tJk+erBdffNH9dd++fT2OU1paqg0bNmjdunXKzMzUggULNHXqVO3Zs0eJiYm9PCUgcrlKr3WchzdbN93fgSpYs9WTi3JVUmjTrtqTqjvdqOy0tqX1vb277bpR0LHOfIJF6m7xgi09OWBJ/gAAQPTZVOPwq32gVy8C4eBXMF9RUeHx9Ysvvqjs7Gzt2bNH119/vfv55ORk2Wzef0GcTqdWrVqlV155RRMnTpQklZeXa+DAgdq0aZNuuukmf88BiArdlV4z1DYb7SuRm7/BeTBnqxMTLEHZo+7tRkH92WY9tKZtD5y3f7/GL1pVWePgDjsAAHFo4z67Vm07bLp9ICv9AOHUqz3zTqdTkpSR4fnL8M477yg7O1tDhw7Vfffdp7q6Ovdre/bs0YULFzRp0iT3c3l5eSoqKtL27du9fp+mpiY1NDR4PIBo42tW3dDfE7l1xZ/gPJoHKteNglu+/hUVD8nUzcPbZuyt/ZO8tneeu6A55VWUqAMAIM5s3HdM89aaT3pnUWAr/QDh1ONg3jAMPfroo7ruuutUVFTkfn7KlCl69dVXtXnzZv3rv/6rdu/erQkTJqipqUmS5HA41LdvXw0YMMDjeDk5OXI4vC+PWbZsmaxWq/sxcODAnnYbCBuzs+rdtTObJC4WB6qSQptS+njfhuOarV+yocavZIIAACB6VVTbNXfN+91uxWtvQP+kXuX3ASJNj4P5efPmad++fVq7dq3H83feeae+/e1vq6ioSNOmTdMf/vAHffjhh3rzzTe7PZ5hGLJYvAceCxculNPpdD+OHDnS024DYROIGu1mksTF6kC1q/akHA29W9kAAABig7/Z66cU5ei9/1MSc5+PEN96FMzPnz9fb7zxht5++21deuml3bbNzc3VoEGDdOjQIUmSzWZTc3Oz6uvrPdrV1dUpJyfH6zGSk5OVnp7u8QCija9ZdYvMLY3vKpv8xf2S9MjEgpgdqAKxsgEAAMQGf5MC/2NxfkytWAQkPxPgGYah+fPna/369XrnnXeUn5/v8z0nTpzQkSNHlJvbFlyMGjVKSUlJqqys1B133CFJstvtqq6u1jPPPNODUwCig2tWfU55lSzyTOTmb432YGWTj2SBWNkAAABigz/Z66M5jxDQHb+C+Yceekhr1qzR66+/rrS0NPced6vVqn79+unMmTNavHixbr/9duXm5urw4cP68Y9/rKysLH3nO99xt509e7YWLFigzMxMZWRk6LHHHtOwYcPc2e2BWNVV6TWbNUWLphX6NaMerGzykcq1ssHhbPSa0d6itn9HBmsAAGJbRbV/2etjLY8Q4OJXML9y5UpJ0vjx4z2ef/HFF3XPPfcoMTFR+/fv18svv6xTp04pNzdX3/rWt/S73/1OaWlp7vYrVqxQnz59dMcdd+j8+fO68cYbtXr1amrMIy7E46x6IARyZQMAAIhO/uyVT7BIZTNiL48Q4GIxDCPqUj83NDTIarXK6XSyfx6IMxXV9k4rG3J7sLIBiGaxPg7G+vkB6LkdH5/QjN/sNNX2+ZkjdPPwvCD3CAg8s+Ngr+rMAwidllZDOz4+odf3/k07Pj4RtyXYJhflausTE7T2vjH6xfe+rrX3jdHWJyYQyAN+WLZsmSwWi0pLS93PGYahxYsXKy8vT/369dP48eN14MABj/c1NTVp/vz5ysrKUmpqqqZPn66jR496tKmvr9esWbPc5WRnzZqlU6dOheCsAMQDs3vl7x03mEAeMc+vZfYAgqul1fC6/N7bbPTF/ZL0g3GDNW9CQdwtLY+3fAFAIO3evVv//u//ruHDh3s8/8wzz+jZZ5/V6tWrNXToUD311FMqKSnRBx984N4qV1paqg0bNmjdunXKzMzUggULNHXqVO3Zs8e9VW7mzJk6evSoKioqJEn333+/Zs2apQ0bNoT2RAHEnI37zO+VLym0BbczQARgmT0QIbpaPj796lz9+7u1XpO+SdLF/ZP09G3DmJkG4khPx8EzZ85o5MiRev755/XUU0/p61//up577jkZhqG8vDyVlpbqiSeekNQ2C5+Tk6Ply5frgQcekNPp1CWXXKJXXnlFd955pyTp2LFjGjhwoDZu3KibbrpJBw8eVGFhoXbu3KnRo0dLknbu3Kni4mL95S9/0RVXXBHU8wMQuzbuO6Z5a9+Xr4WJroS4W5+YEHeTHYgdLLMHokhFtV1zyqs61Uu1Oxv1QjeBvCSdOndBc8qrVFFtD24nAUS9hx56SN/+9rc7VY+pra2Vw+HQpEmT3M8lJyfrhhtu0Pbt2yVJe/bs0YULFzza5OXlqaioyN1mx44dslqt7kBeksaMGSOr1epu401TU5MaGho8HgDgUlFt19w1vgN5qS1BLglxES8I5oEwc2Vl7c0SGUPSkg01cbePnjwCgHnr1q1TVVWVli1b1uk1V6nZnJwcj+dzcnLcrzkcDvXt21cDBgzotk12dnan42dnZ7vbeLNs2TL3Hnur1aqBAwf6d3IAYpY/2eultr3yrFZEvGDPPBBmu2pPdpqR7wm7s1G7ak/GzV5ystoD5h05ckQPP/yw3nrrLaWkpHTZzmLxnMkyDKPTcx11bOOtva/jLFy4UI8++qj764aGBgJ6AJKknX894dfnJPbKI54wMw+EWd3p3gfywThWJOtqW4LD2ciWA8CLPXv2qK6uTqNGjVKfPn3Up08fbdmyRf/2b/+mPn36uGfkO86e19XVuV+z2Wxqbm5WfX19t20+++yzTt//888/7zTr315ycrLS09M9HgBQUW3XQ69WmW6fa21LHgzEC4J5IMyy07qeJQvnsSJVd9sSXM/F45YDoDs33nij9u/fr71797of11xzjb7//e9r7969+upXvyqbzabKykr3e5qbm7VlyxaNHTtWkjRq1CglJSV5tLHb7aqurna3KS4ultPp1K5du9xt/vznP8vpdLrbAIAZrhv3p85fMP0e9soj3rDMHgghb6Xnrs3PkC09RY6Gns+quzK3xsPdaF/bEgzF35YDwJe0tDQVFRV5PJeamqrMzEz386WlpVq6dKkKCgpUUFCgpUuXqn///po5c6YkyWq1avbs2VqwYIEyMzOVkZGhxx57TMOGDXMn1Lvyyis1efJk3XfffXrhhRcktZWmmzp1qulM9gDgbz6hBItUNmMk2+wQdwjmgRDprvRc4xctXt/jurd8//X5+t17R3XqXOe706428XI32uxWgnjZcgAEyuOPP67z589r7ty5qq+v1+jRo/XWW2+5a8xL0ooVK9SnTx/dcccdOn/+vG688UatXr3aXWNekl599VX98Ic/dGe9nz59usrKykJ+PgCil7/5hMpmjNDNwwnkEX+oMw+EgGupmL+/bAP6J2nZ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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "plt.rcParams['figure.figsize'] = [10, 4]\n", @@ -91,14 +68,14 @@ "source": [ "```{note}\n", "We typically do not have access to information regarding the total infected population. More commonly reported is the number of new cases in a given time period (or infection times).\n", - "Furthermore, we are unlikely to know the removed population, unless, for example, the disease results in death.\n", + "Furthermore, we are unlikely to know the removed population, unless, for example, the disease results in death with high probability.\n", "Nevertheless, the purpose of this chapter is to demonstrate model fitting given a data set and so these departures from reality shouldn't undermine the key messages.\n", "```\n", "\n", - "In the next sections, we are going to use PyGOM to obtain estimates for unknown values $\\beta$, $\\alpha$ and $\\gamma$ (assuming that the total population $N$ and initial number of infecteds $I(t=0)$ are known).\n", + "In the next sections, we are going to use PyGOM to obtain estimates for unknown values $\\beta$, $\\alpha$ and $\\gamma$ (assuming that the total population, $N$, and initial number of infecteds, $I(t=0)$, are known).\n", "\n", "```{note}\n", - "Again, it is rather unrealistic to know $I(t=0)$ or $N$, but we proceed in this way for the sake of simplicity in our example.\n", + "Again, it is rather unrealistic to know $I(t=0)$ or indeed $N$, but we proceed in this way for the sake of simplicity in our example.\n", "```" ] }, @@ -110,20 +87,20 @@ "## Fitting an SEIR model (with Infected and Removed known)\n", "\n", "To obtain parameter estimates from data, we must provide a candidate model and specify the unknown parameters which we are interested in. Information regarding the candidate model is contained in {func}`abc.create_loss`, which requires:\n", - "1) A {class}`SimulateOde` object which describes the system of ODEs\n", - "2) The loss function, which describes how we assume observations are distributed about the mean value calculated from the {class}`SimulateOde` object.\n", - "3) `abc.Parameter` which informs which parameters we are interested in and their prior distributions.\n", - "4) The data to which we are fitting\n", + "1) A {class}`.SimulateOde` object which describes the system of ODEs\n", + "2) The loss function, which describes how we assume observations are distributed about the mean value predicted by the {class}`SimulateOde` object.\n", + "3) `abc.Parameter` which indicates which parameters we are interested in and their prior distributions.\n", + "4) The data to which we are fitting the parameters\n", "\n", "We start by specifying the ODE system. In this first example, we are going to assume (correctly) that the underlying process is an SEIR model.\n", "We need to let the model know the value of $N$, however, a feature of PyGOM is that we must pass values for all parameters.\n", - "This usually acts to ensure that we do not under-specify the set of parameters when running simulations.\n", - "Thus, even though the other parameters ($\\beta$, $\\alpha$ and $\\gamma$) are unknown, the model expects some values and so for now we can just pass zeros, which will be overrode later when we specify ABC parameters." + "This usually acts to ensure that we do not under-specify the set of parameters when running simulations, however, in this case it requires us to overspecify what we actually know.\n", + "Thus, even though the other parameters ($\\beta$, $\\alpha$ and $\\gamma$) are unknown, the model expects some values and so for now we can just pass some initial guess (in this case the half way points of our prior distributions defined below), which will be overrode later when we specify ABC parameters." ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "160c27ec", "metadata": {}, "outputs": [], @@ -132,9 +109,9 @@ "from pygom import common_models\n", "\n", "n_pop=1e4\n", - "paramEval=[('beta', 0), ('alpha', 0), ('gamma', 0), ('N', n_pop)]\n", + "paramEval=[('beta', 0.5), ('alpha', 1), ('gamma', 0.5), ('N', n_pop)]\n", "\n", - "ode_SEIR = common_models.SEIR_N_stochastic(param=paramEval)" + "ode_SEIR = common_models.SEIR_N(param=paramEval)" ] }, { @@ -143,12 +120,12 @@ "metadata": {}, "source": [ "The {class}`Parameter` class is used to specify the parameters we wish to infer and their prior probability distributions.\n", - "We can choose from any of the distributions included in PyGOM, here we take uniform distributions." + "We can choose from any of the distributions included in PyGOM, here taking uniform distributions." ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "42291b82", "metadata": {}, "outputs": [], @@ -172,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "dd353fe2", "metadata": {}, "outputs": [], @@ -226,7 +203,7 @@ "source": [ "If we want to run the method for a few more generations, there is no need to start from the beginning.\n", "Instead, we can use {func}`continue_posterior_sample` along with the `next_tol` attribute to set the tolerance.\n", - "Let's perform 2 additional iterations." + "Let's perform 2 additional iterations:" ] }, { @@ -244,7 +221,7 @@ "id": "83092942", "metadata": {}, "source": [ - "There are built in methods to plot the posterior distribution and the corresponding fit to the data " + "There are built in methods to plot the posterior distribution and the corresponding fit to the data:" ] }, { @@ -254,7 +231,7 @@ "metadata": {}, "outputs": [], "source": [ - "abcSEIR.plot_posterior_histograms()\n", + "abcSEIR.plot_posterior_histograms();\n", "abcSEIR.plot_pointwise_predictions();" ] }, @@ -294,86 +271,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "6132aacd", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Generation 1 \n", - " tolerance = inf \n", - " acceptance rate = 70.42%\n", - "\n", - "Generation 2 \n", - " tolerance = 68844.11979 \n", - " acceptance rate = 17.04%\n", - "\n", - "Generation 3 \n", - " tolerance = 12938.27625 \n", - " acceptance rate = 16.18%\n", - "\n", - "Generation 4 \n", - " tolerance = 3996.71842 \n", - " acceptance rate = 7.81%\n", - "\n", - "Generation 5 \n", - " tolerance = 1544.33260 \n", - " acceptance rate = 5.69%\n", - "\n", - "Generation 6 \n", - " tolerance = 932.12762 \n", - " acceptance rate = 4.59%\n", - "\n", - "Generation 7 \n", - " tolerance = 786.20244 \n", - " acceptance rate = 4.26%\n", - "\n", - "Generation 8 \n", - " tolerance = 745.97669 \n", - " acceptance rate = 9.37%\n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\users\\joseph.gibson\\pygom\\pygom\\approximate_bayesian_computation\\approximate_bayesian_computation.py:556: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown\n", - " f.show()\n", - "c:\\users\\joseph.gibson\\pygom\\pygom\\approximate_bayesian_computation\\approximate_bayesian_computation.py:634: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown\n", - " f.show()\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Posterior median estimates: beta=0.359, alpha=0.53, gamma=0.26 \n" - ] - }, - { - "data": { - "image/png": "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N1MjdANIZOFWugndgLMI3R4VbejOzPT/u29f8KenABAtt63plsx13bt3M9YBSFxspAa4A6Hbo6LZSE0yN1MzDKm83N4+AfAmt00vl8xKd3U1G0cCSFzhhm7WdAPOInR7VDRruiV2MAdgv8OHzbYbppdLwTuYc9kwAImqvunlrOkGYofQ7VHRTi+3hm7WdQOwgxunlwcq3RI7mANIXGykBrgDodujGju9XKLSDcAebttITeJa3QCSA2u6AXcgdHsU08sBuIUb13RbQzeVbgCJyjq93OcL/h5ruoHYIXR7VLSV7sAlwyRCNwB7uH1NN5VuAInKWuk+/nzPOr28sjI2/QG8itDtUY29ZJhE6AZgD7dXutlIDUCiqq/SbT3/s54XArAfodujrNOIIgnd1kr3vn22dQdISIWFhTr77LOVkZGhrKwsXXXVVdq4cWODj1u2bJkGDBig5s2bq3v37po+fXoMeutebgzdbKQGIBmEW+lmejngLEK3R9kxvZzQDa9btmyZ7rrrLq1cuVKLFy/WsWPHNGLECB08eDDkY4qKijR69GhdcMEFWrdunR566CHdc889mj9/fgx77i5u30iNSjdgr3A+sDQMQ5MmTVJeXp7S09M1bNgwffbZZ3HqceKyhu76Kt2EbsBZhG6PinZ6OaEbML399tu65ZZb1KdPH/Xr10+zZs3S9u3btWbNmpCPmT59urp06aIpU6aod+/e+tGPfqTbbrtNkydPjmHP3cW6ptstle7mzaUWLfxtKt2AvcL5wPLJJ5/UU089palTp2rVqlXKycnRJZdcov3798ex54kn3Ot0E7oBZ0UQt5BMqHQD9isvL5cktbPOTT7OBx98oBEjRgTdN3LkSM2cOVNHjx5VM+t2sh7hxunlkr/afegQoRuw29tvvx10e9asWcrKytKaNWt04YUXyjAMTZkyRQ8//LCuueYaSdKcOXOUnZ2tefPm6Y477ohHtxNSuNfpJnQDzqLS7VHRXjKsRQtzehIbqQEmwzCUn5+v888/X3379g15XGlpqbKzs4Puy87O1rFjx7R79+46H1NZWamKioqgr2Ti5tAtSXv2sMkQ4KTjP7AsKipSaWlp0AeUaWlpGjp0qN5///06nyPZx8loUekG3IHQ7VHRVrqbNDGnXH77/0gAksaNG6ePP/5YL730UoPH+o5bWGcYRp33BxQWFioz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/ssvvzRatGhhjB8/3vj888+N559/3mjWrJnxt7/9LcY9b1ik7238+PHGE088YfznP/8xNm3aZBQUFBjNmjUz1q5dG+Oe1y/S9xWwb98+o3v37saIESOMfv36xaazEYjmfX33u981Bg0aZCxevNgoKioyPvzwQ+Pf//53DHsdnkjf24oVK4wmTZoYv//9740vv/zSWLFihdGnTx/jqquuinHP67dw4ULj4YcfNubPn29IMl577bV6j0+k8cMqmcfJaET681iyZIkhydi4caNRUlJS+3Xs2LEY99wZXvk7CFekP49k/v0YOXKkMWvWLOPTTz811q9fb1x22WVGly5djAMHDoR8TKL+fiTrOJms55KGwfmkVSKcT3Iu6WfX2BHz0H3OOecYY8eODbrvtNNOMx588ME6j584caJx2mmnBd13xx13GOeee65jfYxWpO+tLqeffrrx6KOP2t21Ron2fV1//fXGT3/6U+PnP/+5KwfJSN/XW2+9ZWRmZhp79uyJRfcaJdL39pvf/Mbo3r170H1PP/200alTJ8f62FjhDJSJNH5YJfM4GY1Ifx6BULV3794Y9C6+kvnvIBqRhG4v/H6UlZUZkoxly5aFPCZRfz+SdZxM1nNJw+B8MiBRzic5l/Sza+yI6fTyqqoqrVmzRiNGjAi6f8SIEXr//ffrfMwHH3xwwvEjR47U6tWrdfToUcf6Gqlo3tvxampqtH//frVr186JLkYl2vc1a9Ysbd26VT//+c+d7mJUonlfCxYs0MCBA/Xkk0/qpJNOUs+ePXXffffp8OHDsehy2KJ5b0OGDNGOHTu0cOFCGYahXbt26W9/+5suu+yyWHTZMYkyflgl8zgZjcaMrf3791dubq4uvvhiLVmyxMluuloy/340hhd+P8rLyyWp3vOKRPz9SNZxMlnPJSXOJ60S4XySc0mTXWNHTEP37t27VV1drezs7KD7s7OzVVpaWudjSktL6zz+2LFj2r17t2N9jVQ07+14v/3tb3Xw4EF9//vfd6KLUYnmfW3evFkPPvig/vznPyslJSUW3YxYNO/ryy+/1HvvvadPP/1Ur732mqZMmaK//e1vuuuuu2LR5bBF896GDBmiP//5z7r++uuVmpqqnJwctWnTRs8880wsuuyYRBk/rJJ5nIxGND+P3NxczZgxQ/Pnz9err76qXr166eKLL9by5ctj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SdKtt96qf//733r55Zf18ccf67rrrtOll16qzZs3a8iQIZoyZYpat26tkpISlZSU6L777pPkD+u//OUv9dFHH+n1119XUVGRbrnllji+SwAI38GDB5Wfn69Vq1bpX//6l5o0aaKrr75aNTU1IR9z//33a/LkyVq1apWysrL03e9+V0ePHq39/qFDhzR58mS9+OKLWr58ubZv3147Zkr+E9wxY8ZoxYoVWrlypXr06KHRo0dr//79jr5XAKhLfn6+/v3vf2vBggVavHixVqxYEfRBYLjnepMmTdLUqVP1/vvvq7i4WN///vc1ZcoUzZs3T2+++aYWL16sZ555Jugxc+bMUYcOHfSf//xHd999t37yk5/ouuuu05AhQ7R27VqNHDlSN910U21Yr6mpUadOnfSXv/xFn3/+uX72s5/poYce0l/+8hdHf0ZIMAYQJ0OHDjV69+5t1NTU1N73wAMPGL179za2bNli+Hw+Y+fOnUGPufjii42CggLDMAxj1qxZRmZmZoOv85///MeQZOzfv9/W/gNALJSVlRmSjE8++cQoKioyJBnr1q0zDMMwlixZYkgyXn755drj9+zZY6SnpxuvvPKKYRj+sVKSsWXLltpjnn32WSM7Ozvkax47dszIyMgw/v73vzvzpgAghIqKCqNZs2bGX//619r79u3bZ7Ro0cIYP358nY85/lwvMDb+85//rD2msLDQkGRs3bq19r477rjDGDlyZO3toUOHGueff37t7WPHjhktW7Y0brrpptr7SkpKDEnGBx98EPI93Hnnnca1114b/ptG0qPSjbg699xz5fP5am8PHjxYmzdv1urVq2UYhnr27KlWrVrVfi1btizkNMuAdevW6corr1TXrl2VkZGhYcOGSZK2b9/u5FsBAFts3bpVN9xwg7p3767WrVurW7dukuofwwYPHlzbbteunXr16qUNGzbU3teiRQudcsoptbdzc3ODpmKWlZVp7Nix6tmzpzIzM5WZmakDBw4wbgKIuS+//FJHjx7VOeecU3tfZmamevXqVXs73HO9M888s7adnZ2tFi1aqHv37kH3Hb8E0fqYpk2bqn379jrjjDOCHiMp6HHTp0/XwIED1bFjR7Vq1UrPP/884yeCpMS7A0AoTZs21Zo1a9S0adOg+1u1ahXyMQcPHtSIESM0YsQIzZ07Vx07dtT27ds1cuRIVVVVOd1lAGi0K664Qp07d9bzzz+vvLw81dTUqG/fvhGPYdYPNJs1a3bC94xv98+QpFtuuUXffPONpkyZoq5duyotLU2DBw9m3AQQc4GxyTqGWe+P5FzPOvb5fL46x8Ljl+7UdczxzyOp9nF/+ctfdO+99+q3v/2tBg8erIyMDP3mN7/Rhx9+GPF7R/IidCOuVq5cecLtHj16qH///qqurlZZWZkuuOCCOh+bmpqq6urqoPu++OIL7d69W48//rg6d+4sSVq9erUznQcAm+3Zs0cbNmzQH/7wh9qx77333mvwcStXrlSXLl0kSXv37tWmTZt02mmnhf26K1as0HPPPafRo0dLkoqLi7V79+4o3gEANM4pp5yiZs2a6T//+U/tuVxFRYU2b96soUOHuu5cb8WKFRoyZIjuvPPO2vsampUJ72F6OeKquLhY+fn52rhxo1566SU988wzGj9+vHr27Kkbb7xRN998s1599VUVFRVp1apVeuKJJ7Rw4UJJ0sknn6wDBw7oX//6l3bv3q1Dhw6pS5cuSk1N1TPPPKMvv/xSCxYs0C9/+cs4v0sACE/btm3Vvn17zZgxQ1u2bNG7776r/Pz8Bh/3i1/8Qv/617/06aef6pZbblGHDh101VVXhf26p556ql588UVt2LBBH374oW688Ualp6c34p0AQHQyMjI0ZswY3X///VqyZIk+++wz3XbbbWrSpIl8Pp/rzvVOPfVUrV69Wu+88442bdqkRx55RKtWrYpbf+BOhG7E1c0336zDhw/rnHPO0V133aW7775b/+///T9J0qxZs3TzzTfr//7v/9SrVy9997vf1Ycfflj7qeaQIUM0duxYXX/99erYsaOefPJJdezYUbNnz9Zf//pXnX766Xr88cc1efLkeL5FAAhbkyZN9PLLL2vNmjXq27ev7r33Xv3mN79p8HGPP/64xo8frwEDBqikpEQLFixQampq2K/7pz/9SXv37lX//v1100036Z577lFWVlZj3goARO2pp57S4MGDdfnll+s73/mOzjvvPPXu3VvNmzd33bne2LFjdc011+j666/XoEGDtGfPnqCqNyBJPsO6qAsAACSMpUuXavjw4dq7d6/atGkT7+4AgCMOHjyok046Sb/97W91++23x7s7QMRY0w0AAADANdatW6cvvvhC55xzjsrLy/WLX/xCknTllVfGuWdAdAjdAAAAAFxl8uTJ2rhxo1JTUzVgwACtWLFCHTp0iHe3gKgwvRwAAAAAAIewkRoAAAAAAA4hdAMAAAAA4BBCNwAAAAAADiF0AwAAAADgEEI3AAAAAAAOIXQDAAAAAOAQQjcAAAAAAA4hdAMAAAAA4BBCNwAAAAAADvn/uyF2ld5Bp8gAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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ntbeeJYuXSoGDRok/Pz8RHR0tLj//vtFcXFxF4+6Zdf6+9gTc0NLmAOZAz2BObD75kBP5T+ZED3wOD8RERERERFRD8BruomIiIiIiIjchEU3ERERERERkZuw6CYiIiIiIiJyExbdRERERERERG7CopuIiIiIiIjITVh0ExEREREREbkJi24iIiIiIiIiN2HRTUREREREROQmLLrJpyxcuBBDhw719DCIiIiIiMhHyIQQwtODIOoMMpms1ftnzpyJZcuWwWKxIDQ0tItGRUREREREvoxFN3mN0tJS6ft169bhlVdewYkTJ6Q2Pz8/6PV6TwyNiIiIiIh8FE8vJ68RFRUlbXq9HjKZrEnb1aeXP/DAA5g2bRpef/11REZGolevXli0aBHsdjt++ctfIiQkBHFxcfj4449dnuv8+fOYPn06goODERoaiqlTp+Ls2bNdGzAREREREXV7LLrJ523evBkXLlzA9u3bsWTJEixcuBCTJ09GcHAw9uzZg1mzZmHWrFkoKioCAJjNZowdOxaBgYHYvn07du7cicDAQEycOBFWq9XD0RARERERUXfCopt8XkhICJYuXYqkpCQ89NBDSEpKgtlsxq9//WsMGDAA8+fPh1qtxnfffQcAWLt2LeRyOf785z8jPT0dKSkpWLlyJQoLC7F161bPBkNERERERN2K0tMDIPK01NRUyOX/+/wpMjISaWlp0m2FQoHQ0FCUl5cDAPbv349Tp05Bp9O57KehoQGnT5/umkETEREREVGPwKKbfJ5KpXK5LZPJmm1zOp0AAKfTiYyMDKxevbrJvsLDw903UCIiIiIi6nFYdBO10/Dhw7Fu3TpEREQgKCjI08MhIiIiIqJujNd0E7XT/fffj7CwMEydOhU7duxAQUEBtm3bhjlz5qC4uNjTwyMiIiIiom6ERTdRO/n7+2P79u2Ij4/H3XffjZSUFDz00EOor6/nkW8iIiIiInIhE0IITw+CiIiIiIiIyBvxSDcRERERERGRm7DoJiIiIiIiInITFt1EREREREREbsKim4iIiIiIiMhNWHQTERERERERuQmLbiIiIiIiIiI3YdFNRERERERE5CYsuomIiIiIiIjchEU3ERERERERkZuw6CYiIiIiIiJyExbdRERERERERG7CopuIiIiIiIjITf4/nnevc3nYcIMAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "objSEIR2 = abc.create_loss(\"PoissonLoss\",\n", " parameters,\n", @@ -391,20 +292,10 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "b9fb499c", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "beta=0.359 (0.330, 0.399)\n", - "alpha=0.526 (0.383, 0.740)\n", - "gamma=0.258 (0.242, 0.278)\n" - ] - } - ], + "outputs": [], "source": [ "print(f'beta={np.median(abcSEIR2.res[:,0]):.3f} ({np.quantile(abcSEIR2.res[:,0], 0.025):.3f}, {np.quantile(abcSEIR2.res[:,0], 0.975):.3f})')\n", "print(f'alpha={np.median(abcSEIR2.res[:,1]):.3f} ({np.quantile(abcSEIR2.res[:,1], 0.025):.3f}, {np.quantile(abcSEIR2.res[:,1], 0.975):.3f})')\n", @@ -416,12 +307,12 @@ "id": "c6542afd", "metadata": {}, "source": [ - "We still see estimates in agreement with the true parameter values, even though we have constrained the model with one fewer state.\n", + "We still see estimates in agreement with the true parameter values, even though we have reduced the amount of data made available to the ABC algorithm.\n", "\n", "## Fitting an SIR model (with only Infected known)\n", "\n", "Of course, we may not know the underlying mechanisms and might instead attempt to fit an SIR model to the infected data.\n", - "We follow similar steps as before, but now specifying and SIR model." + "We follow similar steps as before, but now specifying an SIR model:" ] }, { @@ -441,7 +332,7 @@ "x0=[n_pop-i0, i0, 0]\n", "\n", "# Set up pygom object\n", - "ode_SIR = common_models.SIR_N_stochastic(param=paramEval)\n", + "ode_SIR = common_models.SIR_N(param=paramEval)\n", "\n", "objSIR = abc.create_loss(\"PoissonLoss\", parameters, ode_SIR, x0, t[0], t[1:], sol_i_r[1:,0], ['I'])\n", "abcSIR = abc.ABC(objSIR, parameters)\n", @@ -458,7 +349,7 @@ "metadata": {}, "source": [ "Although we see smaller credible intervals, this actually reflects the restriction in model fitting, rather than increased precision.\n", - "We see that our inappropriate model choice here results in poorer parameter estimates." + "We see that our inappropriate model choice here results in poorer parameter estimates:" ] }, { @@ -485,7 +376,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "id": "85dc7fa9", "metadata": {}, "outputs": [], @@ -507,7 +398,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "id": "ca613e08", "metadata": {}, "outputs": [], @@ -535,90 +426,10 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "id": "2ba62e53", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Generation 1 \n", - " tolerance = inf \n", - " acceptance rate = 75.99%\n", - "\n", - "Generation 2 \n", - " tolerance = 56870.05009 \n", - " acceptance rate = 13.30%\n", - "\n", - "Generation 3 \n", - " tolerance = 18012.48554 \n", - " acceptance rate = 12.99%\n", - "\n", - "Generation 4 \n", - " tolerance = 4926.70805 \n", - " acceptance rate = 6.67%\n", - "\n", - "Generation 5 \n", - " tolerance = 2036.33956 \n", - " acceptance rate = 4.54%\n", - "\n", - "Generation 6 \n", - " tolerance = 1180.79752 \n", - " acceptance rate = 2.87%\n", - "\n", - "Generation 7 \n", - " tolerance = 879.70651 \n", - " acceptance rate = 1.33%\n", - "\n", - "Generation 8 \n", - " tolerance = 781.66943 \n", - " acceptance rate = 0.70%\n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\users\\joseph.gibson\\pygom\\pygom\\approximate_bayesian_computation\\approximate_bayesian_computation.py:556: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown\n", - " f.show()\n", - "c:\\users\\joseph.gibson\\pygom\\pygom\\approximate_bayesian_computation\\approximate_bayesian_computation.py:634: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown\n", - " f.show()\n" - ] - }, - { - "data": { - "image/png": "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ePBg3HrrrcjIyMA999wDq9XKvZ5EFNSY/4hoIGMOpIslE0KIQHeCiIiIiIiIKBhxpJuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTUREREREROQnLLqJiIiIiIiI/IRFNxEREREREZGfsOgmIiIiIiIi8hMW3URERERERER+wqKbiIiIiIiIyE9YdBMRERERERH5CYtuIiIiIiIiIj9h0U1ERERERETkJyy6iYiIiIiIiPyERTcRERERERGRn7DoJiIiIiIiIvITFt1EREREREREfsKimwastWvXQiaTSYtSqURiYiJ++tOfoqioKNDdIyIiIiKiIKAMdAeIAm3NmjUYNWoUbDYbvv76a/zxj3/E1q1bcfToUURGRga6e0RERERE1I+x6KYBLzMzE5MmTQIAXH311XC73Vi6dCk++eQT3H333QHuHRERERER9Wc8vJyoFW8BXllZGeCeEBERERFRf8eim6iV4uJiAMCIESMC3BMiIiIiIurveHg5DXhutxsul0s6p/uZZ57BtGnTcMsttwS6a0RERERE1M+x6KYBb/LkyT73MzIy8K9//QtKJT8eRERERER0aXh4OQ147777Lr799lts2bIF999/PwoLC/Gzn/0s0N0iIiIiIqIgwKE8GvAyMjKkydOuueYauN1uvPnmm/jnP/+Jn/zkJwHuHRERERER9Wcc6SZq5fnnn0dkZCT+8Ic/wOPxBLo7RERERETUj7HoJmolMjISS5YsQWFhIT744INAd4eIiIiIiPoxFt1E7Xj44YcxePBgPP3003C73YHuDhERERER9VMyIYQIdCeIiIiIiIiIghFHuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRER+tmPHDtx8881ISkqCTCbDJ598csHnbN++HVlZWdBqtRg6dCj+/ve/t2nz0UcfYfTo0dBoNBg9ejQ2btzoh94TEV0a5kAiGuhYdBMR+ZnFYsH48eOxatWqLrUvLi7GjTfeiKuuugr5+fn47W9/i0ceeQQfffSR1GbPnj2YN28e5s+fjwMHDmD+/Pm4/fbbsW/fPn+FQUR0UZgDiWig4+zlRES9SCaTYePGjZg7d26HbX7zm9/g008/RWFhobRu4cKFOHDgAPbs2QMAmDdvHsxmMz7//HOpzQ033IDIyEh8+OGHfus/EdGlYA4k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+/btIj09XfziF78IVAg+uhvPmjVrhFKpFKtXrxYnT54Uu3btEpMmTRJXXHFFoEJo40L/H/tbbugIcyBzYCAwB/btHBio/MeiuwteeeUVkZqaKtRqtZg4caJ0SaL+znvNYpVKJZKSksStt94qCgoKpMc9Ho9YunSpSEhIEBqNRkybNk0cOnQogD3unq1btwoAbZYFCxYIIboWn9VqFQ899JCIiooSISEhYvbs2eLs2bMBiObCOou3qalJzJw5U8TGxgqVSiUGDx4sFixY0CaW/hRve7ECEGvWrJHaBNt7fDE6y18LFiwQ06dP92m/bds2cdlllwm1Wi2GDBkiXn311V7ucee6E8/06dM7zQF9RXffo5b64hdOIbofU2FhoZgxY4YICQkRycnJYvHixT470AKtu/G89NJLYvTo0SIkJEQkJiaKO++8U5SWlvZyrzt2of+P/TE3dIQ5kDkwEJgD+24ODFT+kwnRD8f5iYiIiIiIiPoBntNNRERERERE5CcsuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRERERERERH7CopuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTQPKsmXLMGHChEB3g4iIiIiIBgiZEEIEuhNEPUEmk3X6+IIFC7Bq1SrY7XZER0f3Uq+IiIiIiGggY9FNQaOiokL6ecOGDfjDH/6AY8eOSetCQkJgMBgC0TUiIiIiIhqgeHg5BY2EhARpMRgMkMlkbda1Prz8rrvuwty5c/Hss88iPj4eERERWL58OVwuF379618jKioKycnJePvtt31eq6ysDPPmzUNkZCSio6MxZ84cnD59uncDJiIiIiKiPo9FNw14W7Zswblz57Bjxw6sXLkSy5Ytw+zZsxEZGYl9+/Zh4cKFWLhwIUpKSgAATU1NuOaaaxAWFoYdO3Zg165dCAsLww033ACHwxHgaIiIiIiIqC9h0U0DXlRUFF566SWMHDkS99xzD0aOHImmpib89re/RXp6OpYsWQK1Wo2vv/4aALB+/XrI5XK8+eabGDt2LDIyMrBmzRqcPXsW27ZtC2wwRERERETUpygD3QGiQBszZgzk8h/2P8XHxyMzM1O6r1AoEB0dDaPRCADIy8vDiRMnoNfrfbZjs9lw8uTJ3uk0ERERERH1Cyy6acBTqVQ+92UyWbvrPB4PAMDj8SArKwvr1q1rs63Y2Fj/dZSIiIiIiPodFt1E3TRx4kRs2LABcXFxCA8PD3R3iIiIiIioD+M53UTddOeddyImJgZz5szBzp07UVxcjO3bt+PRRx9FaWlpoLtHRERERER9CItuom7S6XTYsWMHBg8ejFtvvRUZGRm45557YLVaOfJNREREREQ+ZEIIEehOEBEREREREQUjjnQTERERERER+QmLbiIiIiIiIiI/YdFNRERERERE5CcsuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRERERERERH7CopuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTUREREREROQnLLqJiIiIiIiI/OT/A0Evmh/XOHQYAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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u+OT97gVdM+bNw/x8fEICQlBYmIitm3b1mD9LVu2IDExESEhIejcuTMWLFjgVmP1avt2YNEisRwaKl6skuc984ycefjhB+D228X1hkldPN7NKykJWLBAnjCqshL47DMxO52ZKQbNkrg44PnnxS7kjz1Wv+utn5+4TOILLwBr1gDDhsm/y88XL4YGDRKDcwbf5uPq94QenTsnnlsA4Npr5RtSWujZU97/xo3yjOpEEjXOzZmZmejRoweCg4PRo0cPrF27tsn7VUt1NTBhgtyTavRooEULTZpiCNJcLoA4P9K5c9q1xVe5HHSvXr0a06ZNw8yZM5Gbm4uBAwdi2LBhKKjbL/E3x48fx/DhwzFw4EDk5ubi2WefxZNPPonMzMwmN14Ptm8HRo6ULyInTABattSyRebVogWQkSGvnfr998D11wNvvCFmv8nzeLybX+/ewOrV4oSFrVvb/i40VFxB4J13gH//W5xfITCw8fe85hqxe/nSpeIxKtm2DUhJEZcue+MNcZkXBuDG5+r3hF7997/y36NymR0tBAXJsw4XFQFffqlte0hf1Dg379y5E6NGjcKYMWPw3XffYcyYMXjggQfw7bffur1ftVy4ADz0kNhDCxCHdSqDSqqvXz95ZveffxZjF+WNdVKfRRBcu+Tp168fbrzxRsyfP9+6rXv37hg5ciTS7Sz6+re//Q3r169HvmImkEmTJuG7777Dzp07ndpneXk5IiIisGRJGZo3D3eluU0mCOKjpka8m3b5svhHeuSIuN7dL7/Iddu0Ad57T8z4kHpOngSefrr+9muuETN3nTuLmbvwcHFW5cBAsaugn584K6zFom77Ll8uxyOPRKCsrAzh4d79e/U0LY93oAwffBDOm1heJAjiybisTDx+OnRo+veZIABffy33BrKnc2dxDGvHjmL39ZYtxVnRg4PtH79qH8OuMNPx7i5Xvyfq0vocX1MDlJQATz0lb09L035uli1bgHnz5Ocvvyz29goM1Ncx4Gv0cMyrcW4eNWoUysvL8YU0QRGAu+66C61atcLK32bfauqxDjh/vAuCOGyzpkac6LO8HDh9Gti7Vw62Jc8+Kw5jooYVFdl+zwFir9GbbwbatwfCwsQbfv7++jvXasWTx3uAK5UrKyuRk5ODZ555xmZ7SkoKduzYYfc1O3fuREpKis22oUOHYvHixaiqqkKg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1KpVK7Rp0wYLFy7EkSNH8M033yA1NbXR182ePRtff/01fvjhB4wfPx5t27Z1aR3P6667Dh9//DHy8/Px7bff4uGHH0azZs2a8C8hIgAICwvDuHHj8H//93/YvHkzDhw4gEcffRR+fn6wWCy6Owdfd9112Lt3LzZu3IiffvoJzz//PPbs2aNZe4iIjIZBt0mMHTsWV65cwc0334wpU6bgiSeewJ///GcAwJIlSzB27Fj89a9/RUJCAn7/+9/j22+/td49HzBgACZNmoRRo0ahXbt2eP3119GuXTssXboU//73v9GjRw+8+uqrmDNnjpb/RCKf5efnh1WrViEnJwe9evXC9OnT8cYbbzT6uldffRVPPfUUEhMTUVhYiPXr1yMoKMjp/X744Yc4d+4c+vbtizFjxuDJJ59EZGRkU/4pRPSbt956C8nJybjnnntwxx134JZbbkH37t0REhKiu3PwpEmT8Ic//AGjRo1Cv379UFpaapP1JiKihlkE5QA+IiIyvOzsbNx+++04d+4cWrZsqXVziMgJly5dwjXXXIM333wTEyZM0Lo5RETkQRzTTURERORlubm5+PHHH3HzzTejrKwMs2fPBgDce++9GreMiIg8jUE3ERERkQbmzJmDQ4cOISgoCImJidi2bRvatm2rdbOIiMjD2L2ciIiIiIiISCWcSI2IiIiIiIhIJQy6iYiIiIiIiFTCoJuIiIiIiIhIJQy6iYiI/n/7dSwAAAAAMMjfehT7yiIAgIl0AwAAwES6AQAAYCLdAAAAMJFuAAAAmASLllb1Q8WH4wAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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ePBg3HrrrcjIyMA999wDq9XKvZ5EFNSY/4hoIGMOpIslE0KIQHeCiIiIiIiIKBhxpJuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTUREREREROQnLLqJiIiIiIiI/IRFNxEREREREZGfsOgmIiIiIiIi8hMW3URERERERER+wqKbiIiIiIiIyE9YdBMRERERERH5CYtuIiIiIiIiIj9h0U1ERERERETkJyy6iYiIiIiIiPyERTcRERERERGRn7DoJiIiIiIiIvITFt1EREREREREfsKimwastWvXQiaTSYtSqURiYiJ++tOfoqioKNDdIyIiIiKiIKAMdAeIAm3NmjUYNWoUbDYbvv76a/zxj3/E1q1bcfToUURGRga6e0RERERE1I+x6KYBLzMzE5MmTQIAXH311XC73Vi6dCk++eQT3H333QHuHRERERER9Wc8vJyoFW8BXllZGeCeEBERERFRf8eim6iV4uJiAMCIESMC3BMiIiIiIurveHg5DXhutxsul0s6p/uZZ57BtGnTcMsttwS6a0RERERE1M+x6KYBb/LkyT73MzIy8K9//QtKJT8eRERERER0aXh4OQ147777Lr799lts2bIF999/PwoLC/Gzn/0s0N0iIiIiIqIgwKE8GvAyMjKkydOuueYauN1uvPnmm/jnP/+Jn/zkJwHuHRERERER9Wcc6SZq5fnnn0dkZCT+8Ic/wOPxBLo7RERERETUj7HoJmolMjISS5YsQWFhIT744INAd4eIiIiIiPoxFt1E7Xj44YcxePBgPP3003C73YHuDhERERER9VMyIYQIdCeIiIiIiIiIghFHuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRER+tmPHDtx8881ISkqCTCbDJ598csHnbN++HVlZWdBqtRg6dCj+/ve/t2nz0UcfYfTo0dBoNBg9ejQ2btzoh94TEV0a5kAiGuhYdBMR+ZnFYsH48eOxatWqLrUvLi7GjTfeiKuuugr5+fn47W9/i0ceeQQfffSR1GbPnj2YN28e5s+fjwMHDmD+/Pm4/fbbsW/fPn+FQUR0UZgDiWig4+zlRES9SCaTYePGjZg7d26HbX7zm9/g008/RWFhobRu4cKFOHDgAPbs2QMAmDdvHsxmMz7//HOpzQ033IDIyEh8+OGHfus/EdGlYA4k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+/btIj09XfziF78IVAg+uhvPmjVrhFKpFKtXrxYnT54Uu3btEpMmTRJXXHFFoEJo40L/H/tbbugIcyBzYCAwB/btHBio/MeiuwteeeUVkZqaKtRqtZg4caJ0SaL+znvNYpVKJZKSksStt94qCgoKpMc9Ho9YunSpSEhIEBqNRkybNk0cOnQogD3unq1btwoAbZYFCxYIIboWn9VqFQ899JCIiooSISEhYvbs2eLs2bMBiObCOou3qalJzJw5U8TGxgqVSiUGDx4sFixY0CaW/hRve7ECEGvWrJHaBNt7fDE6y18LFiwQ06dP92m/bds2cdlllwm1Wi2GDBkiXn311V7ucee6E8/06dM7zQF9RXffo5b64hdOIbofU2FhoZgxY4YICQkRycnJYvHixT470AKtu/G89NJLYvTo0SIkJEQkJiaKO++8U5SWlvZyrzt2of+P/TE3dIQ5kDkwEJgD+24ODFT+kwnRD8f5iYiIiIiIiPoBntNNRERERERE5CcsuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRERERERERH7CopuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTQPKsmXLMGHChEB3g4iIiIiIBgiZEEIEuhNEPUEmk3X6+IIFC7Bq1SrY7XZER0f3Uq+IiIiIiGggY9FNQaOiokL6ecOGDfjDH/6AY8eOSetCQkJgMBgC0TUiIiIiIhqgeHg5BY2EhARpMRgMkMlkbda1Prz8rrvuwty5c/Hss88iPj4eERERWL58OVwuF379618jKioKycnJePvtt31eq6ysDPPmzUNkZCSio6MxZ84cnD59uncDJiIiIiKiPo9FNw14W7Zswblz57Bjxw6sXLkSy5Ytw+zZsxEZGYl9+/Zh4cKFWLhwIUpKSgAATU1NuOaaaxAWFoYdO3Zg165dCAsLww033ACHwxHgaIiIiIiIqC9h0U0DXlRUFF566SWMHDkS99xzD0aOHImmpib89re/RXp6OpYsWQK1Wo2vv/4aALB+/XrI5XK8+eabGDt2LDIyMrBmzRqcPXsW27ZtC2wwRERERETUpygD3QGiQBszZgzk8h/2P8XHxyMzM1O6r1AoEB0dDaPRCADIy8vDiRMnoNfrfbZjs9lw8uTJ3uk0ERERERH1Cyy6acBTqVQ+92UyWbvrPB4PAMDj8SArKwvr1q1rs63Y2Fj/dZSIiIiIiPodFt1E3TRx4kRs2LABcXFxCA8PD3R3iIiIiIioD+M53UTddOeddyImJgZz5szBzp07UVxcjO3bt+PRRx9FaWlpoLtHRERERER9CItuom7S6XTYsWMHBg8ejFtvvRUZGRm45557YLVaOfJNREREREQ+ZEIIEehOEBEREREREQUjjnQTERERERER+QmLbiIiIiIiIiI/YdFNRERERERE5CcsuomIiIiIiIj8hEU3ERERERERkZ+w6CYiIiIiIiLyExbdRERERERERH7CopuIiIiIiIjIT1h0ExEREREREfkJi24iIiIiIiIiP2HRTUREREREROQnLLqJiIiIiIiI/OT/A0Evmh/XOHQYAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "abcSEIR3.get_posterior_sample(N=250, tol=np.inf, G=8, q=0.25, progress=True)\n", "\n", @@ -628,21 +439,10 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "id": "b22e6715", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "beta=0.439 (0.318, 0.673)\n", - "alpha=0.281 (0.129, 0.922)\n", - "gamma=0.295 (0.237, 0.375)\n", - "I0=6.472 (3.714, 9.692)\n" - ] - } - ], + "outputs": [], "source": [ "print(f'beta={np.median(abcSEIR3.res[:,0]):.3f} ({np.quantile(abcSEIR3.res[:,0], 0.025):.3f}, {np.quantile(abcSEIR3.res[:,0], 0.975):.3f})')\n", "print(f'alpha={np.median(abcSEIR3.res[:,1]):.3f} ({np.quantile(abcSEIR3.res[:,1], 0.025):.3f}, {np.quantile(abcSEIR3.res[:,1], 0.975):.3f})')\n", diff --git a/docs/notebooks/paramfit/params_via_optimization.ipynb b/docs/notebooks/paramfit/params_via_optimization.ipynb index c73c3d9a..ef6745cc 100644 --- a/docs/notebooks/paramfit/params_via_optimization.ipynb +++ b/docs/notebooks/paramfit/params_via_optimization.ipynb @@ -6,8 +6,8 @@ "source": [ "# Parameter Estimation: Maximum likelihood\n", "\n", - "In the previous section, we've seen how to use Markov Chain Monte Carlo methods to estimate the posterior probability distribution of parameters.\n", - "These methods have generally replaced techniques which use algorithms to infer the maximum likelihood estimates (MLE) of parameter values, with confidence levels provided after making assumptions about the local likelihood landscape.\n", + "In the previous section, we outlined how to use Markov Chain Monte Carlo methods to estimate the posterior probability distribution of parameters.\n", + "These methods have generally replaced techniques which infer the maximum likelihood estimates (MLE) of parameter values, with confidence levels provided after making assumptions about the local likelihood landscape.\n", "PyGOM has the capability to estimate parameters in this way and although perhaps outdated, including these methods could still be practical if trying to reproduce work from older publications, for example.\n", "\n", "## Example: SEIR model (with I and R known)\n", @@ -41,22 +41,26 @@ "source": [ "The syntax for setting up the solver is similar to the approach via ABC.\n", "We first form our candidate SEIR model.\n", - "Again, we must specify some values for $\\beta$, $\\alpha$ and $\\gamma$, even if we don't know them.\n", - "Here we put zeros, but anything else would be acceptable." + "Currently, PyGOM requires us to provide numerical values for all model parameters, including the unknown ones we are trying to estimate.\n", + "These values are used to perform an additional prior check to verify that the function provided is integrable.\n", + "This step will be likely removed for later versions, but for now it's probably best to input initial guesses as parameter values.\n", + "For the current example, this means specifying $\\beta$, $\\alpha$ and $\\gamma$ from our initial guess `theta`." ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "id": "857371e4", "metadata": {}, "outputs": [], "source": [ "from pygom import common_models\n", "\n", - "n_pop=1e4\n", - "paramEval=[('beta', 0), ('alpha', 0), ('gamma', 0), ('N', n_pop)]\n", - "ode_SEIR = common_models.SEIR_N_stochastic(param=paramEval)" + "n_pop=1e4 # known population size\n", + "theta = [0.4, 0.3, 0.3] # initial guess for [beta, alpha, gamma]\n", + "\n", + "paramEval=[('beta', theta[0]), ('alpha', theta[1]), ('gamma', theta[2]), ('N', n_pop)]\n", + "ode_SEIR = common_models.SEIR_N(param=paramEval)" ] }, { @@ -64,18 +68,16 @@ "id": "80c83797", "metadata": {}, "source": [ - "We provide an initial guess in `theta` and pass all other required information, including initial conditions `x0`, to build an object of class {class}`PoissonLoss`" + "We pass all other required information, including initial conditions, `x0`, to build an object of class {class}`.PoissonLoss`" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "id": "88ad9325", "metadata": {}, "outputs": [], "source": [ - "theta = [0.4, 0.3, 0.3] # initial guess\n", - "\n", "i0=5\n", "x0=[n_pop-i0, 0, i0, 0] # initial conditions\n", "\n", @@ -171,7 +173,7 @@ "Note that the interpolation is currently performed using a univariate spline, due to the limitation of Python packages.\n", "Ideally, one would prefer to use an (adaptive) Hermite or Chebyshev interpolation.\n", "\n", - "#TODO refs\n", + "#TODO refs or just leave this out?\n", "```" ] }, @@ -188,7 +190,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "ff093f77", "metadata": {}, "outputs": [], @@ -209,26 +211,10 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "83eca0ba", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " message: Optimization terminated successfully\n", - " success: True\n", - " status: 0\n", - " fun: 1651.128217170814\n", - " x: [ 3.537e-01 5.384e-01 2.559e-01]\n", - " nit: 17\n", - " jac: [-4.531e+00 -3.594e-01 4.575e+00]\n", - " nfev: 29\n", - " njev: 17\n" - ] - } - ], + "outputs": [], "source": [ "from scipy.optimize import minimize\n", "\n", @@ -251,25 +237,14 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "c826a9db", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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Eh4eLr/++qvRU5vTa6+9JpGRkdLY2Ch9fX2Bx8jIiIiI+Hw+2bdvn1y4cEG8Xq80NDRIZmam3HfffXLjxg2DZ6+3b98+aWxslCtXrsjFixclLy9PIiIiAj04cuSIREZGSm1trbS3t8vzzz8vcXFxytUxaXx8XNatWyf79+/XjZuhJz6fT9ra2qStrU0AyNGjR6WtrS3w7a/B9KKkpETi4+Olvr5eWltbJTs7W1JTU+X27dvK1OL3+yU/P1/i4+Pl+++/1x1Do6OjIiLyyy+/yNtvvy3Nzc3i9Xqlrq5ONmzYIA8++KBStQS7X5mhL5OGh4dl9erV8uGHH057vUp9me88LGKuY8aqzJjzVsp4Eea8Kn1hxjPjjaxlEjN+cXuz4hfzIiIffPCBJCQkiMPhkLS0NN2tX1QFYMbHyZMnRURkZGREcnJy5N577xW73S7r1q2ToqIi6enpMXbiMygoKJC4uDix2+3idrtl27Zt0tHREXh+YmJCKisrxeVyidPplE2bNkl7e7uBM57b119/LQCks7NTN26GnjQ0NMy4XxUVFYlIcL3466+/pLS0VKKioiQsLEzy8vIMqXGuWrxe76zHUENDg4iI9PT0yKZNmyQqKkocDockJSXJ66+/LoODg0rVEux+ZYa+TDpx4oSEhYXJ0NDQtNer1Jf5zsMi5jpmrMxsOW+ljBdhzqvSF2Y8M97IWiYx4xe3N9p/J0tEREREREREJrGi/888ERERERERkRlxMU9ERERERERkMlzMExEREREREZkMF/NEREREREREJsPFPBEREREREZHJcDFPREREREREZDJczBMRERERERGZDBfzRERERERERCbDxTwRERERERGRyXAxT0RERERERGQyXMwTERERERERmcx/ANqx/JRc1uIQAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "pars=res.x\n", "\n", - "ode_est = common_models.SEIR_N_stochastic([('beta', pars[0]), ('alpha', pars[1]), ('gamma', pars[2]), ('N', n_pop)])\n", + "ode_est = common_models.SEIR_N([('beta', pars[0]), ('alpha', pars[1]), ('gamma', pars[2]), ('N', n_pop)])\n", "ode_est.initial_values = (x0, t[0])\n", "solution = ode_est.integrate(t[1::])\n", "\n", @@ -294,15 +269,14 @@ "For parameter estimates found via optimisation, we need to make some assumptions about the shape of the likelihood function in the neighbourhood of the MLE to obtain confidence levels.\n", "\n", "```{warning}\n", - "PyGOM has built in functions using different methods to solve this problem.\n", - "These are, however, under development.\n", + "PyGOM has built in functions using different methods to solve this problem; these are, however, under development.\n", "The location and names of the relevant code can be found below and they should be carefully inspected before being employed.\n", "```" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "1ab2d9b6", "metadata": {}, "outputs": [], diff --git a/docs/notebooks/unroll/unrollSimple.ipynb b/docs/notebooks/unroll/unrollSimple.ipynb index 771c0889..dfba25ce 100644 --- a/docs/notebooks/unroll/unrollSimple.ipynb +++ b/docs/notebooks/unroll/unrollSimple.ipynb @@ -6,15 +6,14 @@ "source": [ "# Deducing transitions from equations\n", "\n", - "Deducing rate of change equations from transitions is as simple as adding up all the different flows in and out of each state.\n", - "For the more difficult reverse problem, PyGOM is able to attempt to distinguish the implied flows between compartments given a set of equations.\n", - "It may be that multiple underlying flow configurations can separately explain a given ODE system, so this functionality should be used with caution.\n", - "Here we demonstrate how this works in practice for two potentially tricky problems.\n", - "The first of which is a system where the total population count is not conserved and the second is a system where a flow out of some of the compartments is split.\n", + "Deducing ODEs from transitions is as simple as adding up all the different flows in and out of each state.\n", + "In this process, information is lost regarding the nature (origin and destination) of the constituent transitions and so the reverse problem, deducing transitions from ODEs, is more difficult.\n", + "PyGOM includes some tools to attempt to distinguish the implied flows between compartments given a set of equations, but given that multiple underlying flow configurations can separately explain an ODE system, this functionality should be used with caution.\n", + "Here we demonstrate how this works in practice for two potentially tricky problems, the first of which is a system where the total population count is not conserved and the second is a system where a flow out of some of the compartments is split between multiple destinations.\n", "\n", "## SIR with births and deaths\n", "\n", - "Let's consider the SIR model with standard incidence mixing and births and deaths proportional to the total population count.\n", + "For our first example, let's consider the SIR model with standard incidence mixing and births and deaths proportional to the total population count, but not necessarily balanced:\n", "\n", "$$\\begin{aligned}\n", "\\frac{\\mathrm{d} S}{\\mathrm{d} t} &= -\\frac{\\beta SI}{N} + B N - \\mu S \\\\\n", @@ -23,17 +22,16 @@ "\\frac{\\mathrm{d} N}{\\mathrm{d} t} &= (B-\\mu)N\n", "\\end{aligned}$$\n", "\n", - "Given that the force of infection, $\\frac{\\beta SI}{N}$, depends on N(t) it is necessary to keep a track of its time development in the final equation. \n", - "\n", - "Here we encounter an issue when thinking in terms of compartments.\n", + "Given that the force of infection, $\\frac{\\beta SI}{N}$, depends on the total population, it is necessary to keep track of $N(t)$ in the final equation. \n", + "Here we encounter an issue when thinking in terms of compartments:\n", "The total number of living individuals, $N$, is not a distinct category, rather, $S$, $I$ and $R$ are a subset of it.\n", "Thus, whilst valid to define a system of ODEs as we have done above, PyGOM will run into difficulties as it will interpret $N$ as a compartment.\n", - "One solution could be to define $N$ as a time dependent parameter, however PyGOM does not have this functionality.\n", + "One solution could be to define $N$ as a time dependent parameter, however PyGOM does not currently have this functionality.\n", "\n", - "Instead, we must be careful to ensure that we only pass state equations to PyGOM's transition calculating function, {func}`get_unrolled_obj()`.\n", + "Instead, we must be careful to ensure that we only pass state equations to PyGOM's transition calculating function, {func}`.get_unrolled_obj()`.\n", "The implication for the current example is that we eliminate the final equation and substitute $N=S+I+R$ everywhere else.\n", "\n", - "Let's set up the {class}`.SimulateOde` object as usual." + "Let's set up the {class}`.SimulateOde` object as usual:" ] }, { @@ -62,7 +60,7 @@ "id": "d712e654", "metadata": {}, "source": [ - "If we now inspect the transition matrix" + "If we now inspect the transition matrix:" ] }, { @@ -100,7 +98,7 @@ "id": "5e3c78c4", "metadata": {}, "source": [ - "and can verify that the calculated transition matrix now matches what we would expect." + "and can verify that the calculated transition matrix now matches what we would expect:" ] }, { @@ -187,7 +185,7 @@ "id": "690b0785", "metadata": {}, "source": [ - "Inspecting the transition graph" + "Deducing the transitions and inspecting the resulting transition graph:" ] }, { @@ -207,8 +205,8 @@ "metadata": {}, "source": [ "we notice that the **L** outflow has been captured, but the outflow from **I** is assumed to be a full death process of which a fraction are born into the recovered state.\n", - "The appearance of multiple consistent configurations demonstrates the difficulty in performing such reverse engineering.\n", - "One work-around is if we explicitly introduce a dead state" + "This appearance of an incorrect, but still consistent, configuration demonstrates the difficulty in performing such reverse engineering.\n", + "One work-around is if we explicitly introduce a dead state, $D$:" ] }, { From abd4c12a8a01530213ddf5928a2c24b35f6a3034 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Fri, 21 Jun 2024 16:10:43 +0100 Subject: [PATCH 032/123] Other file to get rid of DeterministicOde from common models --- pygom/model/common_models.py | 165 ++++++++++++++++++----------------- 1 file changed, 84 insertions(+), 81 deletions(-) diff --git a/pygom/model/common_models.py b/pygom/model/common_models.py index 13e1ed98..add15970 100644 --- a/pygom/model/common_models.py +++ b/pygom/model/common_models.py @@ -8,13 +8,13 @@ from collections import OrderedDict from .transition import TransitionType, Transition -from .deterministic import DeterministicOde +#from .deterministic import DeterministicOde from .simulate import SimulateOde def SIS(param=None): """ - A standard SIS model + Susceptible Infected Susceptible model .. math:: \\frac{dS}{dt} &= -\\beta SI + \\gamma I \\\\ @@ -25,7 +25,7 @@ def SIS(param=None): >>> import numpy as np >>> from pygom import common_models >>> ode = common_models.SIS({'beta':0.5, 'gamma':0.2}) - >>> t = np.linspace(0, 20, 101) + >>> t = np.linspace(0, 20, 100) >>> x0 = [1.0, 0.1] >>> ode.initial_values = (x0, t[0]) >>> solution = ode.integrate(t[1::]) @@ -35,15 +35,13 @@ def SIS(param=None): state = ['S', 'I'] param_list = ['beta', 'gamma'] transition = [ - Transition(origin='S', destination='I', equation='beta*S*I', - transition_type=TransitionType.T), - Transition(origin='I', destination='S', equation='gamma*I', - transition_type=TransitionType.T) + Transition(origin='S', destination='I', equation='beta*S*I',transition_type=TransitionType.T), + Transition(origin='I', destination='S', equation='gamma*I',transition_type=TransitionType.T) ] # initialize the model - ode = DeterministicOde(state, - param_list, - transition=transition) + ode = SimulateOde(state, + param_list, + transition=transition) # set return, depending on whether we have input the parameters if param is None: @@ -91,7 +89,7 @@ def SIS_Periodic(param=None): transition_type=TransitionType.ODE) ] # initialize the model - ode_obj = DeterministicOde(state, param_list, + ode_obj = SimulateOde(state, param_list, derived_param=derived_param, ode=ode) @@ -150,7 +148,7 @@ def SIR(param=None): transition_type=TransitionType.T) ] # initialize the model - ode_obj = DeterministicOde(state, param_list, transition=transition) + ode_obj = SimulateOde(state, param_list, transition=transition) # set return, depending on whether we have input the parameters if param is None: @@ -160,10 +158,15 @@ def SIR(param=None): return ode_obj -def SIR_N_stochastic(param=None, init=None): +def SIR_N(param=None, init=None): """ A standard SIR model [Brauer2008]_ with population N + .. math:: + \\frac{dS}{dt} &= -\\beta SI/N \\\\ + \\frac{dI}{dt} &= \\beta SI/N- \\gamma I \\\\ + \\frac{dR}{dt} &= \\gamma I + """ stateList = ['S', 'I', 'R'] paramList = ['beta', 'gamma', 'N'] @@ -184,7 +187,7 @@ def SIR_N_stochastic(param=None, init=None): return ode_obj -def SEIR_N_stochastic(param=None, init=None): +def SEIR_N(param=None, init=None): """ A standard SIR model [Brauer2008]_ with population N @@ -207,60 +210,60 @@ def SEIR_N_stochastic(param=None, init=None): return ode_obj -def SIR_N(param=None): - """ - A standard SIR model [Brauer2008]_ with population N. This is the unnormalized - version of the SIR model. - - .. math:: - \\frac{dS}{dt} &= -\\beta SI/N \\\\ - \\frac{dI}{dt} &= \\beta SI/N- \\gamma I \\\\ - \\frac{dR}{dt} &= \\gamma I - - Examples - -------- - The model that produced top two graph in Figure 1.3 of the reference above. - First, when everyone is susceptible and only one individual was infected. - - >>> import numpy as np - >>> from pygom import common_models - >>> ode = common_models.SIR({'beta':3.6, 'gamma':0.2}) - >>> t = np.linspace(0, 730, 1001) - >>> N = 7781984.0 - >>> x0 = [N, 1.0, 0.0] - >>> ode.initial_values = (x0, t[0]) - >>> solution = ode.integrate(t[1::]) - >>> ode.plot() - - Second model with a more *realistic* scenario - - >>> import numpy as np - >>> from pygom import common_models - >>> ode = common_models.SIR({'beta':3.6, 'gamma':0.2}) - >>> t = np.linspace(0, 730, 1001) - >>> N = 7781984.0 - >>> x0 = [int(0.065*N), 21.0, 0.0] - >>> ode.initial_values = (x0, t[0]) - >>> solution = ode.integrate(t[1::]) - >>> ode.plot() - """ - state = ['S', 'I', 'R'] - param_list = ['beta', 'gamma', 'N'] - transition = [ - Transition(origin='S', destination='I', equation='beta*S*I/N', - transition_type=TransitionType.T), - Transition(origin='I', destination='R', equation='gamma*I', - transition_type=TransitionType.T) - ] - # initialize the model - ode_obj = DeterministicOde(state, param_list, transition=transition) - - # set return, depending on whether we have input the parameters - if param is None: - return ode_obj - else: - ode_obj.parameters = param - return ode_obj +# def SIR_N(param=None): +# """ +# A standard SIR model [Brauer2008]_ with population N. This is the unnormalized +# version of the SIR model. + +# .. math:: +# \\frac{dS}{dt} &= -\\beta SI/N \\\\ +# \\frac{dI}{dt} &= \\beta SI/N- \\gamma I \\\\ +# \\frac{dR}{dt} &= \\gamma I + +# Examples +# -------- +# The model that produced top two graph in Figure 1.3 of the reference above. +# First, when everyone is susceptible and only one individual was infected. + +# >>> import numpy as np +# >>> from pygom import common_models +# >>> ode = common_models.SIR({'beta':3.6, 'gamma':0.2}) +# >>> t = np.linspace(0, 730, 1001) +# >>> N = 7781984.0 +# >>> x0 = [N, 1.0, 0.0] +# >>> ode.initial_values = (x0, t[0]) +# >>> solution = ode.integrate(t[1::]) +# >>> ode.plot() + +# Second model with a more *realistic* scenario + +# >>> import numpy as np +# >>> from pygom import common_models +# >>> ode = common_models.SIR({'beta':3.6, 'gamma':0.2}) +# >>> t = np.linspace(0, 730, 1001) +# >>> N = 7781984.0 +# >>> x0 = [int(0.065*N), 21.0, 0.0] +# >>> ode.initial_values = (x0, t[0]) +# >>> solution = ode.integrate(t[1::]) +# >>> ode.plot() +# """ +# state = ['S', 'I', 'R'] +# param_list = ['beta', 'gamma', 'N'] +# transition = [ +# Transition(origin='S', destination='I', equation='beta*S*I/N', +# transition_type=TransitionType.T), +# Transition(origin='I', destination='R', equation='gamma*I', +# transition_type=TransitionType.T) +# ] +# # initialize the model +# ode_obj = SimulateOde(state, param_list, transition=transition) + +# # set return, depending on whether we have input the parameters +# if param is None: +# return ode_obj +# else: +# ode_obj.parameters = param +# return ode_obj def SIR_Birth_Death(param=None): @@ -312,7 +315,7 @@ def SIR_Birth_Death(param=None): ] # initialize the model - ode_obj = DeterministicOde(state, param_list, + ode_obj = SimulateOde(state, param_list, birth_death=birth_death, transition=transition) @@ -363,7 +366,7 @@ def SEIR(param=None): transition_type=TransitionType.T) ] - ode_obj = DeterministicOde(state, param_list, transition=transition) + ode_obj = SimulateOde(state, param_list, transition=transition) if param is None: return ode_obj @@ -425,7 +428,7 @@ def SEIR_Birth_Death(param=None): transition_type=TransitionType.B) ] - ode_obj = DeterministicOde(state, param_list, + ode_obj = SimulateOde(state, param_list, transition=transition, birth_death=bd_list) @@ -492,7 +495,7 @@ def SEIR_Birth_Death_Periodic(param=None): transition_type=TransitionType.ODE) ] # initialize the model - ode_obj = DeterministicOde(state, param_list, + ode_obj = SimulateOde(state, param_list, derived_param=derived_param, ode=ode) @@ -598,7 +601,7 @@ def SEIR_Multiple(n=2, param=None): bd_list += [Transition(origin=states[v][i], equation='d*' + states[v][i], transition_type=TransitionType.D)] bd_list += [Transition(origin=states['S'][i], equation='d*' + N[i], transition_type=TransitionType.B)] - ode_obj = DeterministicOde(state_list, + ode_obj = SimulateOde(state_list, param_list, derived_param=derived_param, transition=transition, @@ -639,7 +642,7 @@ def Influenza_SLIARN(param=None): transition_type=TransitionType.ODE) ] # initialize the model - ode_obj = DeterministicOde(state, param_list, ode=ode) + ode_obj = SimulateOde(state, param_list, ode=ode) if param is None: return ode_obj @@ -704,7 +707,7 @@ def Legrand_Ebola_SEIHFR(param=None): ] # alternatively, we can do it on the operate ode model - ode_obj = DeterministicOde(state, params) + ode_obj = SimulateOde(state, params) # add the derived parameter ode_obj.derived_param_list = derived_param @@ -789,7 +792,7 @@ def Lotka_Volterra(param=None): transition_type=TransitionType.ODE) ] - ode_obj = DeterministicOde(state, param_list, ode=ode) + ode_obj = SimulateOde(state, param_list, ode=ode) # set return, depending on whether we have input the parameters if param is None: return ode_obj @@ -840,7 +843,7 @@ def Lotka_Volterra_4State(param=None): transition_type=TransitionType.T) ] - ode_obj = DeterministicOde(state, param_list, transition=transition) + ode_obj = SimulateOde(state, param_list, transition=transition) # set return, depending on whether we have input the parameters if param is None: @@ -883,7 +886,7 @@ def FitzHugh(param=None): transition_type=TransitionType.ODE) ] # setup our ode - ode_obj = DeterministicOde(state, param_list, + ode_obj = SimulateOde(state, param_list, derived_param=None, transition=None, birth_death=None, @@ -931,7 +934,7 @@ def Lorenz(param=None): transition_type=TransitionType.ODE) ] # initialize the model - ode_obj = DeterministicOde(state, param_list, ode=ode) + ode_obj = SimulateOde(state, param_list, ode=ode) if param is None: return ode_obj @@ -981,7 +984,7 @@ def vanDelPol(param=None): transition_type=TransitionType.ODE) ] # initialize the model - ode_obj = DeterministicOde(state_list, param_list, ode=ode) + ode_obj = SimulateOde(state_list, param_list, ode=ode) if param is None: return ode_obj @@ -1028,7 +1031,7 @@ def Robertson(param=None): transition_type=TransitionType.T) ] # initialize the model - ode_obj = DeterministicOde(state, param_list, transition=transition) + ode_obj = SimulateOde(state, param_list, transition=transition) if param is None: return ode_obj From b97d589e2452727fdecdc4d2bee590f2fea9d01d Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Fri, 21 Jun 2024 16:15:10 +0100 Subject: [PATCH 033/123] Define function to avoid DRY violation --- pygom/model/base_ode_model.py | 38 +++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/pygom/model/base_ode_model.py b/pygom/model/base_ode_model.py index 92ca513a..e58a373e 100644 --- a/pygom/model/base_ode_model.py +++ b/pygom/model/base_ode_model.py @@ -61,14 +61,13 @@ def __init__(self, """ Constructor """ - # the 3 required input when doing evaluation + # the 3 required inputs when doing evaluation self._state = None self._param = None self._time = None - # we always need time to be a symbol... and it should be denoted as t + # we always need time to be a symbol and it should be denoted as t self._t = symbols('t') - # self._isDifficult = False # allows the system to be defined directly self._ode = None @@ -114,17 +113,8 @@ def __init__(self, self._vMat = None self._GMat = None - if state is not None: - if isinstance(state, str): - state = re_split_string.split(state) - state = filter(lambda x: not len(x.strip()) == 0, state) - self.state_list = list(state) - - if param is not None: - if isinstance(param, str): - param = re_split_string.split(param) - param = filter(lambda x: not len(x.strip()) == 0, param) - self.param_list = list(param) + self._add_list_attr(state, "state_list") + self._add_list_attr(param, "param_list") # this has to go after adding the parameters # because it is suppose to be based on the current @@ -178,9 +168,22 @@ def _get_model_str(self): {str(k): v for k, v in self._parameters.items()} return model_str + def _add_list_attr(self, attr, attr_list_name): + """ + Given an attribute (name attr_name), which is a string of comma + or space separated values, create a new attribute (name attr_name_list) + which is a list of those separated values. + e.g. "a,b,c d ef" returns [a, b, c, d, ef] + """ + if attr is not None: + if isinstance(attr, str): + attr = re_split_string.split(attr) + attr = filter(lambda x: not len(x.strip()) == 0, attr) + self.__setattr__(attr_list_name, list(attr)) + ######################################################################## # - # Getting and setters + # Getters and setters # ######################################################################## @@ -223,6 +226,7 @@ def parameters(self, parameters): if isinstance(parameters, (list, tuple, np.ndarray)): # length checking, we are assuming here that we always set # the full set of parameters + # TODO: for model fitting, we might only want to set a subset of the known ones if len(parameters) == self.num_param: if isinstance(parameters, np.ndarray): if parameters.size == self.num_param: @@ -306,6 +310,7 @@ def parameters(self, parameters): elif self.num_param == 1: # a single parameter ode and you are not evaluating it # analytically! fair enough! no further comments your honour. + # TODO: Can't single parameter ODE's still be complicated? if isinstance(parameters, tuple): param_out[f(parameters[0])] = parameters[1] elif isinstance(parameters, (int, float)): @@ -1139,6 +1144,9 @@ def _extractParamIndex(self, input_str): raise InputError("Input parameter: %s does not exist" % input_str) def _extractParamSymbol(self, input_str): + """ + Given a parameter name, input_str + """ if isinstance(input_str, ODEVariable): input_str = input_str.ID From 2f0528281394ea2750ba33409cbeec42d5de9439 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Wed, 26 Jun 2024 15:53:48 +0100 Subject: [PATCH 034/123] Add a try-except for newer versions of scipy that have renamed the simps function --- pygom/loss/get_init.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pygom/loss/get_init.py b/pygom/loss/get_init.py index 78f81ed9..57f80b1d 100644 --- a/pygom/loss/get_init.py +++ b/pygom/loss/get_init.py @@ -2,7 +2,13 @@ import numpy as np from scipy.interpolate import UnivariateSpline -from scipy.integrate import simps + +# TODO: For newer <1.14.0 versions of scipy. Once established remove and leave only except part +try: + from scipy.integrate import simps +except ImportError: + from scipy.integrate import simpson as simps + from scipy.optimize import leastsq, minimize_scalar def get_init(y, t, ode, theta=None, full_output=False): From 7df31b04a18b2de91cb379f94e24b2075a65b3b6 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Mon, 8 Jul 2024 16:30:20 +0100 Subject: [PATCH 035/123] draft time dependent params section --- docs/notebooks/time_dependent_params.ipynb | 180 +++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 docs/notebooks/time_dependent_params.ipynb diff --git a/docs/notebooks/time_dependent_params.ipynb b/docs/notebooks/time_dependent_params.ipynb new file mode 100644 index 00000000..a71f52dd --- /dev/null +++ b/docs/notebooks/time_dependent_params.ipynb @@ -0,0 +1,180 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "aeef8af5", + "metadata": {}, + "source": [ + "# Time dependent parameters\n", + "\n", + "PyGOM may also be used with time dependent parameters.\n", + "Such situations commonly enter epidemic modelling if, for example, the rate of infection shows time dependence due to seasonal effects or interventions.\n", + "Let's consider an SIR model with periodic infectivity ($beta(t)$) and add in immune waning too (so we can witness multiple seasons):\n", + "\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d} S}{\\mathrm{d} t} &= -\\frac{\\beta(t) SI}{N} + w R \\\\\n", + "\\frac{\\mathrm{d} I}{\\mathrm{d} t} &= \\frac{\\beta(t) SI}{N}- \\gamma I \\\\\n", + "\\frac{\\mathrm{d} R}{\\mathrm{d} t} &= \\gamma I - w R \\\\\n", + "\\beta(t) &= \\beta_0 \\left(1+\\delta \\cos \\left(\\frac{2 \\pi t}{P} \\right) \\right)\n", + "\\end{aligned}$$\n", + "\n", + "where $\\beta_0$ is some baseline infection rate, $\\delta$ is the magnitude of oscillations from the baseline ($-1<\\delta<1$ so that $\\beta>0$), $P$ is the oscillation period and $w$ is the waning rate.\n", + "PyGOM cannot handle the time dependence explicitly, instead we must define a dummy variable, $\\tau$, to play the same role.\n", + "We thus append our set of equations with one extra:\n", + "\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d} \\tau}{\\mathrm{d} t} &= 1\n", + "\\end{aligned}$$\n", + "\n", + "This takes the place of an extra ``state'' in our system, so we need to treat it as such by:\n", + "\n", + "- Declaring it in our state list\n", + "- Including the equation above in our ode list\n", + "- Providing an initial condition (doesn't matter too much, but best set $\\tau_0=0$ if $t_0=0$)\n", + "\n", + "We must also provide the functional form of $\\beta$.\n", + "It might be easiest to do so by including it as a `derived parameter`." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "1679a48a", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import SimulateOde, Transition, TransitionType\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "# Define SIR model\n", + "stateList = ['S', 'I', 'R', 'tau'] # now we have added tau to the states\n", + "paramList = ['gamma', 'N', 'beta0', 'delta', 'period', 'w']\n", + "derived_param = [('beta', 'beta0*(1+delta*cos(2*3.14*tau/period))')] # beta (with tau instead of t)\n", + "\n", + "odeList=[Transition(origin='S', equation='-beta*S*I/N + w*R', transition_type=TransitionType.ODE),\n", + " Transition(origin='I', equation='beta*S*I/N - gamma*I', transition_type=TransitionType.ODE),\n", + " Transition(origin='R', equation='gamma*I - w*R', transition_type=TransitionType.ODE),\n", + " Transition(origin='tau', equation='1', transition_type=TransitionType.ODE)] # d(tau)/dt = 1\n", + "\n", + "# Set parameter values\n", + "gamma=0.25 # Recovery rate\n", + "n_pop=1e4 # Total population\n", + "beta0=0.3 # Baseline infectivity\n", + "period=365 # Period 1 year\n", + "delta=0.2 # beta varies between 0.8 and 1.2 times beta0\n", + "w=2/(365) # timescale of immune waning of order 0.5 year\n", + "\n", + "params=[('gamma', gamma),\n", + " ('N', n_pop),\n", + " ('beta0', beta0),\n", + " ('delta', delta),\n", + " ('period', period),\n", + " ('w', w)]\n", + "\n", + "# Initial conditions\n", + "i0=1\n", + "x0 = [n_pop-i0, i0, 0, 0] # We specify tau(0)=0\n", + "\n", + "# Time range and increments\n", + "tmax=10*365 # run for 10 years\n", + "dt=0.1 # timestep\n", + "n_timestep=int(tmax/dt) # number of iterations\n", + "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated\n", + "\n", + "# Set up pygom object\n", + "ode = SimulateOde(stateList,\n", + " paramList,\n", + " ode=odeList,\n", + " derived_param=derived_param)\n", + "\n", + "ode.initial_values = (x0, t[0]) # (initial state conditions, initial timepoint)\n", + "ode.parameters=params" + ] + }, + { + "cell_type": "markdown", + "id": "1dcdfcc4", + "metadata": {}, + "source": [ + "Solve and plot" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "a8057a58", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'tau')" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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EEIIIYSoZSTMCyGEEEIIIYQQtYyEeSGEEEIIIYQQopaRMC+EEEIIIYQQQtQyEubt6L333iM6OhofHx+6d+/Ob7/95uom1QozZ86kZ8+e6PV6wsLCuP322zl06JCrm1VrzZw5E41GQ2JioqubUmucPXuWe+65h5CQEPz8/OjSpQs7duxwdbNqjfLycl588UWio6Px9fWlRYsWvPLKK5jNZlc3zS2tW7eO0aNHExkZiUaj4bvvvqv0vKIoTJ8+ncjISHx9fRk8eDD79+93TWPrCbl+14xcv+1Lrt81I9fwmpPrd/W44/VbwrydLFmyhMTERKZNm8auXbsYMGAAI0eO5PTp065umttLTk5mwoQJbN68mVWrVlFeXk58fDwFBQWublqts23bNj744AM6derk6qbUGtnZ2fTr1w+dTsfy5cs5cOAAb7/9Ng0aNHB102qNf//73/z3v/9l7ty5HDx4kDfeeIM333yTOXPmuLppbqmgoIDOnTszd+7cqz7/xhtvMGvWLObOncu2bduIiIhg+PDh5OXlObml9YNcv2tOrt/2I9fvmpFruG3k+l09bnn9VoRd9OrVS3n00UcrPda2bVvlueeec1GLaq/MzEwFUJKTk13dlFolLy9PiYmJUVatWqUMGjRImTx5squbVCs8++yzSv/+/V3djFrtlltuUR588MFKj91xxx3KPffc46IW1R6AsnTpUvXfZrNZiYiIUP71r3+pjxUXFysGg0H573//64IW1n1y/bYfuX7XjFy/a06u4baR63fNucv1W3rm7aC0tJQdO3YQHx9f6fH4+Hg2btzoolbVXkajEYDg4GAXt6R2mTBhArfccgvDhg1zdVNqlR9++IEePXpw1113ERYWRteuXfnwww9d3axapX///vzyyy8cPnwYgN27d7N+/XpuvvlmF7es9jlx4gTp6emVrife3t4MGjRIricOINdv+5Lrd83I9bvm5BpuG7l+24+rrt+eDttzPXLhwgVMJhPh4eGVHg8PDyc9Pd1FraqdFEVhypQp9O/fn9jYWFc3p9ZYvHgxO3fuZNu2ba5uSq1z/Phx5s2bx5QpU3jhhRfYunUrTzzxBN7e3tx7772ubl6t8Oyzz2I0Gmnbti0eHh6YTCZef/11/vrXv7q6abWO9ZpxtevJqVOnXNGkOk2u3/Yj1++akeu3beQabhu5ftuPq67fEubtSKPRVPq3oihXPCaub+LEiezZs4f169e7uim1RmpqKpMnT2blypX4+Pi4ujm1jtlspkePHsyYMQOArl27sn//fubNmydfBKpoyZIlLFiwgEWLFtGhQwdSUlJITEwkMjKS++67z9XNq5XkeuJccr5tJ9fv6pPrt+3kGm4buX7bn7OvJxLm7SA0NBQPD48r7uJnZmZecXdGXNukSZP44YcfWLduHU2aNHF1c2qNHTt2kJmZSffu3dXHTCYT69atY+7cuZSUlODh4eHCFrq3Ro0a0b59+0qPtWvXjm+++cZFLap9nn76aZ577jnuvvtuADp27MipU6eYOXOmfBmopoiICMByh79Ro0bq43I9cQy5ftuHXL9rRq7ftpNruG3k+m0/rrp+y5x5O/Dy8qJ79+6sWrWq0uOrVq2ib9++LmpV7aEoChMnTuTbb79lzZo1REdHu7pJtcrQoUPZu3cvKSkp6k+PHj3429/+RkpKinwRuIF+/fpdsZTS4cOHadasmYtaVPsUFhai1Va+nHh4eMjSNjUQHR1NREREpetJaWkpycnJcj1xALl+20au37aR67ft5BpuG7l+24+rrt/SM28nU6ZMYdy4cfTo0YO4uDg++OADTp8+zaOPPurqprm9CRMmsGjRIr7//nv0er3aQ2IwGPD19XVx69yfXq+/Yn6iv78/ISEhMm+xCp588kn69u3LjBkzGDNmDFu3buWDDz7ggw8+cHXTao3Ro0fz+uuv07RpUzp06MCuXbuYNWsWDz74oKub5pby8/M5evSo+u8TJ06QkpJCcHAwTZs2JTExkRkzZhATE0NMTAwzZszAz8+PsWPHurDVdZdcv2tOrt+2keu37eQabhu5flePW16/HVYnvx76v//7P6VZs2aKl5eX0q1bN1mapYqAq/588sknrm5arSVL21TPsmXLlNjYWMXb21tp27at8sEHH7i6SbVKbm6uMnnyZKVp06aKj4+P0qJFC2XatGlKSUmJq5vmln799der/s277777FEWxLG/z8ssvKxEREYq3t7cycOBAZe/eva5tdB0n1++akeu3/cn1u/rkGl5zcv2uHne8fmsURVEcd6tACCGEEEIIIYQQ9iZz5oUQQgghhBBCiFpGwrwQQgghhBBCCFHLSJgXQgghhBBCCCFqGQnzQgghhBBCCCFELSNhXgghhBBCCCGEqGUkzAshhBBCCCGEELWMhHkhhBBCCCGEEKKWkTAvhBBCCCGEEELUMhLmhRBCCCGEEEKIWkbCvBBCCCGEEEIIUctImBdCCCGEEEIIIWqZ/wfP/JVjuqQqKwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "solution = ode.solve_determ(t[1::])\n", + "\n", + "f, axarr = plt.subplots(2,2, layout='constrained', figsize=(10, 4))\n", + "\n", + "axarr[0][0].plot(t/365, solution[:,0], color='C1')\n", + "axarr[0][1].plot(t/365, solution[:,1], color='C0')\n", + "axarr[1][0].plot(t/365, solution[:,2], color='C2')\n", + "axarr[1][1].plot(t/365, solution[:,3], color='C3')\n", + "axarr[0][0].set_title(\"S\")\n", + "axarr[0][1].set_title(\"I\")\n", + "axarr[1][0].set_title(\"R\")\n", + "axarr[1][1].set_title(\"tau\")" + ] + }, + { + "cell_type": "markdown", + "id": "dc691a8f", + "metadata": {}, + "source": [ + "TODO: Figure out how to do this for a step function." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From d0c8045b24da0dbc58f3170825616c43fbad2405 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 12 Jul 2024 15:08:27 +0100 Subject: [PATCH 036/123] Fix some minor warnings in doc building --- docs/bib/ref.bib | 3 ++- .../approximate_bayesian_computation.py | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/bib/ref.bib b/docs/bib/ref.bib index cf02a3ca..2f1df48a 100644 --- a/docs/bib/ref.bib +++ b/docs/bib/ref.bib @@ -156,6 +156,7 @@ @book{Press2007 issn = {00361445}, journal = {Sample page from NUMBERICAL RECIPES IN C}, title = {Numerical Recipes 3rd Edition: The Art of Scientific Computing}, + publisher = {Cambridge University Press}, volume = {1}, year = {2007}, } @@ -272,4 +273,4 @@ @article{fitzhugh1961impulses pages={445--466}, year={1961}, publisher={Elsevier} -} \ No newline at end of file +} diff --git a/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py b/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py index 8262bb27..440b2a35 100644 --- a/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py +++ b/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py @@ -137,7 +137,7 @@ def create_loss(loss_type, parameters, ode, x0, t0, t, y, state_name, state_weight=None, sigma=None): """ Parameters (see also class `BaseLoss`) - ---------- + -------------------------------------- loss_type: class `BaseLoss` parameters: list a list of objects of class `Parameter` @@ -155,7 +155,8 @@ def create_loss(loss_type, parameters, ode, x0, t0, t, y, state_name, the state(s) which the observations came from state_weight: array like weight for the observations - sigma: + sigma: numeric + sigma for `NormalLoss` function """ assert t0 != t[0], "Make sure that the times, t, do not include t0" assert all(param.name in (ode.param_list+ode.state_list) for param in parameters), "Parameters have been provided that are not in the model" @@ -474,7 +475,7 @@ def _perform_generation(self, def continue_posterior_sample(self, N, tol, G=1, q=None, M=None, progress=False): """ Parameters (same as get_posterior_sample) - ---------- + ----------------------------------------- N: integer the number of samples in each generation tol: float or array like @@ -736,4 +737,4 @@ def _log_parameters(self, params): def _vprod(self,a1,a2): diff = (a1-a2).reshape((self.numParam,1)) return np.dot(diff,diff.T) - \ No newline at end of file + From 100434d3ae98708ebd49652f416c1336b749e243 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 12 Jul 2024 17:33:09 +0100 Subject: [PATCH 037/123] Updates to the documentation. --- docs/md/installation.md | 7 +- notebooks/ABC loss function tests.ipynb | 254 ++++++++++++++++++++++++ 2 files changed, 257 insertions(+), 4 deletions(-) create mode 100644 notebooks/ABC loss function tests.ipynb diff --git a/docs/md/installation.md b/docs/md/installation.md index 4543a6c0..0f088f4f 100644 --- a/docs/md/installation.md +++ b/docs/md/installation.md @@ -1,6 +1,6 @@ # Installation -Installation instructions may be found on the [GitHub project README](https://github.com/ukhsa-collaboration/pygom/tree/feature/prep-doc) (currently on the `feature/prep-doc` branch), but we include them here also. +Installation instructions may be found on the [GitHub project README](https://github.com/ukhsa-collaboration/pygom/), but we include them here also. ## From source @@ -43,8 +43,7 @@ pip install -r requirements.txt The final prerequisite, if you are working on a Windows machine, is that you will also need to install: - [Graphviz](https://graphviz.org/) -- [Visual C++](https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0) -- Visual C++ Build Tools +- [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) You you should be able to install the PyGOM package via command line: @@ -74,4 +73,4 @@ Test files should then be run from the command line to check that installation h python setup.py test ``` -This can take some minutes to complete. \ No newline at end of file +This can take some minutes to complete. diff --git a/notebooks/ABC loss function tests.ipynb b/notebooks/ABC loss function tests.ipynb new file mode 100644 index 00000000..ffc97d43 --- /dev/null +++ b/notebooks/ABC loss function tests.ipynb @@ -0,0 +1,254 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "e847f075-fdaa-4d6e-961c-02aaf1d7c112", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from unittest import main, TestCase\n", + "\n", + "from pygom import SquareLoss, NormalLoss\n", + "from pygom.model import common_models\n", + "from pygom import approximate_bayesian_computation as pgabc" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "533185c5-3671-4499-aba5-4d18f6a13a60", + "metadata": {}, + "outputs": [], + "source": [ + "class Expando: pass\n", + "self = Expando()\n", + "\n", + "## def setUp(self):\n", + "# define the model and parameters\n", + "self.ode = common_models.SIR({'beta':0.5, 'gamma':1.0/3.0})\n", + "\n", + "# the initial state, normalized to one\n", + "self.x0 = [1, 1.27e-6, 0]\n", + "# set the time sequence that we would like to observe\n", + "self.t = np.linspace(0, 150, 100)\n", + "self.ode.initial_values = (self.x0, self.t[0])\n", + "# find the solution\n", + "self.solution = self.ode.integrate(self.t[1::])\n", + "\n", + "# what the posterior median estimates should be close to\n", + "self.target = np.array([0.5, 1.0/3.0])\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "ac7a5ac6-ec89-4308-a0ff-fdddf383c62b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + " y = self.solution[1::, 1:3]\n", + " \n", + " # setting the parameters in the inference\n", + " parameters = [pgabc.Parameter('beta', 'unif', 0, 3, logscale=False),\n", + " pgabc.Parameter('gamma', 'unif', 0, 3, logscale=False)]\n", + " \n", + " # creating the loss and abc objects\n", + " sir_obj = pgabc.create_loss(SquareLoss, parameters, self.ode, self.x0, self.t[0],\n", + " self.t[1::], y, ['I', 'R'])\n", + " sir_abc = pgabc.ABC(sir_obj, parameters)\n", + " \n", + " # getting the posterior sample\n", + " sir_abc.get_posterior_sample(N=100, tol=np.inf, G=10, q=0.5)\n", + " sir_abc.continue_posterior_sample(N=100, tol=sir_abc.next_tol, G=10, q=0.5)\n", + "\n", + " # the estimate for beta must be between 0.485 and 0.515\n", + " # the estimate for gamma must be between 0.32 and 0.3466 \n", + " med_est = np.median(sir_abc.res, axis=0)\n", + " \n", + " np.allclose(med_est, self.target, 1e-2, 1e-2)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "1badf36a-9a0c-4f09-a69a-84383a188711", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + " # def test_SIR_abc_NormalLoss(self):\n", + " y = self.solution[1::, 1:3]\n", + " parameters = [pgabc.Parameter('beta', 'unif', 0, 3, logscale=False), \n", + " pgabc.Parameter('gamma', 'unif', 0, 3, logscale=False)]\n", + " sir_obj = pgabc.create_loss(NormalLoss, parameters, self.ode, self.x0, self.t[0],\n", + " self.t[1::], y, ['I', 'R'], sigma=1.0)\n", + " sir_abc = pgabc.ABC(sir_obj, parameters)\n", + " sir_abc.get_posterior_sample(N=100, tol=np.inf, G=10, q=0.5)\n", + " sir_abc.continue_posterior_sample(N=100, tol=sir_abc.next_tol, G=10, q=0.5)\n", + " med_est = np.median(sir_abc.res, axis=0)\n", + " np.allclose(med_est, self.target, 1e-2, 1e-2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2e3c926e-a194-45e0-aade-7b6593be15e5", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "9cbf8b2a-5b64-4604-9a9a-fbe766a6ee04", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> \u001b[0;32m/home/phe.gov.uk/thomas.finnie/git/pygom/pygom/loss/ode_loss.py\u001b[0m(59)\u001b[0;36m_setLossType\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32m 57 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 58 \u001b[0;31m \u001b[0;32mdef\u001b[0m \u001b[0m_setLossType\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m---> 59 \u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_lossObj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mNormal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_y\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_weight\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_spread_param\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 60 \u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_lossObj\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 61 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ipdb> u\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> \u001b[0;32m/home/phe.gov.uk/thomas.finnie/git/pygom/pygom/loss/base_loss.py\u001b[0m(191)\u001b[0;36m__init__\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32m 189 \u001b[0;31m \u001b[0;31m# TODO: optimal weight in terms of Pareto front from a\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 190 \u001b[0;31m \u001b[0;31m# multiobjective optimization perspective\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m--> 191 \u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_lossObj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_setLossType\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 192 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 193 \u001b[0;31m \u001b[0;31m# final check\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ipdb> state_name\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['I', 'R']\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ipdb> spread_param\n", + "ipdb> u\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> \u001b[0;32m/home/phe.gov.uk/thomas.finnie/git/pygom/pygom/loss/ode_loss.py\u001b[0m(43)\u001b[0;36m__init__\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32m 41 \u001b[0;31m def __init__(self, theta, ode, x0, t0, t, y, state_name, state_weight=None,\n", + "\u001b[0m\u001b[0;32m 42 \u001b[0;31m sigma=1.0, target_param=None, target_state=None):\n", + "\u001b[0m\u001b[0;32m---> 43 \u001b[0;31m super().__init__(theta=theta, \n", + "\u001b[0m\u001b[0;32m 44 \u001b[0;31m \u001b[0mode\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mode\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 45 \u001b[0;31m \u001b[0mx0\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mx0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ipdb> sigma\n", + "ipdb> u\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> \u001b[0;32m/home/phe.gov.uk/thomas.finnie/git/pygom/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py\u001b[0m(162)\u001b[0;36mcreate_loss\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32m 160 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 161 \u001b[0;31m \u001b[0;32melif\u001b[0m \u001b[0mloss_type\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mNormalLoss\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m--> 162 \u001b[0;31m return NormalLoss(theta=theta, \n", + "\u001b[0m\u001b[0;32m 163 \u001b[0;31m \u001b[0mode\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mode\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 164 \u001b[0;31m \u001b[0mx0\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mx0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ipdb> sigma\n", + "ipdb> q\n" + ] + } + ], + "source": [ + "debug" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From f4623c1796142f41d1012544b087067ded68a20d Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Fri, 19 Jul 2024 13:06:23 +0100 Subject: [PATCH 038/123] Test tau leap step size algorithm --- debug_tau_leap.ipynb | 512 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 512 insertions(+) create mode 100644 debug_tau_leap.ipynb diff --git a/debug_tau_leap.ipynb b/debug_tau_leap.ipynb new file mode 100644 index 00000000..5ffe59d3 --- /dev/null +++ b/debug_tau_leap.ipynb @@ -0,0 +1,512 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this notebook, we debug the `_test_tau_leap_safety` function (old version written in python).\n", + "Fixing this will help to understand and fix the Cython version.\n", + "\n", + "First load the relevant modules:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import SimulateOde, Transition, TransitionType\n", + "import numpy as np\n", + "import math" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Set up PyGOM object. This will be an SIR model with births and deaths:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1, 0, 0, 1, 0, 0],\n", + " [1, 1, 0, 0, 1, 0],\n", + " [0, 0, 0, 0, 0, 1]])" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "state = ['S', 'I', 'R']\n", + "param_list = ['beta', 'gamma', 'mu', 'N']\n", + "\n", + "transition = [\n", + " Transition(origin='S',\n", + " destination='I',\n", + " equation='beta*S*I/N',\n", + " transition_type=TransitionType.T),\n", + " Transition(origin='I',\n", + " destination='R',\n", + " equation='gamma*I',\n", + " transition_type=TransitionType.T)\n", + "]\n", + "\n", + "birth_death = [\n", + " Transition(origin='S',\n", + " equation='mu*N',\n", + " transition_type=TransitionType.B),\n", + " Transition(origin='S',\n", + " equation='mu*S',\n", + " transition_type=TransitionType.D),\n", + " Transition(origin='I',\n", + " equation='mu*I',\n", + " transition_type=TransitionType.D),\n", + " Transition(origin='R',\n", + " equation='mu*R',\n", + " transition_type=TransitionType.D)\n", + "]\n", + "\n", + "# initialize the model\n", + "ode = SimulateOde(state,\n", + " param_list,\n", + " birth_death=birth_death,\n", + " transition=transition)\n", + "\n", + "#Params\n", + "n_pop=1e4\n", + "param_set=[('beta', 0.4), ('gamma', 0.25), ('mu', 0.01), ('N', n_pop)]\n", + "ode.parameters=param_set\n", + "\n", + "# Initial conditions\n", + "i0=10\n", + "x0 = [n_pop-i0, i0, 0]\n", + "ode.initial_values = (x0, 0)\n", + "\n", + "# Calculate reactant matrix\n", + "ode._computeReactantMatrix()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define old python version of function here. I've added a few comments in" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "## Python solution\n", + "\n", + "import scipy.stats as st\n", + "\n", + "def _ppois(q, mu=1.0):\n", + " '''\n", + " A cached and slightly faster and less safe version of the pygom.utilR.ppois\n", + " function\n", + " '''\n", + " return st.poisson._cdf(q, mu=mu)\n", + "\n", + "def _test_tau_leap_safety(x, reactant_mat, rates, tau_scale, epsilon):\n", + " \"\"\"\n", + " Additional safety test on :math:`\\\\tau`-leap, decrease the step size if\n", + " the original is not small enough. Decrease a couple of times and then\n", + " bail out because we don't want to spend too long decreasing the\n", + " step size until we find a suitable one.\n", + "\n", + " Parameters\n", + " ----------\n", + " x: array\n", + " Current populations of the states\n", + " reactant_mat: matrix\n", + " reactant_mat[i,j]=1 if state i involved in transition j and 0 if not\n", + " rates: array\n", + " rates of each of the transitions\n", + " tau_scale: float\n", + " initial value for timestep\n", + " epsilon: float\n", + " threshold value\n", + " \"\"\"\n", + "\n", + " total_rate = sum(rates) \n", + " safe = False # when True, indicates that tau_scale is sufficiently small\n", + " count = 0 # number of attempts to find acceptable tau_scale\n", + "\n", + " # Print output, first some titles\n", + " row=[\"Iteration\", \"tau_scale\", \"max_cdf\"]\n", + " print(\"{: <10} {: <10} {: <10}\".format(*row))\n", + "\n", + " while safe is False:\n", + " cdf_val = 1.0\n", + " for i, r in enumerate(rates):\n", + " xi = x[reactant_mat[:, i]] # reactant_mat[i,j]={0,1} so we only ever look at first 2 states. Seems wrong\n", + " mu=tau_scale*r # Expected number of events\n", + " new_cdf = _ppois(xi, mu=mu).min() # prob(# transitions in jump < size of state)\n", + " if new_cdf < cdf_val:\n", + " cdf_val = new_cdf\n", + "\n", + " max_cdf = 1.0 - cdf_val # prob(# transmissions in jump > size of state)\n", + "\n", + " # Print output\n", + " row=[count, tau_scale, max_cdf]\n", + " print(\"{: <10} {: <10.4g} {: <10.4g}\".format(*row))\n", + "\n", + " # cannot allow it to exceed out epsilon\n", + " if max_cdf > epsilon:\n", + " tau_scale /= (max_cdf / epsilon)\n", + " else:\n", + " safe = True\n", + "\n", + " # Abandon if we're taking too many attempts\n", + " if count > 256:\n", + " print(\"count error\")\n", + " return tau_scale, False\n", + " \n", + " # Abandon if tau_scale gets too small?\n", + " if tau_scale*total_rate <= 1.0:\n", + " print(\"scale error\")\n", + " return tau_scale, False\n", + " \n", + " count += 1\n", + "\n", + " return tau_scale, True" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We provide the state of the system to prepare the function inputs:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "x=np.array([100., 1., 0.]) # (S=100, I=1, R=0)\n", + "\n", + "reactant_mat=ode._lambdaMat # Reactant_mat[i,j]=1 if state i involved in transition j and 0 if not\n", + "\n", + "# Rates of transitions at current state x and time t\n", + "t=0 # No time dependence, so this is unimportant, just need to give something to function.\n", + "transition_func=ode.transition_vector\n", + "rates = transition_func(x, t)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, there seems to be an issue with the reactant matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 0 0 1 0 0]\n", + " [1 1 0 0 1 0]\n", + " [0 0 0 0 0 1]]\n" + ] + } + ], + "source": [ + "print(reactant_mat)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This correctly implies that states 0 and 1 ($S$ and $I$) are involved in infections (column 0).\n", + "It then incorrectly implies that only state 1 ($I$) is involved in recovery (column 1) and that no state is involved in births (column 2).\n", + "In the calculation of the reactant matrix, what is actually calculated is if the state appears as a variable in the equations.\n", + "i.e. $S$ and $I$ appear in infection rate $\\frac{\\beta S I}{N}$, but only $I$ appears in recovery rate $\\gamma I$.\n", + "\n", + "The second issue is that in the function `_test_tau_leap_safety`, we try to find the populations, xi, of the states involved in transition, i, via\n", + "\n", + "```{python}\n", + "xi = x[reactant_mat[:, i]]\n", + "```\n", + "\n", + "However, since reactant_mat only takes values 0 and 1, we are mistakenly recycling our binary indicators as state indices.\n", + "For example, let's look at the last transition, i=5, which should be a death rate from the recovereds:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([100., 100., 1.])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x[reactant_mat[:, 5]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We should just get $[N_R]$.\n", + "Instead, we get $[N_S, N_S, N_I]$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Perhaps we should instead use:\n", + "\n", + "```{python}\n", + "xi = x[reactant_mat[:, i]==1]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0.])" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x[reactant_mat[:, 5]==1]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Looks better, let's deifne a fixed version of the `_test_tau_leap_safety` function and compare them later:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def _test_tau_leap_safety_fix(x, reactant_mat, rates, tau_scale, epsilon):\n", + " total_rate = sum(rates) \n", + " safe = False # when True, indicates that tau_scale is sufficiently small\n", + " count = 0 # number of attempts to find acceptable tau_scale\n", + "\n", + " # Print output, first some titles\n", + " row=[\"Iteration\", \"tau_scale\", \"max_cdf\"]\n", + " print(\"{: <10} {: <10} {: <10}\".format(*row))\n", + "\n", + " while safe is False:\n", + " cdf_val = 1.0\n", + " for i, r in enumerate(rates):\n", + " xi = x[reactant_mat[:, i]==1] # Population of each state involved in the transitions\n", + " mu=tau_scale*r # Expected number of events\n", + " new_cdf = _ppois(xi, mu=mu).min() # prob(# transitions in jump < size of state)\n", + "\n", + " if new_cdf < cdf_val:\n", + " cdf_val = new_cdf\n", + "\n", + " max_cdf = 1.0 - cdf_val # prob(# transmissions in jump > size of state)\n", + "\n", + " # Print output\n", + " row=[count, tau_scale, max_cdf]\n", + " print(\"{: <10} {: <10.4g} {: <10.4g}\".format(*row))\n", + "\n", + " # cannot allow it to exceed out epsilon\n", + " if max_cdf > epsilon:\n", + " tau_scale /= (max_cdf / epsilon)\n", + " else:\n", + " safe = True\n", + "\n", + " # Abandon if we're taking too many attempts\n", + " if count > 256:\n", + " print(\"count error\")\n", + " return tau_scale, False\n", + " \n", + " # Abandon if tau_scale gets too small?\n", + " if tau_scale*total_rate <= 1.0:\n", + " print(\"scale error\")\n", + " return tau_scale, False\n", + " \n", + " count += 1\n", + "\n", + " return tau_scale, True" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We still have the issue that the `reactant_mat` which is input to the `_test_tau_leap_safety` function is not entirely correct.\n", + "For now, let's manually edit it and see the difference:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 0 1 1 0 0]\n", + " [1 1 0 0 1 0]\n", + " [0 1 0 0 0 1]]\n" + ] + } + ], + "source": [ + "reactant_mat_fix=reactant_mat\n", + "reactant_mat_fix[2, 1]=1 # add the fact that R is involved in recovery\n", + "reactant_mat_fix[0, 2]=1 # add the fact that S is involved in birth\n", + "print(reactant_mat)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We need a value of the parameter epsilon, which dictates how stringent we are with the step size.\n", + "There is usually a preliminary calculation to obtain a first guess for `tau_scale`, for now we supply an overly large value so that the function has to do some work." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "epsilon=0.1\n", + "tau_scale=10 # Set a silly high value, which algorithm should iteratively cut down" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's compare the output of each function" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Iteration tau_scale max_cdf \n", + "0 10 1 \n", + "1 1 0.4734 \n", + "2 0.2112 0.05144 \n", + "(0.21122098761337782, True)\n", + "\n", + "\n", + "Iteration tau_scale max_cdf \n", + "0 10 1 \n", + "1 1 1 \n", + "2 0.1 0.9995 \n", + "3 0.01 0.2644 \n", + "scale error\n", + "(0.003783681272942391, False)\n" + ] + } + ], + "source": [ + "y1=_test_tau_leap_safety_fix(x.astype(np.float64, copy=False),\n", + " reactant_mat_fix.astype(np.int64, copy=False),\n", + " rates.astype(np.float64, copy=False),\n", + " tau_scale=float(tau_scale),\n", + " epsilon=float(epsilon))\n", + "\n", + "print(y1)\n", + "print(\"\\n\")\n", + "\n", + "y2=_test_tau_leap_safety(x.astype(np.float64, copy=False),\n", + " reactant_mat.astype(np.int64, copy=False),\n", + " rates.astype(np.float64, copy=False),\n", + " tau_scale=float(tau_scale),\n", + " epsilon=float(epsilon))\n", + "\n", + "print(y2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that the old version fails due to the \"scale error\", namely\n", + "\n", + "```{python}\n", + "tau_scale*total_rate <= 1.0:\n", + "```\n", + "\n", + "It is worth pointing out that even if it didn't fail, it would not be returning correct values due to errors described above.\n", + "\n", + "The next question is why is this scale error useful?\n", + "Is it that we don't want the step size getting so small that the probability of nothing happening becomes significant. " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From b4d3a674ded7557564b4588485a89b94f53489b5 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 30 Jul 2024 12:56:53 +0100 Subject: [PATCH 039/123] Fix bug in tau leap algorithm --- pygom/model/_tau_leap.c | 2003 +++++++++++++++++++++------------ pygom/model/_tau_leap.pyx | 34 +- pygom/model/base_ode_model.py | 25 +- pygom/model/simulate.py | 26 +- 4 files changed, 1366 insertions(+), 722 deletions(-) diff --git a/pygom/model/_tau_leap.c b/pygom/model/_tau_leap.c index de05a573..04607eb1 100644 --- a/pygom/model/_tau_leap.c +++ b/pygom/model/_tau_leap.c @@ -10,6 +10,9 @@ "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\ndarraytypes.h", "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\ufuncobject.h" ], + "extra_compile_args": [ + "-std=c99" + ], "include_dirs": [ "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include" ], @@ -1673,7 +1676,7 @@ typedef struct { /* #### Code section: numeric_typedefs ### */ -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":730 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":770 * # in Cython to enable them only on the right systems. * * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< @@ -1682,7 +1685,7 @@ typedef struct { */ typedef npy_int8 __pyx_t_5numpy_int8_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":731 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":771 * * ctypedef npy_int8 int8_t * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< @@ -1691,7 +1694,7 @@ typedef npy_int8 __pyx_t_5numpy_int8_t; */ typedef npy_int16 __pyx_t_5numpy_int16_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":732 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":772 * ctypedef npy_int8 int8_t * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< @@ -1700,7 +1703,7 @@ typedef npy_int16 __pyx_t_5numpy_int16_t; */ typedef npy_int32 __pyx_t_5numpy_int32_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":733 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":773 * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< @@ -1709,7 +1712,7 @@ typedef npy_int32 __pyx_t_5numpy_int32_t; */ typedef npy_int64 __pyx_t_5numpy_int64_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":737 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":777 * #ctypedef npy_int128 int128_t * * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< @@ -1718,7 +1721,7 @@ typedef npy_int64 __pyx_t_5numpy_int64_t; */ typedef npy_uint8 __pyx_t_5numpy_uint8_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":738 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":778 * * ctypedef npy_uint8 uint8_t * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< @@ -1727,7 +1730,7 @@ typedef npy_uint8 __pyx_t_5numpy_uint8_t; */ typedef npy_uint16 __pyx_t_5numpy_uint16_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":739 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":779 * ctypedef npy_uint8 uint8_t * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< @@ -1736,7 +1739,7 @@ typedef npy_uint16 __pyx_t_5numpy_uint16_t; */ typedef npy_uint32 __pyx_t_5numpy_uint32_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":740 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":780 * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< @@ -1745,7 +1748,7 @@ typedef npy_uint32 __pyx_t_5numpy_uint32_t; */ typedef npy_uint64 __pyx_t_5numpy_uint64_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":744 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":784 * #ctypedef npy_uint128 uint128_t * * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< @@ -1754,7 +1757,7 @@ typedef npy_uint64 __pyx_t_5numpy_uint64_t; */ typedef npy_float32 __pyx_t_5numpy_float32_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":745 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":785 * * ctypedef npy_float32 float32_t * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< @@ -1763,43 +1766,25 @@ typedef npy_float32 __pyx_t_5numpy_float32_t; */ typedef npy_float64 __pyx_t_5numpy_float64_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":754 - * # The int types are mapped a bit surprising -- - * # numpy.int corresponds to 'l' and numpy.long to 'q' - * ctypedef npy_long int_t # <<<<<<<<<<<<<< - * ctypedef npy_longlong longlong_t +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":792 + * ctypedef double complex complex128_t * - */ -typedef npy_long __pyx_t_5numpy_int_t; - -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":755 - * # numpy.int corresponds to 'l' and numpy.long to 'q' - * ctypedef npy_long int_t * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< - * - * ctypedef npy_ulong uint_t - */ -typedef npy_longlong __pyx_t_5numpy_longlong_t; - -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":757 - * ctypedef npy_longlong longlong_t - * - * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< * ctypedef npy_ulonglong ulonglong_t * */ -typedef npy_ulong __pyx_t_5numpy_uint_t; +typedef npy_longlong __pyx_t_5numpy_longlong_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":758 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":793 * - * ctypedef npy_ulong uint_t + * ctypedef npy_longlong longlong_t * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< * * ctypedef npy_intp intp_t */ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":760 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":795 * ctypedef npy_ulonglong ulonglong_t * * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< @@ -1808,7 +1793,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; */ typedef npy_intp __pyx_t_5numpy_intp_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":761 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":796 * * ctypedef npy_intp intp_t * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< @@ -1817,7 +1802,7 @@ typedef npy_intp __pyx_t_5numpy_intp_t; */ typedef npy_uintp __pyx_t_5numpy_uintp_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":763 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":798 * ctypedef npy_uintp uintp_t * * ctypedef npy_double float_t # <<<<<<<<<<<<<< @@ -1826,7 +1811,7 @@ typedef npy_uintp __pyx_t_5numpy_uintp_t; */ typedef npy_double __pyx_t_5numpy_float_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":764 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":799 * * ctypedef npy_double float_t * ctypedef npy_double double_t # <<<<<<<<<<<<<< @@ -1835,12 +1820,12 @@ typedef npy_double __pyx_t_5numpy_float_t; */ typedef npy_double __pyx_t_5numpy_double_t; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":765 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":800 * ctypedef npy_double float_t * ctypedef npy_double double_t * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< * - * ctypedef npy_cfloat cfloat_t + * ctypedef float complex cfloat_t */ typedef npy_longdouble __pyx_t_5numpy_longdouble_t; /* #### Code section: complex_type_declarations ### */ @@ -1868,6 +1853,18 @@ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(floa #endif static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); +/* Declarations.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + typedef ::std::complex< long double > __pyx_t_long_double_complex; + #else + typedef long double _Complex __pyx_t_long_double_complex; + #endif +#else + typedef struct { long double real, imag; } __pyx_t_long_double_complex; +#endif +static CYTHON_INLINE __pyx_t_long_double_complex __pyx_t_long_double_complex_from_parts(long double, long double); + /* #### Code section: type_declarations ### */ /*--- Type declarations ---*/ @@ -1876,41 +1873,23 @@ struct __pyx_MemviewEnum_obj; struct __pyx_memoryview_obj; struct __pyx_memoryviewslice_obj; -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":767 - * ctypedef npy_longdouble longdouble_t - * - * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< - * ctypedef npy_cdouble cdouble_t - * ctypedef npy_clongdouble clongdouble_t - */ -typedef npy_cfloat __pyx_t_5numpy_cfloat_t; - -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":768 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1096 * - * ctypedef npy_cfloat cfloat_t - * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< - * ctypedef npy_clongdouble clongdouble_t + * # Iterator API added in v1.6 + * ctypedef int (*NpyIter_IterNextFunc)(NpyIter* it) noexcept nogil # <<<<<<<<<<<<<< + * ctypedef void (*NpyIter_GetMultiIndexFunc)(NpyIter* it, npy_intp* outcoords) noexcept nogil * */ -typedef npy_cdouble __pyx_t_5numpy_cdouble_t; +typedef int (*__pyx_t_5numpy_NpyIter_IterNextFunc)(NpyIter *); -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":769 - * ctypedef npy_cfloat cfloat_t - * ctypedef npy_cdouble cdouble_t - * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1097 + * # Iterator API added in v1.6 + * ctypedef int (*NpyIter_IterNextFunc)(NpyIter* it) noexcept nogil + * ctypedef void (*NpyIter_GetMultiIndexFunc)(NpyIter* it, npy_intp* outcoords) noexcept nogil # <<<<<<<<<<<<<< * - * ctypedef npy_cdouble complex_t + * cdef extern from "numpy/arrayobject.h": */ -typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; - -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":771 - * ctypedef npy_clongdouble clongdouble_t - * - * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew1(a): - */ -typedef npy_cdouble __pyx_t_5numpy_complex_t; +typedef void (*__pyx_t_5numpy_NpyIter_GetMultiIndexFunc)(NpyIter *, npy_intp *); struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_jn; struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_jn; struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_yn; @@ -3110,6 +3089,44 @@ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_n #endif #endif +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #define __Pyx_c_eq_long__double(a, b) ((a)==(b)) + #define __Pyx_c_sum_long__double(a, b) ((a)+(b)) + #define __Pyx_c_diff_long__double(a, b) ((a)-(b)) + #define __Pyx_c_prod_long__double(a, b) ((a)*(b)) + #define __Pyx_c_quot_long__double(a, b) ((a)/(b)) + #define __Pyx_c_neg_long__double(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_long__double(z) ((z)==(long double)0) + #define __Pyx_c_conj_long__double(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_long__double(z) (::std::abs(z)) + #define __Pyx_c_pow_long__double(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_long__double(z) ((z)==0) + #define __Pyx_c_conj_long__double(z) (conjl(z)) + #if 1 + #define __Pyx_c_abs_long__double(z) (cabsl(z)) + #define __Pyx_c_pow_long__double(a, b) (cpowl(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_sum_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_diff_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_prod_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_quot_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_neg_long__double(__pyx_t_long_double_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_long__double(__pyx_t_long_double_complex); + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_conj_long__double(__pyx_t_long_double_complex); + #if 1 + static CYTHON_INLINE long double __Pyx_c_abs_long__double(__pyx_t_long_double_complex); + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_pow_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); + #endif +#endif + /* MemviewSliceCopyTemplate.proto */ static __Pyx_memviewslice __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, @@ -3199,6 +3216,18 @@ static PyObject *__pyx_memoryview__get_base(struct __pyx_memoryview_obj *__pyx_v static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/ static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/ static PyObject *__pyx_memoryviewslice__get_base(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_8itemsize_itemsize(PyArray_Descr *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_9alignment_alignment(PyArray_Descr *__pyx_v_self); /* proto*/ +static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_6fields_fields(PyArray_Descr *__pyx_v_self); /* proto*/ +static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_5names_names(PyArray_Descr *__pyx_v_self); /* proto*/ +static CYTHON_INLINE PyArray_ArrayDescr *__pyx_f_5numpy_5dtype_8subarray_subarray(PyArray_Descr *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_uint64 __pyx_f_5numpy_5dtype_5flags_flags(PyArray_Descr *__pyx_v_self); /* proto*/ +static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_7numiter_numiter(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_4size_size(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_5index_index(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_2nd_nd(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_9broadcast_10dimensions_dimensions(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ +static CYTHON_INLINE void **__pyx_f_5numpy_9broadcast_5iters_iters(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject *__pyx_v_self); /* proto*/ static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArrayObject *__pyx_v_self); /* proto*/ static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx_v_self); /* proto*/ @@ -3291,6 +3320,7 @@ int __pyx_module_is_main_pygom__model___tau_leap = 0; /* Implementation of "pygom.model._tau_leap" */ /* #### Code section: global_var ### */ static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_print; static PyObject *__pyx_builtin___import__; static PyObject *__pyx_builtin_ValueError; static PyObject *__pyx_builtin_MemoryError; @@ -3316,7 +3346,7 @@ static const char __pyx_k_gc[] = "gc"; static const char __pyx_k_id[] = "id"; static const char __pyx_k_mu[] = "mu"; static const char __pyx_k_np[] = "np"; -static const char __pyx_k__24[] = "?"; +static const char __pyx_k__25[] = "?"; static const char __pyx_k_abc[] = "abc"; static const char __pyx_k_and[] = " and "; static const char __pyx_k_got[] = " (got "; @@ -3344,6 +3374,7 @@ static const char __pyx_k_error[] = "error"; static const char __pyx_k_flags[] = "flags"; static const char __pyx_k_index[] = "index"; static const char __pyx_k_numpy[] = "numpy"; +static const char __pyx_k_print[] = "print"; static const char __pyx_k_range[] = "range"; static const char __pyx_k_rates[] = "rates"; static const char __pyx_k_shape[] = "shape"; @@ -3390,6 +3421,7 @@ static const char __pyx_k_ImportError[] = "ImportError"; static const char __pyx_k_MemoryError[] = "MemoryError"; static const char __pyx_k_PickleError[] = "PickleError"; static const char __pyx_k_collections[] = "collections"; +static const char __pyx_k_count_error[] = "count error"; static const char __pyx_k_n_reactants[] = "n_reactants"; static const char __pyx_k_initializing[] = "_initializing"; static const char __pyx_k_is_coroutine[] = "_is_coroutine"; @@ -3427,7 +3459,6 @@ static const char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero static const char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array"; static const char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data."; static const char __pyx_k_strided_and_direct_or_indirect[] = ""; -static const char __pyx_k_numpy_core_multiarray_failed_to[] = "numpy.core.multiarray failed to import"; static const char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced"; static const char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides"; static const char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory."; @@ -3442,7 +3473,8 @@ static const char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on static const char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object"; static const char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension "; static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; -static const char __pyx_k_numpy_core_umath_failed_to_impor[] = "numpy.core.umath failed to import"; +static const char __pyx_k_numpy__core_multiarray_failed_to[] = "numpy._core.multiarray failed to import"; +static const char __pyx_k_numpy__core_umath_failed_to_impo[] = "numpy._core.umath failed to import"; static const char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides."; /* #### Code section: decls ### */ static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */ @@ -3605,7 +3637,7 @@ typedef struct { PyObject *__pyx_n_s_ValueError; PyObject *__pyx_n_s_View_MemoryView; PyObject *__pyx_kp_u__2; - PyObject *__pyx_n_s__24; + PyObject *__pyx_n_s__25; PyObject *__pyx_n_s__3; PyObject *__pyx_kp_u__6; PyObject *__pyx_kp_u__7; @@ -3625,6 +3657,7 @@ typedef struct { PyObject *__pyx_kp_s_contiguous_and_direct; PyObject *__pyx_kp_s_contiguous_and_indirect; PyObject *__pyx_n_s_count; + PyObject *__pyx_kp_s_count_error; PyObject *__pyx_n_s_cy_test_tau_leap_safety; PyObject *__pyx_n_s_dict; PyObject *__pyx_kp_u_disable; @@ -3667,11 +3700,12 @@ typedef struct { PyObject *__pyx_kp_s_no_default___reduce___due_to_non; PyObject *__pyx_n_s_np; PyObject *__pyx_n_s_numpy; - PyObject *__pyx_kp_s_numpy_core_multiarray_failed_to; - PyObject *__pyx_kp_s_numpy_core_umath_failed_to_impor; + PyObject *__pyx_kp_s_numpy__core_multiarray_failed_to; + PyObject *__pyx_kp_s_numpy__core_umath_failed_to_impo; PyObject *__pyx_n_s_obj; PyObject *__pyx_n_s_pack; PyObject *__pyx_n_s_pickle; + PyObject *__pyx_n_s_print; PyObject *__pyx_n_s_pygom_model__tau_leap; PyObject *__pyx_kp_s_pygom_model__tau_leap_pyx; PyObject *__pyx_n_s_pyx_PickleError; @@ -3738,9 +3772,10 @@ typedef struct { PyObject *__pyx_tuple__18; PyObject *__pyx_tuple__19; PyObject *__pyx_tuple__20; - PyObject *__pyx_tuple__22; - PyObject *__pyx_codeobj__21; - PyObject *__pyx_codeobj__23; + PyObject *__pyx_tuple__21; + PyObject *__pyx_tuple__23; + PyObject *__pyx_codeobj__22; + PyObject *__pyx_codeobj__24; } __pyx_mstate; #if CYTHON_USE_MODULE_STATE @@ -3840,7 +3875,7 @@ static int __pyx_m_clear(PyObject *m) { Py_CLEAR(clear_module_state->__pyx_n_s_ValueError); Py_CLEAR(clear_module_state->__pyx_n_s_View_MemoryView); Py_CLEAR(clear_module_state->__pyx_kp_u__2); - Py_CLEAR(clear_module_state->__pyx_n_s__24); + Py_CLEAR(clear_module_state->__pyx_n_s__25); Py_CLEAR(clear_module_state->__pyx_n_s__3); Py_CLEAR(clear_module_state->__pyx_kp_u__6); Py_CLEAR(clear_module_state->__pyx_kp_u__7); @@ -3860,6 +3895,7 @@ static int __pyx_m_clear(PyObject *m) { Py_CLEAR(clear_module_state->__pyx_kp_s_contiguous_and_direct); Py_CLEAR(clear_module_state->__pyx_kp_s_contiguous_and_indirect); Py_CLEAR(clear_module_state->__pyx_n_s_count); + Py_CLEAR(clear_module_state->__pyx_kp_s_count_error); Py_CLEAR(clear_module_state->__pyx_n_s_cy_test_tau_leap_safety); Py_CLEAR(clear_module_state->__pyx_n_s_dict); Py_CLEAR(clear_module_state->__pyx_kp_u_disable); @@ -3902,11 +3938,12 @@ static int __pyx_m_clear(PyObject *m) { Py_CLEAR(clear_module_state->__pyx_kp_s_no_default___reduce___due_to_non); Py_CLEAR(clear_module_state->__pyx_n_s_np); Py_CLEAR(clear_module_state->__pyx_n_s_numpy); - Py_CLEAR(clear_module_state->__pyx_kp_s_numpy_core_multiarray_failed_to); - Py_CLEAR(clear_module_state->__pyx_kp_s_numpy_core_umath_failed_to_impor); + Py_CLEAR(clear_module_state->__pyx_kp_s_numpy__core_multiarray_failed_to); + Py_CLEAR(clear_module_state->__pyx_kp_s_numpy__core_umath_failed_to_impo); Py_CLEAR(clear_module_state->__pyx_n_s_obj); Py_CLEAR(clear_module_state->__pyx_n_s_pack); Py_CLEAR(clear_module_state->__pyx_n_s_pickle); + Py_CLEAR(clear_module_state->__pyx_n_s_print); Py_CLEAR(clear_module_state->__pyx_n_s_pygom_model__tau_leap); Py_CLEAR(clear_module_state->__pyx_kp_s_pygom_model__tau_leap_pyx); Py_CLEAR(clear_module_state->__pyx_n_s_pyx_PickleError); @@ -3973,9 +4010,10 @@ static int __pyx_m_clear(PyObject *m) { Py_CLEAR(clear_module_state->__pyx_tuple__18); Py_CLEAR(clear_module_state->__pyx_tuple__19); Py_CLEAR(clear_module_state->__pyx_tuple__20); - Py_CLEAR(clear_module_state->__pyx_tuple__22); - Py_CLEAR(clear_module_state->__pyx_codeobj__21); - Py_CLEAR(clear_module_state->__pyx_codeobj__23); + Py_CLEAR(clear_module_state->__pyx_tuple__21); + Py_CLEAR(clear_module_state->__pyx_tuple__23); + Py_CLEAR(clear_module_state->__pyx_codeobj__22); + Py_CLEAR(clear_module_state->__pyx_codeobj__24); return 0; } #endif @@ -4053,7 +4091,7 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(traverse_module_state->__pyx_n_s_ValueError); Py_VISIT(traverse_module_state->__pyx_n_s_View_MemoryView); Py_VISIT(traverse_module_state->__pyx_kp_u__2); - Py_VISIT(traverse_module_state->__pyx_n_s__24); + Py_VISIT(traverse_module_state->__pyx_n_s__25); Py_VISIT(traverse_module_state->__pyx_n_s__3); Py_VISIT(traverse_module_state->__pyx_kp_u__6); Py_VISIT(traverse_module_state->__pyx_kp_u__7); @@ -4073,6 +4111,7 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(traverse_module_state->__pyx_kp_s_contiguous_and_direct); Py_VISIT(traverse_module_state->__pyx_kp_s_contiguous_and_indirect); Py_VISIT(traverse_module_state->__pyx_n_s_count); + Py_VISIT(traverse_module_state->__pyx_kp_s_count_error); Py_VISIT(traverse_module_state->__pyx_n_s_cy_test_tau_leap_safety); Py_VISIT(traverse_module_state->__pyx_n_s_dict); Py_VISIT(traverse_module_state->__pyx_kp_u_disable); @@ -4115,11 +4154,12 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(traverse_module_state->__pyx_kp_s_no_default___reduce___due_to_non); Py_VISIT(traverse_module_state->__pyx_n_s_np); Py_VISIT(traverse_module_state->__pyx_n_s_numpy); - Py_VISIT(traverse_module_state->__pyx_kp_s_numpy_core_multiarray_failed_to); - Py_VISIT(traverse_module_state->__pyx_kp_s_numpy_core_umath_failed_to_impor); + Py_VISIT(traverse_module_state->__pyx_kp_s_numpy__core_multiarray_failed_to); + Py_VISIT(traverse_module_state->__pyx_kp_s_numpy__core_umath_failed_to_impo); Py_VISIT(traverse_module_state->__pyx_n_s_obj); Py_VISIT(traverse_module_state->__pyx_n_s_pack); Py_VISIT(traverse_module_state->__pyx_n_s_pickle); + Py_VISIT(traverse_module_state->__pyx_n_s_print); Py_VISIT(traverse_module_state->__pyx_n_s_pygom_model__tau_leap); Py_VISIT(traverse_module_state->__pyx_kp_s_pygom_model__tau_leap_pyx); Py_VISIT(traverse_module_state->__pyx_n_s_pyx_PickleError); @@ -4186,9 +4226,10 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(traverse_module_state->__pyx_tuple__18); Py_VISIT(traverse_module_state->__pyx_tuple__19); Py_VISIT(traverse_module_state->__pyx_tuple__20); - Py_VISIT(traverse_module_state->__pyx_tuple__22); - Py_VISIT(traverse_module_state->__pyx_codeobj__21); - Py_VISIT(traverse_module_state->__pyx_codeobj__23); + Py_VISIT(traverse_module_state->__pyx_tuple__21); + Py_VISIT(traverse_module_state->__pyx_tuple__23); + Py_VISIT(traverse_module_state->__pyx_codeobj__22); + Py_VISIT(traverse_module_state->__pyx_codeobj__24); return 0; } #endif @@ -4304,7 +4345,7 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { #define __pyx_n_s_ValueError __pyx_mstate_global->__pyx_n_s_ValueError #define __pyx_n_s_View_MemoryView __pyx_mstate_global->__pyx_n_s_View_MemoryView #define __pyx_kp_u__2 __pyx_mstate_global->__pyx_kp_u__2 -#define __pyx_n_s__24 __pyx_mstate_global->__pyx_n_s__24 +#define __pyx_n_s__25 __pyx_mstate_global->__pyx_n_s__25 #define __pyx_n_s__3 __pyx_mstate_global->__pyx_n_s__3 #define __pyx_kp_u__6 __pyx_mstate_global->__pyx_kp_u__6 #define __pyx_kp_u__7 __pyx_mstate_global->__pyx_kp_u__7 @@ -4324,6 +4365,7 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { #define __pyx_kp_s_contiguous_and_direct __pyx_mstate_global->__pyx_kp_s_contiguous_and_direct #define __pyx_kp_s_contiguous_and_indirect __pyx_mstate_global->__pyx_kp_s_contiguous_and_indirect #define __pyx_n_s_count __pyx_mstate_global->__pyx_n_s_count +#define __pyx_kp_s_count_error __pyx_mstate_global->__pyx_kp_s_count_error #define __pyx_n_s_cy_test_tau_leap_safety __pyx_mstate_global->__pyx_n_s_cy_test_tau_leap_safety #define __pyx_n_s_dict __pyx_mstate_global->__pyx_n_s_dict #define __pyx_kp_u_disable __pyx_mstate_global->__pyx_kp_u_disable @@ -4366,11 +4408,12 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { #define __pyx_kp_s_no_default___reduce___due_to_non __pyx_mstate_global->__pyx_kp_s_no_default___reduce___due_to_non #define __pyx_n_s_np __pyx_mstate_global->__pyx_n_s_np #define __pyx_n_s_numpy __pyx_mstate_global->__pyx_n_s_numpy -#define __pyx_kp_s_numpy_core_multiarray_failed_to __pyx_mstate_global->__pyx_kp_s_numpy_core_multiarray_failed_to -#define __pyx_kp_s_numpy_core_umath_failed_to_impor __pyx_mstate_global->__pyx_kp_s_numpy_core_umath_failed_to_impor +#define __pyx_kp_s_numpy__core_multiarray_failed_to __pyx_mstate_global->__pyx_kp_s_numpy__core_multiarray_failed_to +#define __pyx_kp_s_numpy__core_umath_failed_to_impo __pyx_mstate_global->__pyx_kp_s_numpy__core_umath_failed_to_impo #define __pyx_n_s_obj __pyx_mstate_global->__pyx_n_s_obj #define __pyx_n_s_pack __pyx_mstate_global->__pyx_n_s_pack #define __pyx_n_s_pickle __pyx_mstate_global->__pyx_n_s_pickle +#define __pyx_n_s_print __pyx_mstate_global->__pyx_n_s_print #define __pyx_n_s_pygom_model__tau_leap __pyx_mstate_global->__pyx_n_s_pygom_model__tau_leap #define __pyx_kp_s_pygom_model__tau_leap_pyx __pyx_mstate_global->__pyx_kp_s_pygom_model__tau_leap_pyx #define __pyx_n_s_pyx_PickleError __pyx_mstate_global->__pyx_n_s_pyx_PickleError @@ -4437,9 +4480,10 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { #define __pyx_tuple__18 __pyx_mstate_global->__pyx_tuple__18 #define __pyx_tuple__19 __pyx_mstate_global->__pyx_tuple__19 #define __pyx_tuple__20 __pyx_mstate_global->__pyx_tuple__20 -#define __pyx_tuple__22 __pyx_mstate_global->__pyx_tuple__22 -#define __pyx_codeobj__21 __pyx_mstate_global->__pyx_codeobj__21 -#define __pyx_codeobj__23 __pyx_mstate_global->__pyx_codeobj__23 +#define __pyx_tuple__21 __pyx_mstate_global->__pyx_tuple__21 +#define __pyx_tuple__23 __pyx_mstate_global->__pyx_tuple__23 +#define __pyx_codeobj__22 __pyx_mstate_global->__pyx_codeobj__22 +#define __pyx_codeobj__24 __pyx_mstate_global->__pyx_codeobj__24 /* #### Code section: module_code ### */ /* "View.MemoryView":131 @@ -18068,33 +18112,33 @@ static PyObject *__pyx_unpickle_Enum__set_state(struct __pyx_MemviewEnum_obj *__ return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":245 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":286 * * @property - * cdef inline PyObject* base(self) nogil: # <<<<<<<<<<<<<< - * """Returns a borrowed reference to the object owning the data/memory. - * """ + * cdef inline npy_intp itemsize(self) noexcept nogil: # <<<<<<<<<<<<<< + * return PyDataType_ELSIZE(self) + * */ -static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject *__pyx_v_self) { - PyObject *__pyx_r; +static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_8itemsize_itemsize(PyArray_Descr *__pyx_v_self) { + npy_intp __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":248 - * """Returns a borrowed reference to the object owning the data/memory. - * """ - * return PyArray_BASE(self) # <<<<<<<<<<<<<< + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":287 + * @property + * cdef inline npy_intp itemsize(self) noexcept nogil: + * return PyDataType_ELSIZE(self) # <<<<<<<<<<<<<< * * @property */ - __pyx_r = PyArray_BASE(__pyx_v_self); + __pyx_r = PyDataType_ELSIZE(__pyx_v_self); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":245 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":286 * * @property - * cdef inline PyObject* base(self) nogil: # <<<<<<<<<<<<<< - * """Returns a borrowed reference to the object owning the data/memory. - * """ + * cdef inline npy_intp itemsize(self) noexcept nogil: # <<<<<<<<<<<<<< + * return PyDataType_ELSIZE(self) + * */ /* function exit code */ @@ -18102,143 +18146,151 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":251 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":290 * * @property - * cdef inline dtype descr(self): # <<<<<<<<<<<<<< - * """Returns an owned reference to the dtype of the array. - * """ + * cdef inline npy_intp alignment(self) noexcept nogil: # <<<<<<<<<<<<<< + * return PyDataType_ALIGNMENT(self) + * */ -static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArrayObject *__pyx_v_self) { - PyArray_Descr *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyArray_Descr *__pyx_t_1; - __Pyx_RefNannySetupContext("descr", 1); +static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_9alignment_alignment(PyArray_Descr *__pyx_v_self) { + npy_intp __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":254 - * """Returns an owned reference to the dtype of the array. - * """ - * return PyArray_DESCR(self) # <<<<<<<<<<<<<< - * + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":291 * @property + * cdef inline npy_intp alignment(self) noexcept nogil: + * return PyDataType_ALIGNMENT(self) # <<<<<<<<<<<<<< + * + * # Use fields/names with care as they may be NULL. You must check */ - __Pyx_XDECREF((PyObject *)__pyx_r); - __pyx_t_1 = PyArray_DESCR(__pyx_v_self); - __Pyx_INCREF((PyObject *)((PyArray_Descr *)__pyx_t_1)); - __pyx_r = ((PyArray_Descr *)__pyx_t_1); + __pyx_r = PyDataType_ALIGNMENT(__pyx_v_self); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":251 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":290 * * @property - * cdef inline dtype descr(self): # <<<<<<<<<<<<<< - * """Returns an owned reference to the dtype of the array. - * """ + * cdef inline npy_intp alignment(self) noexcept nogil: # <<<<<<<<<<<<<< + * return PyDataType_ALIGNMENT(self) + * */ /* function exit code */ __pyx_L0:; - __Pyx_XGIVEREF((PyObject *)__pyx_r); - __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":257 - * +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":296 + * # for this using PyDataType_HASFIELDS. * @property - * cdef inline int ndim(self) nogil: # <<<<<<<<<<<<<< - * """Returns the number of dimensions in the array. - * """ + * cdef inline object fields(self): # <<<<<<<<<<<<<< + * return PyDataType_FIELDS(self) + * */ -static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx_v_self) { - int __pyx_r; +static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_6fields_fields(PyArray_Descr *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1; + __Pyx_RefNannySetupContext("fields", 1); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":260 - * """Returns the number of dimensions in the array. - * """ - * return PyArray_NDIM(self) # <<<<<<<<<<<<<< + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":297 + * @property + * cdef inline object fields(self): + * return PyDataType_FIELDS(self) # <<<<<<<<<<<<<< * * @property */ - __pyx_r = PyArray_NDIM(__pyx_v_self); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyDataType_FIELDS(__pyx_v_self); + __Pyx_INCREF(((PyObject *)__pyx_t_1)); + __pyx_r = ((PyObject *)__pyx_t_1); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":257 - * + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":296 + * # for this using PyDataType_HASFIELDS. * @property - * cdef inline int ndim(self) nogil: # <<<<<<<<<<<<<< - * """Returns the number of dimensions in the array. - * """ + * cdef inline object fields(self): # <<<<<<<<<<<<<< + * return PyDataType_FIELDS(self) + * */ /* function exit code */ __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":263 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":300 * * @property - * cdef inline npy_intp *shape(self) nogil: # <<<<<<<<<<<<<< - * """Returns a pointer to the dimensions/shape of the array. - * The number of elements matches the number of dimensions of the array (ndim). + * cdef inline tuple names(self): # <<<<<<<<<<<<<< + * return PyDataType_NAMES(self) + * */ -static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObject *__pyx_v_self) { - npy_intp *__pyx_r; +static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_5names_names(PyArray_Descr *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1; + __Pyx_RefNannySetupContext("names", 1); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":268 - * Can return NULL for 0-dimensional arrays. - * """ - * return PyArray_DIMS(self) # <<<<<<<<<<<<<< - * + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":301 * @property + * cdef inline tuple names(self): + * return PyDataType_NAMES(self) # <<<<<<<<<<<<<< + * + * # Use PyDataType_HASSUBARRAY to test whether this field is */ - __pyx_r = PyArray_DIMS(__pyx_v_self); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyDataType_NAMES(__pyx_v_self); + __Pyx_INCREF(((PyObject*)__pyx_t_1)); + __pyx_r = ((PyObject*)__pyx_t_1); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":263 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":300 * * @property - * cdef inline npy_intp *shape(self) nogil: # <<<<<<<<<<<<<< - * """Returns a pointer to the dimensions/shape of the array. - * The number of elements matches the number of dimensions of the array (ndim). + * cdef inline tuple names(self): # <<<<<<<<<<<<<< + * return PyDataType_NAMES(self) + * */ /* function exit code */ __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":271 - * +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":307 + * # this field via the inline helper method PyDataType_SHAPE. * @property - * cdef inline npy_intp *strides(self) nogil: # <<<<<<<<<<<<<< - * """Returns a pointer to the strides of the array. - * The number of elements matches the number of dimensions of the array (ndim). + * cdef inline PyArray_ArrayDescr* subarray(self) noexcept nogil: # <<<<<<<<<<<<<< + * return PyDataType_SUBARRAY(self) + * */ -static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayObject *__pyx_v_self) { - npy_intp *__pyx_r; +static CYTHON_INLINE PyArray_ArrayDescr *__pyx_f_5numpy_5dtype_8subarray_subarray(PyArray_Descr *__pyx_v_self) { + PyArray_ArrayDescr *__pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":275 - * The number of elements matches the number of dimensions of the array (ndim). - * """ - * return PyArray_STRIDES(self) # <<<<<<<<<<<<<< + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":308 + * @property + * cdef inline PyArray_ArrayDescr* subarray(self) noexcept nogil: + * return PyDataType_SUBARRAY(self) # <<<<<<<<<<<<<< * * @property */ - __pyx_r = PyArray_STRIDES(__pyx_v_self); + __pyx_r = PyDataType_SUBARRAY(__pyx_v_self); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":271 - * + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":307 + * # this field via the inline helper method PyDataType_SHAPE. * @property - * cdef inline npy_intp *strides(self) nogil: # <<<<<<<<<<<<<< - * """Returns a pointer to the strides of the array. - * The number of elements matches the number of dimensions of the array (ndim). + * cdef inline PyArray_ArrayDescr* subarray(self) noexcept nogil: # <<<<<<<<<<<<<< + * return PyDataType_SUBARRAY(self) + * */ /* function exit code */ @@ -18246,33 +18298,33 @@ static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayO return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":278 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":311 * * @property - * cdef inline npy_intp size(self) nogil: # <<<<<<<<<<<<<< - * """Returns the total size (in number of elements) of the array. - * """ + * cdef inline npy_uint64 flags(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The data types flags.""" + * return PyDataType_FLAGS(self) */ -static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject *__pyx_v_self) { - npy_intp __pyx_r; +static CYTHON_INLINE npy_uint64 __pyx_f_5numpy_5dtype_5flags_flags(PyArray_Descr *__pyx_v_self) { + npy_uint64 __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":281 - * """Returns the total size (in number of elements) of the array. - * """ - * return PyArray_SIZE(self) # <<<<<<<<<<<<<< + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":313 + * cdef inline npy_uint64 flags(self) noexcept nogil: + * """The data types flags.""" + * return PyDataType_FLAGS(self) # <<<<<<<<<<<<<< + * * - * @property */ - __pyx_r = PyArray_SIZE(__pyx_v_self); + __pyx_r = PyDataType_FLAGS(__pyx_v_self); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":278 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":311 * * @property - * cdef inline npy_intp size(self) nogil: # <<<<<<<<<<<<<< - * """Returns the total size (in number of elements) of the array. - * """ + * cdef inline npy_uint64 flags(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The data types flags.""" + * return PyDataType_FLAGS(self) */ /* function exit code */ @@ -18280,33 +18332,33 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject * return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":284 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":323 * * @property - * cdef inline char* data(self) nogil: # <<<<<<<<<<<<<< - * """The pointer to the data buffer as a char*. - * This is provided for legacy reasons to avoid direct struct field access. + * cdef inline int numiter(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The number of arrays that need to be broadcast to the same shape.""" + * return PyArray_MultiIter_NUMITER(self) */ -static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__pyx_v_self) { - char *__pyx_r; +static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_7numiter_numiter(PyArrayMultiIterObject *__pyx_v_self) { + int __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":290 - * of `PyArray_DATA()` instead, which returns a 'void*'. - * """ - * return PyArray_BYTES(self) # <<<<<<<<<<<<<< + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":325 + * cdef inline int numiter(self) noexcept nogil: + * """The number of arrays that need to be broadcast to the same shape.""" + * return PyArray_MultiIter_NUMITER(self) # <<<<<<<<<<<<<< * - * ctypedef unsigned char npy_bool + * @property */ - __pyx_r = PyArray_BYTES(__pyx_v_self); + __pyx_r = PyArray_MultiIter_NUMITER(__pyx_v_self); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":284 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":323 * * @property - * cdef inline char* data(self) nogil: # <<<<<<<<<<<<<< - * """The pointer to the data buffer as a char*. - * This is provided for legacy reasons to avoid direct struct field access. + * cdef inline int numiter(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The number of arrays that need to be broadcast to the same shape.""" + * return PyArray_MultiIter_NUMITER(self) */ /* function exit code */ @@ -18314,148 +18366,564 @@ static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__p return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":773 - * ctypedef npy_cdouble complex_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":328 * + * @property + * cdef inline npy_intp size(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The total broadcasted size.""" + * return PyArray_MultiIter_SIZE(self) */ -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 1); +static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_4size_size(PyArrayMultiIterObject *__pyx_v_self) { + npy_intp __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":774 - * - * cdef inline object PyArray_MultiIterNew1(a): - * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":330 + * cdef inline npy_intp size(self) noexcept nogil: + * """The total broadcasted size.""" + * return PyArray_MultiIter_SIZE(self) # <<<<<<<<<<<<<< * - * cdef inline object PyArray_MultiIterNew2(a, b): + * @property */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 774, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; + __pyx_r = PyArray_MultiIter_SIZE(__pyx_v_self); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":773 - * ctypedef npy_cdouble complex_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":328 * + * @property + * cdef inline npy_intp size(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The total broadcasted size.""" + * return PyArray_MultiIter_SIZE(self) */ /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":776 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":333 * + * @property + * cdef inline npy_intp index(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The current (1-d) index into the broadcasted result.""" + * return PyArray_MultiIter_INDEX(self) */ -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 1); +static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_5index_index(PyArrayMultiIterObject *__pyx_v_self) { + npy_intp __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":777 - * - * cdef inline object PyArray_MultiIterNew2(a, b): - * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":335 + * cdef inline npy_intp index(self) noexcept nogil: + * """The current (1-d) index into the broadcasted result.""" + * return PyArray_MultiIter_INDEX(self) # <<<<<<<<<<<<<< * - * cdef inline object PyArray_MultiIterNew3(a, b, c): + * @property */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 777, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; + __pyx_r = PyArray_MultiIter_INDEX(__pyx_v_self); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":776 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":333 * + * @property + * cdef inline npy_intp index(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The current (1-d) index into the broadcasted result.""" + * return PyArray_MultiIter_INDEX(self) */ /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":779 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":338 * + * @property + * cdef inline int nd(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The number of dimensions in the broadcasted result.""" + * return PyArray_MultiIter_NDIM(self) */ -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 1); +static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_2nd_nd(PyArrayMultiIterObject *__pyx_v_self) { + int __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":780 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":340 + * cdef inline int nd(self) noexcept nogil: + * """The number of dimensions in the broadcasted result.""" + * return PyArray_MultiIter_NDIM(self) # <<<<<<<<<<<<<< * - * cdef inline object PyArray_MultiIterNew3(a, b, c): - * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + * @property */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 780, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; + __pyx_r = PyArray_MultiIter_NDIM(__pyx_v_self); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":779 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":338 * + * @property + * cdef inline int nd(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The number of dimensions in the broadcasted result.""" + * return PyArray_MultiIter_NDIM(self) */ /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); + __pyx_L0:; + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":343 + * + * @property + * cdef inline npy_intp* dimensions(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The shape of the broadcasted result.""" + * return PyArray_MultiIter_DIMS(self) + */ + +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_9broadcast_10dimensions_dimensions(PyArrayMultiIterObject *__pyx_v_self) { + npy_intp *__pyx_r; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":345 + * cdef inline npy_intp* dimensions(self) noexcept nogil: + * """The shape of the broadcasted result.""" + * return PyArray_MultiIter_DIMS(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_MultiIter_DIMS(__pyx_v_self); + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":343 + * + * @property + * cdef inline npy_intp* dimensions(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The shape of the broadcasted result.""" + * return PyArray_MultiIter_DIMS(self) + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":348 + * + * @property + * cdef inline void** iters(self) noexcept nogil: # <<<<<<<<<<<<<< + * """An array of iterator objects that holds the iterators for the arrays to be broadcast together. + * On return, the iterators are adjusted for broadcasting.""" + */ + +static CYTHON_INLINE void **__pyx_f_5numpy_9broadcast_5iters_iters(PyArrayMultiIterObject *__pyx_v_self) { + void **__pyx_r; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":351 + * """An array of iterator objects that holds the iterators for the arrays to be broadcast together. + * On return, the iterators are adjusted for broadcasting.""" + * return PyArray_MultiIter_ITERS(self) # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = PyArray_MultiIter_ITERS(__pyx_v_self); + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":348 + * + * @property + * cdef inline void** iters(self) noexcept nogil: # <<<<<<<<<<<<<< + * """An array of iterator objects that holds the iterators for the arrays to be broadcast together. + * On return, the iterators are adjusted for broadcasting.""" + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":366 + * + * @property + * cdef inline PyObject* base(self) noexcept nogil: # <<<<<<<<<<<<<< + * """Returns a borrowed reference to the object owning the data/memory. + * """ + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject *__pyx_v_self) { + PyObject *__pyx_r; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":369 + * """Returns a borrowed reference to the object owning the data/memory. + * """ + * return PyArray_BASE(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_BASE(__pyx_v_self); + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":366 + * + * @property + * cdef inline PyObject* base(self) noexcept nogil: # <<<<<<<<<<<<<< + * """Returns a borrowed reference to the object owning the data/memory. + * """ + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":372 + * + * @property + * cdef inline dtype descr(self): # <<<<<<<<<<<<<< + * """Returns an owned reference to the dtype of the array. + * """ + */ + +static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArrayObject *__pyx_v_self) { + PyArray_Descr *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyArray_Descr *__pyx_t_1; + __Pyx_RefNannySetupContext("descr", 1); + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":375 + * """Returns an owned reference to the dtype of the array. + * """ + * return PyArray_DESCR(self) # <<<<<<<<<<<<<< + * + * @property + */ + __Pyx_XDECREF((PyObject *)__pyx_r); + __pyx_t_1 = PyArray_DESCR(__pyx_v_self); + __Pyx_INCREF((PyObject *)((PyArray_Descr *)__pyx_t_1)); + __pyx_r = ((PyArray_Descr *)__pyx_t_1); + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":372 + * + * @property + * cdef inline dtype descr(self): # <<<<<<<<<<<<<< + * """Returns an owned reference to the dtype of the array. + * """ + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF((PyObject *)__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":378 + * + * @property + * cdef inline int ndim(self) noexcept nogil: # <<<<<<<<<<<<<< + * """Returns the number of dimensions in the array. + * """ + */ + +static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx_v_self) { + int __pyx_r; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":381 + * """Returns the number of dimensions in the array. + * """ + * return PyArray_NDIM(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_NDIM(__pyx_v_self); + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":378 + * + * @property + * cdef inline int ndim(self) noexcept nogil: # <<<<<<<<<<<<<< + * """Returns the number of dimensions in the array. + * """ + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":384 + * + * @property + * cdef inline npy_intp *shape(self) noexcept nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the dimensions/shape of the array. + * The number of elements matches the number of dimensions of the array (ndim). + */ + +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObject *__pyx_v_self) { + npy_intp *__pyx_r; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":389 + * Can return NULL for 0-dimensional arrays. + * """ + * return PyArray_DIMS(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_DIMS(__pyx_v_self); + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":384 + * + * @property + * cdef inline npy_intp *shape(self) noexcept nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the dimensions/shape of the array. + * The number of elements matches the number of dimensions of the array (ndim). + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":392 + * + * @property + * cdef inline npy_intp *strides(self) noexcept nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the strides of the array. + * The number of elements matches the number of dimensions of the array (ndim). + */ + +static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayObject *__pyx_v_self) { + npy_intp *__pyx_r; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":396 + * The number of elements matches the number of dimensions of the array (ndim). + * """ + * return PyArray_STRIDES(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_STRIDES(__pyx_v_self); + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":392 + * + * @property + * cdef inline npy_intp *strides(self) noexcept nogil: # <<<<<<<<<<<<<< + * """Returns a pointer to the strides of the array. + * The number of elements matches the number of dimensions of the array (ndim). + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":399 + * + * @property + * cdef inline npy_intp size(self) noexcept nogil: # <<<<<<<<<<<<<< + * """Returns the total size (in number of elements) of the array. + * """ + */ + +static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject *__pyx_v_self) { + npy_intp __pyx_r; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":402 + * """Returns the total size (in number of elements) of the array. + * """ + * return PyArray_SIZE(self) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_r = PyArray_SIZE(__pyx_v_self); + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":399 + * + * @property + * cdef inline npy_intp size(self) noexcept nogil: # <<<<<<<<<<<<<< + * """Returns the total size (in number of elements) of the array. + * """ + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":405 + * + * @property + * cdef inline char* data(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The pointer to the data buffer as a char*. + * This is provided for legacy reasons to avoid direct struct field access. + */ + +static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__pyx_v_self) { + char *__pyx_r; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":411 + * of `PyArray_DATA()` instead, which returns a 'void*'. + * """ + * return PyArray_BYTES(self) # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = PyArray_BYTES(__pyx_v_self); + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":405 + * + * @property + * cdef inline char* data(self) noexcept nogil: # <<<<<<<<<<<<<< + * """The pointer to the data buffer as a char*. + * This is provided for legacy reasons to avoid direct struct field access. + */ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":807 + * ctypedef long double complex clongdouble_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 1); + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":808 + * + * cdef inline object PyArray_MultiIterNew1(a): + * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew2(a, b): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 808, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":807 + * ctypedef long double complex clongdouble_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":810 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 1); + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":811 + * + * cdef inline object PyArray_MultiIterNew2(a, b): + * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 811, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":810 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":813 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 1); + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":814 + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 814, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":813 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; @@ -18464,7 +18932,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__ return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":782 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":816 * return PyArray_MultiIterNew(3, a, b, c) * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< @@ -18481,7 +18949,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__ int __pyx_clineno = 0; __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 1); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":783 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":817 * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< @@ -18489,13 +18957,13 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 783, __pyx_L1_error) + __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 817, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":782 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":816 * return PyArray_MultiIterNew(3, a, b, c) * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< @@ -18514,7 +18982,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__ return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":785 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":819 * return PyArray_MultiIterNew(4, a, b, c, d) * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< @@ -18531,7 +18999,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__ int __pyx_clineno = 0; __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 1); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":786 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":820 * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< @@ -18539,13 +19007,13 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__ * cdef inline tuple PyDataType_SHAPE(dtype d): */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 786, __pyx_L1_error) + __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 820, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":785 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":819 * return PyArray_MultiIterNew(4, a, b, c, d) * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< @@ -18564,7 +19032,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__ return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":788 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":822 * return PyArray_MultiIterNew(5, a, b, c, d, e) * * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< @@ -18576,9 +19044,10 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; + PyObject *__pyx_t_2; __Pyx_RefNannySetupContext("PyDataType_SHAPE", 1); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":789 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":823 * * cdef inline tuple PyDataType_SHAPE(dtype d): * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< @@ -18588,7 +19057,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ __pyx_t_1 = PyDataType_HASSUBARRAY(__pyx_v_d); if (__pyx_t_1) { - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":790 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":824 * cdef inline tuple PyDataType_SHAPE(dtype d): * if PyDataType_HASSUBARRAY(d): * return d.subarray.shape # <<<<<<<<<<<<<< @@ -18596,11 +19065,12 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ * return () */ __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject*)__pyx_v_d->subarray->shape)); - __pyx_r = ((PyObject*)__pyx_v_d->subarray->shape); + __pyx_t_2 = __pyx_f_5numpy_5dtype_8subarray_subarray(__pyx_v_d)->shape; + __Pyx_INCREF(((PyObject*)__pyx_t_2)); + __pyx_r = ((PyObject*)__pyx_t_2); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":789 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":823 * * cdef inline tuple PyDataType_SHAPE(dtype d): * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< @@ -18609,7 +19079,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ */ } - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":792 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":826 * return d.subarray.shape * else: * return () # <<<<<<<<<<<<<< @@ -18623,7 +19093,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ goto __pyx_L0; } - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":788 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":822 * return PyArray_MultiIterNew(5, a, b, c, d, e) * * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< @@ -18638,10 +19108,10 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":968 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1010 * int _import_umath() except -1 * - * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * cdef inline void set_array_base(ndarray arr, object base) except *: # <<<<<<<<<<<<<< * Py_INCREF(base) # important to do this before stealing the reference below! * PyArray_SetBaseObject(arr, base) */ @@ -18652,28 +19122,28 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a const char *__pyx_filename = NULL; int __pyx_clineno = 0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":969 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1011 * - * cdef inline void set_array_base(ndarray arr, object base): + * cdef inline void set_array_base(ndarray arr, object base) except *: * Py_INCREF(base) # important to do this before stealing the reference below! # <<<<<<<<<<<<<< * PyArray_SetBaseObject(arr, base) * */ Py_INCREF(__pyx_v_base); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":970 - * cdef inline void set_array_base(ndarray arr, object base): + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1012 + * cdef inline void set_array_base(ndarray arr, object base) except *: * Py_INCREF(base) # important to do this before stealing the reference below! * PyArray_SetBaseObject(arr, base) # <<<<<<<<<<<<<< * * cdef inline object get_array_base(ndarray arr): */ - __pyx_t_1 = PyArray_SetBaseObject(__pyx_v_arr, __pyx_v_base); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(2, 970, __pyx_L1_error) + __pyx_t_1 = PyArray_SetBaseObject(__pyx_v_arr, __pyx_v_base); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(2, 1012, __pyx_L1_error) - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":968 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1010 * int _import_umath() except -1 * - * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * cdef inline void set_array_base(ndarray arr, object base) except *: # <<<<<<<<<<<<<< * Py_INCREF(base) # important to do this before stealing the reference below! * PyArray_SetBaseObject(arr, base) */ @@ -18685,7 +19155,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a __pyx_L0:; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":972 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1014 * PyArray_SetBaseObject(arr, base) * * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< @@ -18700,7 +19170,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py int __pyx_t_1; __Pyx_RefNannySetupContext("get_array_base", 1); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":973 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1015 * * cdef inline object get_array_base(ndarray arr): * base = PyArray_BASE(arr) # <<<<<<<<<<<<<< @@ -18709,7 +19179,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py */ __pyx_v_base = PyArray_BASE(__pyx_v_arr); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":974 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1016 * cdef inline object get_array_base(ndarray arr): * base = PyArray_BASE(arr) * if base is NULL: # <<<<<<<<<<<<<< @@ -18719,7 +19189,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py __pyx_t_1 = (__pyx_v_base == NULL); if (__pyx_t_1) { - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":975 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1017 * base = PyArray_BASE(arr) * if base is NULL: * return None # <<<<<<<<<<<<<< @@ -18730,7 +19200,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":974 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1016 * cdef inline object get_array_base(ndarray arr): * base = PyArray_BASE(arr) * if base is NULL: # <<<<<<<<<<<<<< @@ -18739,7 +19209,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py */ } - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":976 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1018 * if base is NULL: * return None * return base # <<<<<<<<<<<<<< @@ -18751,7 +19221,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py __pyx_r = ((PyObject *)__pyx_v_base); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":972 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1014 * PyArray_SetBaseObject(arr, base) * * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< @@ -18766,7 +19236,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":980 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1022 * # Versions of the import_* functions which are more suitable for * # Cython code. * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< @@ -18790,7 +19260,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { int __pyx_clineno = 0; __Pyx_RefNannySetupContext("import_array", 1); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":981 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1023 * # Cython code. * cdef inline int import_array() except -1: * try: # <<<<<<<<<<<<<< @@ -18806,16 +19276,16 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { __Pyx_XGOTREF(__pyx_t_3); /*try:*/ { - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":982 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1024 * cdef inline int import_array() except -1: * try: * __pyx_import_array() # <<<<<<<<<<<<<< * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") + * raise ImportError("numpy._core.multiarray failed to import") */ - __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 982, __pyx_L3_error) + __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1024, __pyx_L3_error) - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":981 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1023 * # Cython code. * cdef inline int import_array() except -1: * try: # <<<<<<<<<<<<<< @@ -18829,37 +19299,37 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { goto __pyx_L8_try_end; __pyx_L3_error:; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":983 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1025 * try: * __pyx_import_array() * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.multiarray failed to import") + * raise ImportError("numpy._core.multiarray failed to import") * */ __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); if (__pyx_t_4) { __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 983, __pyx_L5_except_error) + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1025, __pyx_L5_except_error) __Pyx_XGOTREF(__pyx_t_5); __Pyx_XGOTREF(__pyx_t_6); __Pyx_XGOTREF(__pyx_t_7); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":984 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1026 * __pyx_import_array() * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + * raise ImportError("numpy._core.multiarray failed to import") # <<<<<<<<<<<<<< * * cdef inline int import_umath() except -1: */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 984, __pyx_L5_except_error) + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1026, __pyx_L5_except_error) __Pyx_GOTREF(__pyx_t_8); __Pyx_Raise(__pyx_t_8, 0, 0, 0); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(2, 984, __pyx_L5_except_error) + __PYX_ERR(2, 1026, __pyx_L5_except_error) } goto __pyx_L5_except_error; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":981 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1023 * # Cython code. * cdef inline int import_array() except -1: * try: # <<<<<<<<<<<<<< @@ -18875,7 +19345,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { __pyx_L8_try_end:; } - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":980 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1022 * # Versions of the import_* functions which are more suitable for * # Cython code. * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< @@ -18898,8 +19368,8 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":986 - * raise ImportError("numpy.core.multiarray failed to import") +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1028 + * raise ImportError("numpy._core.multiarray failed to import") * * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< * try: @@ -18922,7 +19392,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { int __pyx_clineno = 0; __Pyx_RefNannySetupContext("import_umath", 1); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":987 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1029 * * cdef inline int import_umath() except -1: * try: # <<<<<<<<<<<<<< @@ -18938,16 +19408,16 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { __Pyx_XGOTREF(__pyx_t_3); /*try:*/ { - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":988 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1030 * cdef inline int import_umath() except -1: * try: * _import_umath() # <<<<<<<<<<<<<< * except Exception: - * raise ImportError("numpy.core.umath failed to import") + * raise ImportError("numpy._core.umath failed to import") */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 988, __pyx_L3_error) + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1030, __pyx_L3_error) - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":987 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1029 * * cdef inline int import_umath() except -1: * try: # <<<<<<<<<<<<<< @@ -18961,37 +19431,37 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { goto __pyx_L8_try_end; __pyx_L3_error:; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":989 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1031 * try: * _import_umath() * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.umath failed to import") + * raise ImportError("numpy._core.umath failed to import") * */ __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); if (__pyx_t_4) { __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 989, __pyx_L5_except_error) + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1031, __pyx_L5_except_error) __Pyx_XGOTREF(__pyx_t_5); __Pyx_XGOTREF(__pyx_t_6); __Pyx_XGOTREF(__pyx_t_7); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":990 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1032 * _import_umath() * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * raise ImportError("numpy._core.umath failed to import") # <<<<<<<<<<<<<< * * cdef inline int import_ufunc() except -1: */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 990, __pyx_L5_except_error) + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1032, __pyx_L5_except_error) __Pyx_GOTREF(__pyx_t_8); __Pyx_Raise(__pyx_t_8, 0, 0, 0); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(2, 990, __pyx_L5_except_error) + __PYX_ERR(2, 1032, __pyx_L5_except_error) } goto __pyx_L5_except_error; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":987 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1029 * * cdef inline int import_umath() except -1: * try: # <<<<<<<<<<<<<< @@ -19007,8 +19477,8 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { __pyx_L8_try_end:; } - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":986 - * raise ImportError("numpy.core.multiarray failed to import") + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1028 + * raise ImportError("numpy._core.multiarray failed to import") * * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< * try: @@ -19030,8 +19500,8 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":992 - * raise ImportError("numpy.core.umath failed to import") +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1034 + * raise ImportError("numpy._core.umath failed to import") * * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< * try: @@ -19054,7 +19524,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { int __pyx_clineno = 0; __Pyx_RefNannySetupContext("import_ufunc", 1); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":993 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1035 * * cdef inline int import_ufunc() except -1: * try: # <<<<<<<<<<<<<< @@ -19070,16 +19540,16 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { __Pyx_XGOTREF(__pyx_t_3); /*try:*/ { - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":994 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1036 * cdef inline int import_ufunc() except -1: * try: * _import_umath() # <<<<<<<<<<<<<< * except Exception: - * raise ImportError("numpy.core.umath failed to import") + * raise ImportError("numpy._core.umath failed to import") */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 994, __pyx_L3_error) + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1036, __pyx_L3_error) - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":993 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1035 * * cdef inline int import_ufunc() except -1: * try: # <<<<<<<<<<<<<< @@ -19093,37 +19563,37 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { goto __pyx_L8_try_end; __pyx_L3_error:; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":995 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1037 * try: * _import_umath() * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.umath failed to import") + * raise ImportError("numpy._core.umath failed to import") * */ __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); if (__pyx_t_4) { __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 995, __pyx_L5_except_error) + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1037, __pyx_L5_except_error) __Pyx_XGOTREF(__pyx_t_5); __Pyx_XGOTREF(__pyx_t_6); __Pyx_XGOTREF(__pyx_t_7); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":996 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1038 * _import_umath() * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * raise ImportError("numpy._core.umath failed to import") # <<<<<<<<<<<<<< * * */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 996, __pyx_L5_except_error) + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1038, __pyx_L5_except_error) __Pyx_GOTREF(__pyx_t_8); __Pyx_Raise(__pyx_t_8, 0, 0, 0); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(2, 996, __pyx_L5_except_error) + __PYX_ERR(2, 1038, __pyx_L5_except_error) } goto __pyx_L5_except_error; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":993 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1035 * * cdef inline int import_ufunc() except -1: * try: # <<<<<<<<<<<<<< @@ -19139,8 +19609,8 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { __pyx_L8_try_end:; } - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":992 - * raise ImportError("numpy.core.umath failed to import") + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1034 + * raise ImportError("numpy._core.umath failed to import") * * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< * try: @@ -19162,10 +19632,10 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":999 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1041 * * - * cdef inline bint is_timedelta64_object(object obj): # <<<<<<<<<<<<<< + * cdef inline bint is_timedelta64_object(object obj) noexcept: # <<<<<<<<<<<<<< * """ * Cython equivalent of `isinstance(obj, np.timedelta64)` */ @@ -19173,7 +19643,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_obj) { int __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1011 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1053 * bool * """ * return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type) # <<<<<<<<<<<<<< @@ -19183,10 +19653,10 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_ __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyTimedeltaArrType_Type)); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":999 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1041 * * - * cdef inline bint is_timedelta64_object(object obj): # <<<<<<<<<<<<<< + * cdef inline bint is_timedelta64_object(object obj) noexcept: # <<<<<<<<<<<<<< * """ * Cython equivalent of `isinstance(obj, np.timedelta64)` */ @@ -19196,10 +19666,10 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_ return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1014 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1056 * * - * cdef inline bint is_datetime64_object(object obj): # <<<<<<<<<<<<<< + * cdef inline bint is_datetime64_object(object obj) noexcept: # <<<<<<<<<<<<<< * """ * Cython equivalent of `isinstance(obj, np.datetime64)` */ @@ -19207,7 +19677,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_ static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_obj) { int __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1026 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1068 * bool * """ * return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type) # <<<<<<<<<<<<<< @@ -19217,10 +19687,10 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_o __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyDatetimeArrType_Type)); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1014 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1056 * * - * cdef inline bint is_datetime64_object(object obj): # <<<<<<<<<<<<<< + * cdef inline bint is_datetime64_object(object obj) noexcept: # <<<<<<<<<<<<<< * """ * Cython equivalent of `isinstance(obj, np.datetime64)` */ @@ -19230,10 +19700,10 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_o return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1029 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1071 * * - * cdef inline npy_datetime get_datetime64_value(object obj) nogil: # <<<<<<<<<<<<<< + * cdef inline npy_datetime get_datetime64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< * """ * returns the int64 value underlying scalar numpy datetime64 object */ @@ -19241,7 +19711,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_o static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject *__pyx_v_obj) { npy_datetime __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1036 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1078 * also needed. That can be found using `get_datetime64_unit`. * """ * return (obj).obval # <<<<<<<<<<<<<< @@ -19251,10 +19721,10 @@ static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject * __pyx_r = ((PyDatetimeScalarObject *)__pyx_v_obj)->obval; goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1029 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1071 * * - * cdef inline npy_datetime get_datetime64_value(object obj) nogil: # <<<<<<<<<<<<<< + * cdef inline npy_datetime get_datetime64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< * """ * returns the int64 value underlying scalar numpy datetime64 object */ @@ -19264,10 +19734,10 @@ static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject * return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1039 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1081 * * - * cdef inline npy_timedelta get_timedelta64_value(object obj) nogil: # <<<<<<<<<<<<<< + * cdef inline npy_timedelta get_timedelta64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< * """ * returns the int64 value underlying scalar numpy timedelta64 object */ @@ -19275,7 +19745,7 @@ static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject * static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject *__pyx_v_obj) { npy_timedelta __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1043 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1085 * returns the int64 value underlying scalar numpy timedelta64 object * """ * return (obj).obval # <<<<<<<<<<<<<< @@ -19285,10 +19755,10 @@ static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject __pyx_r = ((PyTimedeltaScalarObject *)__pyx_v_obj)->obval; goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1039 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1081 * * - * cdef inline npy_timedelta get_timedelta64_value(object obj) nogil: # <<<<<<<<<<<<<< + * cdef inline npy_timedelta get_timedelta64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< * """ * returns the int64 value underlying scalar numpy timedelta64 object */ @@ -19298,10 +19768,10 @@ static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject return __pyx_r; } -/* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1046 +/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1088 * * - * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil: # <<<<<<<<<<<<<< + * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) noexcept nogil: # <<<<<<<<<<<<<< * """ * returns the unit part of the dtype for a numpy datetime64 object. */ @@ -19309,18 +19779,20 @@ static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject static CYTHON_INLINE NPY_DATETIMEUNIT __pyx_f_5numpy_get_datetime64_unit(PyObject *__pyx_v_obj) { NPY_DATETIMEUNIT __pyx_r; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1050 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1092 * returns the unit part of the dtype for a numpy datetime64 object. * """ * return (obj).obmeta.base # <<<<<<<<<<<<<< + * + * */ __pyx_r = ((NPY_DATETIMEUNIT)((PyDatetimeScalarObject *)__pyx_v_obj)->obmeta.base); goto __pyx_L0; - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":1046 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1088 * * - * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil: # <<<<<<<<<<<<<< + * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) noexcept nogil: # <<<<<<<<<<<<<< * """ * returns the unit part of the dtype for a numpy datetime64 object. */ @@ -19511,7 +19983,7 @@ static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTH double __pyx_v_mu; double __pyx_v_max_cdf; double __pyx_v_new_cdf; - double __pyx_v_total_rate; + CYTHON_UNUSED double __pyx_v_total_rate; int __pyx_v_safe; int __pyx_v_count; double __pyx_v_cdf_val; @@ -19526,14 +19998,14 @@ static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTH PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations __Pyx_memviewslice __pyx_t_1 = { 0, 0, { 0 }, { 0 }, { 0 } }; - npy_intp *__pyx_t_2; - __Pyx_memviewslice __pyx_t_3 = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_t_2 = { 0, 0, { 0 }, { 0 }, { 0 } }; + PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; - double __pyx_t_8; - int __pyx_t_9; + int __pyx_t_6; + double __pyx_t_7; + int __pyx_t_8; + __pyx_t_5numpy_int64_t __pyx_t_9; __pyx_t_5numpy_int64_t __pyx_t_10; __pyx_t_5numpy_int64_t __pyx_t_11; __pyx_t_5numpy_int64_t __pyx_t_12; @@ -19541,8 +20013,6 @@ static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTH __pyx_t_5numpy_int64_t __pyx_t_14; __pyx_t_5numpy_int64_t __pyx_t_15; __pyx_t_5numpy_int64_t __pyx_t_16; - __pyx_t_5numpy_int64_t __pyx_t_17; - int __pyx_t_18; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; @@ -19594,8 +20064,7 @@ static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTH * cdef double[:] x_view = x * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat */ - __pyx_t_2 = __pyx_f_5numpy_7ndarray_5shape_shape(((PyArrayObject *)__pyx_v_rates)); if (unlikely(__pyx_t_2 == ((npy_intp *)NULL) && PyErr_Occurred())) __PYX_ERR(0, 24, __pyx_L1_error) - __pyx_v_n_rates = (__pyx_t_2[0]); + __pyx_v_n_rates = (__pyx_f_5numpy_7ndarray_5shape_shape(((PyArrayObject *)__pyx_v_rates))[0]); /* "pygom/model/_tau_leap.pyx":25 * cdef double[:] rates_view = rates @@ -19616,10 +20085,10 @@ static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTH * cdef np.int64_t n_reactants = reactant_mat.shape[0] * */ - __pyx_t_3 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int64_t(((PyObject *)__pyx_v_reactant_mat), PyBUF_WRITABLE); if (unlikely(!__pyx_t_3.memview)) __PYX_ERR(0, 26, __pyx_L1_error) - __pyx_v_reactant_mat_view = __pyx_t_3; - __pyx_t_3.memview = NULL; - __pyx_t_3.data = NULL; + __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int64_t(((PyObject *)__pyx_v_reactant_mat), PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 26, __pyx_L1_error) + __pyx_v_reactant_mat_view = __pyx_t_2; + __pyx_t_2.memview = NULL; + __pyx_t_2.data = NULL; /* "pygom/model/_tau_leap.pyx":27 * cdef double[:] x_view = x @@ -19628,205 +20097,176 @@ static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTH * * cdef double mu, max_cdf, new_cdf */ - __pyx_t_2 = __pyx_f_5numpy_7ndarray_5shape_shape(((PyArrayObject *)__pyx_v_reactant_mat)); if (unlikely(__pyx_t_2 == ((npy_intp *)NULL) && PyErr_Occurred())) __PYX_ERR(0, 27, __pyx_L1_error) - __pyx_v_n_reactants = (__pyx_t_2[0]); + __pyx_v_n_reactants = (__pyx_f_5numpy_7ndarray_5shape_shape(((PyArrayObject *)__pyx_v_reactant_mat))[0]); /* "pygom/model/_tau_leap.pyx":30 * * cdef double mu, max_cdf, new_cdf * cdef double total_rate = np.sum(rates) # <<<<<<<<<<<<<< - * safe = False - * cdef int count = 0 + * safe = False # when True, indicates that tau_scale is sufficiently small + * cdef int count = 0 # number of attempts to find acceptable tau_scale */ - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_sum); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 30, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_sum); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = NULL; - __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = NULL; + __pyx_t_6 = 0; #if CYTHON_UNPACK_METHODS - if (unlikely(PyMethod_Check(__pyx_t_6))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); - __Pyx_INCREF(__pyx_t_5); + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_6, function); - __pyx_t_7 = 1; + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_6 = 1; } } #endif { - PyObject *__pyx_callargs[2] = {__pyx_t_5, ((PyObject *)__pyx_v_rates)}; - __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + PyObject *__pyx_callargs[2] = {__pyx_t_4, ((PyObject *)__pyx_v_rates)}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } - __pyx_t_8 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_v_total_rate = __pyx_t_8; + __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_total_rate = __pyx_t_7; /* "pygom/model/_tau_leap.pyx":31 * cdef double mu, max_cdf, new_cdf * cdef double total_rate = np.sum(rates) - * safe = False # <<<<<<<<<<<<<< - * cdef int count = 0 + * safe = False # when True, indicates that tau_scale is sufficiently small # <<<<<<<<<<<<<< + * cdef int count = 0 # number of attempts to find acceptable tau_scale * while safe is False: */ __pyx_v_safe = 0; /* "pygom/model/_tau_leap.pyx":32 * cdef double total_rate = np.sum(rates) - * safe = False - * cdef int count = 0 # <<<<<<<<<<<<<< + * safe = False # when True, indicates that tau_scale is sufficiently small + * cdef int count = 0 # number of attempts to find acceptable tau_scale # <<<<<<<<<<<<<< * while safe is False: - * cdf_val = 1.0 + * # print(count) */ __pyx_v_count = 0; /* "pygom/model/_tau_leap.pyx":33 - * safe = False - * cdef int count = 0 + * safe = False # when True, indicates that tau_scale is sufficiently small + * cdef int count = 0 # number of attempts to find acceptable tau_scale * while safe is False: # <<<<<<<<<<<<<< - * cdf_val = 1.0 - * for i in range(n_rates): + * # print(count) + * # print(tau_scale) */ while (1) { - __pyx_t_9 = (__pyx_v_safe == 0); - if (!__pyx_t_9) break; + __pyx_t_8 = (__pyx_v_safe == 0); + if (!__pyx_t_8) break; - /* "pygom/model/_tau_leap.pyx":34 - * cdef int count = 0 - * while safe is False: + /* "pygom/model/_tau_leap.pyx":36 + * # print(count) + * # print(tau_scale) * cdf_val = 1.0 # <<<<<<<<<<<<<< - * for i in range(n_rates): - * #xi = x[reactant_mat[:, i]] + * for i in range(n_rates): # loop over transitions, i + * for j in range(n_reactants): # loop over states, j */ __pyx_v_cdf_val = 1.0; - /* "pygom/model/_tau_leap.pyx":35 - * while safe is False: + /* "pygom/model/_tau_leap.pyx":37 + * # print(tau_scale) * cdf_val = 1.0 - * for i in range(n_rates): # <<<<<<<<<<<<<< - * #xi = x[reactant_mat[:, i]] - * #new_cdf = _ppois(xi, mu=tau_scale*r).min() + * for i in range(n_rates): # loop over transitions, i # <<<<<<<<<<<<<< + * for j in range(n_reactants): # loop over states, j + * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? */ - __pyx_t_10 = __pyx_v_n_rates; - __pyx_t_11 = __pyx_t_10; - for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) { - __pyx_v_i = __pyx_t_12; + __pyx_t_9 = __pyx_v_n_rates; + __pyx_t_10 = __pyx_t_9; + for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { + __pyx_v_i = __pyx_t_11; /* "pygom/model/_tau_leap.pyx":38 - * #xi = x[reactant_mat[:, i]] - * #new_cdf = _ppois(xi, mu=tau_scale*r).min() - * for j in range(n_reactants): # <<<<<<<<<<<<<< - * if reactant_mat_view[j, i] == 1: - * mu = rates_view[i] * tau_scale + * cdf_val = 1.0 + * for i in range(n_rates): # loop over transitions, i + * for j in range(n_reactants): # loop over states, j # <<<<<<<<<<<<<< + * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? + * mu = rates_view[i] * tau_scale # expected number of events for transition i */ - __pyx_t_13 = __pyx_v_n_reactants; - __pyx_t_14 = __pyx_t_13; - for (__pyx_t_15 = 0; __pyx_t_15 < __pyx_t_14; __pyx_t_15+=1) { - __pyx_v_j = __pyx_t_15; + __pyx_t_12 = __pyx_v_n_reactants; + __pyx_t_13 = __pyx_t_12; + for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { + __pyx_v_j = __pyx_t_14; /* "pygom/model/_tau_leap.pyx":39 - * #new_cdf = _ppois(xi, mu=tau_scale*r).min() - * for j in range(n_reactants): - * if reactant_mat_view[j, i] == 1: # <<<<<<<<<<<<<< - * mu = rates_view[i] * tau_scale - * new_cdf = csc.pdtr(floor(x_view[i]), mu) + * for i in range(n_rates): # loop over transitions, i + * for j in range(n_reactants): # loop over states, j + * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? # <<<<<<<<<<<<<< + * mu = rates_view[i] * tau_scale # expected number of events for transition i + * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop */ - __pyx_t_16 = __pyx_v_j; - __pyx_t_17 = __pyx_v_i; - __pyx_t_9 = ((*((__pyx_t_5numpy_int64_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_reactant_mat_view.data + __pyx_t_16 * __pyx_v_reactant_mat_view.strides[0]) ) + __pyx_t_17 * __pyx_v_reactant_mat_view.strides[1]) ))) == 1); - if (__pyx_t_9) { + __pyx_t_15 = __pyx_v_j; + __pyx_t_16 = __pyx_v_i; + __pyx_t_8 = ((*((__pyx_t_5numpy_int64_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_reactant_mat_view.data + __pyx_t_15 * __pyx_v_reactant_mat_view.strides[0]) ) + __pyx_t_16 * __pyx_v_reactant_mat_view.strides[1]) ))) == 1); + if (__pyx_t_8) { /* "pygom/model/_tau_leap.pyx":40 - * for j in range(n_reactants): - * if reactant_mat_view[j, i] == 1: - * mu = rates_view[i] * tau_scale # <<<<<<<<<<<<<< - * new_cdf = csc.pdtr(floor(x_view[i]), mu) - * if new_cdf < cdf_val: + * for j in range(n_reactants): # loop over states, j + * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? + * mu = rates_view[i] * tau_scale # expected number of events for transition i # <<<<<<<<<<<<<< + * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop + * if new_cdf < cdf_val: */ - __pyx_t_17 = __pyx_v_i; - __pyx_v_mu = ((*((double *) ( /* dim=0 */ (__pyx_v_rates_view.data + __pyx_t_17 * __pyx_v_rates_view.strides[0]) ))) * __pyx_v_tau_scale); + __pyx_t_16 = __pyx_v_i; + __pyx_v_mu = ((*((double *) ( /* dim=0 */ (__pyx_v_rates_view.data + __pyx_t_16 * __pyx_v_rates_view.strides[0]) ))) * __pyx_v_tau_scale); /* "pygom/model/_tau_leap.pyx":41 - * if reactant_mat_view[j, i] == 1: - * mu = rates_view[i] * tau_scale - * new_cdf = csc.pdtr(floor(x_view[i]), mu) # <<<<<<<<<<<<<< - * if new_cdf < cdf_val: - * cdf_val = new_cdf - */ - __pyx_t_17 = __pyx_v_i; - __pyx_v_new_cdf = __pyx_f_5scipy_7special_14cython_special_pdtr(floor((*((double *) ( /* dim=0 */ (__pyx_v_x_view.data + __pyx_t_17 * __pyx_v_x_view.strides[0]) )))), __pyx_v_mu, 0); - - /* "pygom/model/_tau_leap.pyx":39 - * #new_cdf = _ppois(xi, mu=tau_scale*r).min() - * for j in range(n_reactants): - * if reactant_mat_view[j, i] == 1: # <<<<<<<<<<<<<< - * mu = rates_view[i] * tau_scale - * new_cdf = csc.pdtr(floor(x_view[i]), mu) - */ - } - - /* "pygom/model/_tau_leap.pyx":42 - * mu = rates_view[i] * tau_scale - * new_cdf = csc.pdtr(floor(x_view[i]), mu) - * if new_cdf < cdf_val: # <<<<<<<<<<<<<< - * cdf_val = new_cdf - * if new_cdf < cdf_val: - */ - __pyx_t_9 = (__pyx_v_new_cdf < __pyx_v_cdf_val); - if (__pyx_t_9) { - - /* "pygom/model/_tau_leap.pyx":43 - * new_cdf = csc.pdtr(floor(x_view[i]), mu) - * if new_cdf < cdf_val: - * cdf_val = new_cdf # <<<<<<<<<<<<<< - * if new_cdf < cdf_val: - * cdf_val = new_cdf + * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? + * mu = rates_view[i] * tau_scale # expected number of events for transition i + * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop # <<<<<<<<<<<<<< + * if new_cdf < cdf_val: + * cdf_val = new_cdf */ - __pyx_v_cdf_val = __pyx_v_new_cdf; + __pyx_t_16 = __pyx_v_j; + __pyx_v_new_cdf = __pyx_f_5scipy_7special_14cython_special_pdtr(floor((*((double *) ( /* dim=0 */ (__pyx_v_x_view.data + __pyx_t_16 * __pyx_v_x_view.strides[0]) )))), __pyx_v_mu, 0); /* "pygom/model/_tau_leap.pyx":42 - * mu = rates_view[i] * tau_scale - * new_cdf = csc.pdtr(floor(x_view[i]), mu) - * if new_cdf < cdf_val: # <<<<<<<<<<<<<< - * cdf_val = new_cdf - * if new_cdf < cdf_val: - */ - } - } - - /* "pygom/model/_tau_leap.pyx":44 - * if new_cdf < cdf_val: - * cdf_val = new_cdf - * if new_cdf < cdf_val: # <<<<<<<<<<<<<< - * cdf_val = new_cdf - * #cdf_val[i * reactant_mat.shape[0] : (i * reactant_mat.shape[0]) + len(rates)] = _ppois(xi, mu=tau_scale*r) + * mu = rates_view[i] * tau_scale # expected number of events for transition i + * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop + * if new_cdf < cdf_val: # <<<<<<<<<<<<<< + * cdf_val = new_cdf + * # if new_cdf < cdf_val: # think this extra condition is redundant + */ + __pyx_t_8 = (__pyx_v_new_cdf < __pyx_v_cdf_val); + if (__pyx_t_8) { + + /* "pygom/model/_tau_leap.pyx":43 + * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop + * if new_cdf < cdf_val: + * cdf_val = new_cdf # <<<<<<<<<<<<<< + * # if new_cdf < cdf_val: # think this extra condition is redundant + * # cdf_val = new_cdf + */ + __pyx_v_cdf_val = __pyx_v_new_cdf; + + /* "pygom/model/_tau_leap.pyx":42 + * mu = rates_view[i] * tau_scale # expected number of events for transition i + * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop + * if new_cdf < cdf_val: # <<<<<<<<<<<<<< + * cdf_val = new_cdf + * # if new_cdf < cdf_val: # think this extra condition is redundant */ - __pyx_t_9 = (__pyx_v_new_cdf < __pyx_v_cdf_val); - if (__pyx_t_9) { - - /* "pygom/model/_tau_leap.pyx":45 - * cdf_val = new_cdf - * if new_cdf < cdf_val: - * cdf_val = new_cdf # <<<<<<<<<<<<<< - * #cdf_val[i * reactant_mat.shape[0] : (i * reactant_mat.shape[0]) + len(rates)] = _ppois(xi, mu=tau_scale*r) - * - */ - __pyx_v_cdf_val = __pyx_v_new_cdf; + } - /* "pygom/model/_tau_leap.pyx":44 - * if new_cdf < cdf_val: - * cdf_val = new_cdf - * if new_cdf < cdf_val: # <<<<<<<<<<<<<< - * cdf_val = new_cdf - * #cdf_val[i * reactant_mat.shape[0] : (i * reactant_mat.shape[0]) + len(rates)] = _ppois(xi, mu=tau_scale*r) + /* "pygom/model/_tau_leap.pyx":39 + * for i in range(n_rates): # loop over transitions, i + * for j in range(n_reactants): # loop over states, j + * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? # <<<<<<<<<<<<<< + * mu = rates_view[i] * tau_scale # expected number of events for transition i + * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop */ + } } } @@ -19834,22 +20274,22 @@ static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTH * * # the expected probability that our jump will exceed the value * max_cdf = 1.0 - cdf_val # <<<<<<<<<<<<<< + * # print(max_cdf) * # cannot allow it to exceed out epsilon - * if max_cdf > epsilon: */ __pyx_v_max_cdf = (1.0 - __pyx_v_cdf_val); - /* "pygom/model/_tau_leap.pyx":51 - * max_cdf = 1.0 - cdf_val + /* "pygom/model/_tau_leap.pyx":52 + * # print(max_cdf) * # cannot allow it to exceed out epsilon * if max_cdf > epsilon: # <<<<<<<<<<<<<< * tau_scale /= (max_cdf / epsilon) * else: */ - __pyx_t_9 = (__pyx_v_max_cdf > __pyx_v_epsilon); - if (__pyx_t_9) { + __pyx_t_8 = (__pyx_v_max_cdf > __pyx_v_epsilon); + if (__pyx_t_8) { - /* "pygom/model/_tau_leap.pyx":52 + /* "pygom/model/_tau_leap.pyx":53 * # cannot allow it to exceed out epsilon * if max_cdf > epsilon: * tau_scale /= (max_cdf / epsilon) # <<<<<<<<<<<<<< @@ -19858,70 +20298,73 @@ static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTH */ __pyx_v_tau_scale = (__pyx_v_tau_scale / (__pyx_v_max_cdf / __pyx_v_epsilon)); - /* "pygom/model/_tau_leap.pyx":51 - * max_cdf = 1.0 - cdf_val + /* "pygom/model/_tau_leap.pyx":52 + * # print(max_cdf) * # cannot allow it to exceed out epsilon * if max_cdf > epsilon: # <<<<<<<<<<<<<< * tau_scale /= (max_cdf / epsilon) * else: */ - goto __pyx_L12; + goto __pyx_L11; } - /* "pygom/model/_tau_leap.pyx":54 + /* "pygom/model/_tau_leap.pyx":55 * tau_scale /= (max_cdf / epsilon) * else: * safe = True # <<<<<<<<<<<<<< * - * if tau_scale*total_rate <= 1.0 or count > 256: + * if count > 256: */ /*else*/ { __pyx_v_safe = 1; } - __pyx_L12:; + __pyx_L11:; - /* "pygom/model/_tau_leap.pyx":56 + /* "pygom/model/_tau_leap.pyx":57 * safe = True * - * if tau_scale*total_rate <= 1.0 or count > 256: # <<<<<<<<<<<<<< + * if count > 256: # <<<<<<<<<<<<<< + * print("count error") * return False - * count += 1 */ - __pyx_t_18 = ((__pyx_v_tau_scale * __pyx_v_total_rate) <= 1.0); - if (!__pyx_t_18) { - } else { - __pyx_t_9 = __pyx_t_18; - goto __pyx_L14_bool_binop_done; - } - __pyx_t_18 = (__pyx_v_count > 0x100); - __pyx_t_9 = __pyx_t_18; - __pyx_L14_bool_binop_done:; - if (__pyx_t_9) { + __pyx_t_8 = (__pyx_v_count > 0x100); + if (__pyx_t_8) { - /* "pygom/model/_tau_leap.pyx":57 + /* "pygom/model/_tau_leap.pyx":58 + * + * if count > 256: + * print("count error") # <<<<<<<<<<<<<< + * return False * - * if tau_scale*total_rate <= 1.0 or count > 256: + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "pygom/model/_tau_leap.pyx":59 + * if count > 256: + * print("count error") * return False # <<<<<<<<<<<<<< - * count += 1 * + * # if tau_scale*total_rate <= 1.0: # leave out Gillespie regime catch for now */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_False); __pyx_r = Py_False; goto __pyx_L0; - /* "pygom/model/_tau_leap.pyx":56 + /* "pygom/model/_tau_leap.pyx":57 * safe = True * - * if tau_scale*total_rate <= 1.0 or count > 256: # <<<<<<<<<<<<<< + * if count > 256: # <<<<<<<<<<<<<< + * print("count error") * return False - * count += 1 */ } - /* "pygom/model/_tau_leap.pyx":58 - * if tau_scale*total_rate <= 1.0 or count > 256: - * return False + /* "pygom/model/_tau_leap.pyx":64 + * # print("scale error") + * # return False * count += 1 # <<<<<<<<<<<<<< * * return tau_scale, True @@ -19929,24 +20372,24 @@ static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTH __pyx_v_count = (__pyx_v_count + 1); } - /* "pygom/model/_tau_leap.pyx":60 + /* "pygom/model/_tau_leap.pyx":66 * count += 1 * * return tau_scale, True # <<<<<<<<<<<<<< */ __Pyx_XDECREF(__pyx_r); - __pyx_t_4 = PyFloat_FromDouble(__pyx_v_tau_scale); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_4); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4)) __PYX_ERR(0, 60, __pyx_L1_error); + __pyx_t_3 = PyFloat_FromDouble(__pyx_v_tau_scale); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3)) __PYX_ERR(0, 66, __pyx_L1_error); __Pyx_INCREF(Py_True); __Pyx_GIVEREF(Py_True); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, Py_True)) __PYX_ERR(0, 60, __pyx_L1_error); - __pyx_t_4 = 0; - __pyx_r = __pyx_t_6; - __pyx_t_6 = 0; + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, Py_True)) __PYX_ERR(0, 66, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; goto __pyx_L0; /* "pygom/model/_tau_leap.pyx":8 @@ -19960,10 +20403,10 @@ static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTH /* function exit code */ __pyx_L1_error:; __PYX_XCLEAR_MEMVIEW(&__pyx_t_1, 1); - __PYX_XCLEAR_MEMVIEW(&__pyx_t_3, 1); + __PYX_XCLEAR_MEMVIEW(&__pyx_t_2, 1); + __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; __Pyx_PyThreadState_declare __Pyx_PyThreadState_assign @@ -20983,7 +21426,7 @@ static int __Pyx_CreateStringTabAndInitStrings(void) { {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, {&__pyx_n_s_View_MemoryView, __pyx_k_View_MemoryView, sizeof(__pyx_k_View_MemoryView), 0, 0, 1, 1}, {&__pyx_kp_u__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 1, 0, 0}, - {&__pyx_n_s__24, __pyx_k__24, sizeof(__pyx_k__24), 0, 0, 1, 1}, + {&__pyx_n_s__25, __pyx_k__25, sizeof(__pyx_k__25), 0, 0, 1, 1}, {&__pyx_n_s__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 0, 1, 1}, {&__pyx_kp_u__6, __pyx_k__6, sizeof(__pyx_k__6), 0, 1, 0, 0}, {&__pyx_kp_u__7, __pyx_k__7, sizeof(__pyx_k__7), 0, 1, 0, 0}, @@ -21003,6 +21446,7 @@ static int __Pyx_CreateStringTabAndInitStrings(void) { {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0}, {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0}, {&__pyx_n_s_count, __pyx_k_count, sizeof(__pyx_k_count), 0, 0, 1, 1}, + {&__pyx_kp_s_count_error, __pyx_k_count_error, sizeof(__pyx_k_count_error), 0, 0, 1, 0}, {&__pyx_n_s_cy_test_tau_leap_safety, __pyx_k_cy_test_tau_leap_safety, sizeof(__pyx_k_cy_test_tau_leap_safety), 0, 0, 1, 1}, {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, {&__pyx_kp_u_disable, __pyx_k_disable, sizeof(__pyx_k_disable), 0, 1, 0, 0}, @@ -21045,11 +21489,12 @@ static int __Pyx_CreateStringTabAndInitStrings(void) { {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, - {&__pyx_kp_s_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 0, 1, 0}, - {&__pyx_kp_s_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 0, 1, 0}, + {&__pyx_kp_s_numpy__core_multiarray_failed_to, __pyx_k_numpy__core_multiarray_failed_to, sizeof(__pyx_k_numpy__core_multiarray_failed_to), 0, 0, 1, 0}, + {&__pyx_kp_s_numpy__core_umath_failed_to_impo, __pyx_k_numpy__core_umath_failed_to_impo, sizeof(__pyx_k_numpy__core_umath_failed_to_impo), 0, 0, 1, 0}, {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1}, {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1}, {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, + {&__pyx_n_s_print, __pyx_k_print, sizeof(__pyx_k_print), 0, 0, 1, 1}, {&__pyx_n_s_pygom_model__tau_leap, __pyx_k_pygom_model__tau_leap, sizeof(__pyx_k_pygom_model__tau_leap), 0, 0, 1, 1}, {&__pyx_kp_s_pygom_model__tau_leap_pyx, __pyx_k_pygom_model__tau_leap_pyx, sizeof(__pyx_k_pygom_model__tau_leap_pyx), 0, 0, 1, 0}, {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, @@ -21100,7 +21545,8 @@ static int __Pyx_CreateStringTabAndInitStrings(void) { } /* #### Code section: cached_builtins ### */ static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 35, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 37, __pyx_L1_error) + __pyx_builtin_print = __Pyx_GetBuiltinName(__pyx_n_s_print); if (!__pyx_builtin_print) __PYX_ERR(0, 58, __pyx_L1_error) __pyx_builtin___import__ = __Pyx_GetBuiltinName(__pyx_n_s_import); if (!__pyx_builtin___import__) __PYX_ERR(1, 100, __pyx_L1_error) __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 141, __pyx_L1_error) __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(1, 156, __pyx_L1_error) @@ -21110,7 +21556,7 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) __PYX_ERR(1, 408, __pyx_L1_error) __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(1, 618, __pyx_L1_error) __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(1, 914, __pyx_L1_error) - __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(2, 984, __pyx_L1_error) + __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(2, 1026, __pyx_L1_error) return 0; __pyx_L1_error:; return -1; @@ -21157,28 +21603,39 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { __Pyx_GOTREF(__pyx_tuple__8); __Pyx_GIVEREF(__pyx_tuple__8); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":984 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1026 * __pyx_import_array() * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + * raise ImportError("numpy._core.multiarray failed to import") # <<<<<<<<<<<<<< * * cdef inline int import_umath() except -1: */ - __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_multiarray_failed_to); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(2, 984, __pyx_L1_error) + __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_numpy__core_multiarray_failed_to); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(2, 1026, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__9); __Pyx_GIVEREF(__pyx_tuple__9); - /* "../Anaconda3/envs/pygom_development/lib/site-packages/numpy/__init__.cython-30.pxd":990 + /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1032 * _import_umath() * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * raise ImportError("numpy._core.umath failed to import") # <<<<<<<<<<<<<< * * cdef inline int import_ufunc() except -1: */ - __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(2, 990, __pyx_L1_error) + __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_numpy__core_umath_failed_to_impo); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(2, 1032, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__10); __Pyx_GIVEREF(__pyx_tuple__10); + /* "pygom/model/_tau_leap.pyx":58 + * + * if count > 256: + * print("count error") # <<<<<<<<<<<<<< + * return False + * + */ + __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_count_error); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__11); + __Pyx_GIVEREF(__pyx_tuple__11); + /* "View.MemoryView":100 * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" * try: @@ -21186,12 +21643,12 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence * else: */ - __pyx_tuple__11 = PyTuple_Pack(1, __pyx_n_s_sys); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(1, 100, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__11); - __Pyx_GIVEREF(__pyx_tuple__11); - __pyx_tuple__12 = PyTuple_Pack(2, __pyx_int_3, __pyx_int_3); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(1, 100, __pyx_L1_error) + __pyx_tuple__12 = PyTuple_Pack(1, __pyx_n_s_sys); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(1, 100, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__12); __Pyx_GIVEREF(__pyx_tuple__12); + __pyx_tuple__13 = PyTuple_Pack(2, __pyx_int_3, __pyx_int_3); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(1, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__13); + __Pyx_GIVEREF(__pyx_tuple__13); /* "View.MemoryView":101 * try: @@ -21200,9 +21657,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * else: * __pyx_collections_abc_Sequence = __import__("collections").Sequence */ - __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_collections_abc); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(1, 101, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__13); - __Pyx_GIVEREF(__pyx_tuple__13); + __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_collections_abc); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(1, 101, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__14); + __Pyx_GIVEREF(__pyx_tuple__14); /* "View.MemoryView":103 * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence @@ -21211,9 +21668,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * except: * */ - __pyx_tuple__14 = PyTuple_Pack(1, __pyx_n_s_collections); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(1, 103, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__14); - __Pyx_GIVEREF(__pyx_tuple__14); + __pyx_tuple__15 = PyTuple_Pack(1, __pyx_n_s_collections); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(1, 103, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__15); + __Pyx_GIVEREF(__pyx_tuple__15); /* "View.MemoryView":309 * return self.name @@ -21222,9 +21679,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * cdef strided = Enum("") # default * cdef indirect = Enum("") */ - __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(1, 309, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__15); - __Pyx_GIVEREF(__pyx_tuple__15); + __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(1, 309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__16); + __Pyx_GIVEREF(__pyx_tuple__16); /* "View.MemoryView":310 * @@ -21233,9 +21690,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * cdef indirect = Enum("") * */ - __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(1, 310, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__16); - __Pyx_GIVEREF(__pyx_tuple__16); + __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(1, 310, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__17); + __Pyx_GIVEREF(__pyx_tuple__17); /* "View.MemoryView":311 * cdef generic = Enum("") @@ -21244,9 +21701,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * * */ - __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(1, 311, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__17); - __Pyx_GIVEREF(__pyx_tuple__17); + __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(1, 311, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__18); + __Pyx_GIVEREF(__pyx_tuple__18); /* "View.MemoryView":314 * @@ -21255,9 +21712,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * cdef indirect_contiguous = Enum("") * */ - __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(1, 314, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__18); - __Pyx_GIVEREF(__pyx_tuple__18); + __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(1, 314, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__19); + __Pyx_GIVEREF(__pyx_tuple__19); /* "View.MemoryView":315 * @@ -21266,19 +21723,19 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * * */ - __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(1, 315, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__19); - __Pyx_GIVEREF(__pyx_tuple__19); + __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(1, 315, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__20); + __Pyx_GIVEREF(__pyx_tuple__20); /* "(tree fragment)":1 * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< * cdef object __pyx_PickleError * cdef object __pyx_result */ - __pyx_tuple__20 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__20); - __Pyx_GIVEREF(__pyx_tuple__20); - __pyx_codeobj__21 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_Enum, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__21)) __PYX_ERR(1, 1, __pyx_L1_error) + __pyx_tuple__21 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__21); + __Pyx_GIVEREF(__pyx_tuple__21); + __pyx_codeobj__22 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__21, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_Enum, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__22)) __PYX_ERR(1, 1, __pyx_L1_error) /* "pygom/model/_tau_leap.pyx":8 * cimport cython @@ -21287,10 +21744,10 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * @cython.wraparound(False) # Deactivate negative indexing. * @cython.cdivision(True) # Deactivate the div 0 error checking */ - __pyx_tuple__22 = PyTuple_Pack(19, __pyx_n_s_x, __pyx_n_s_reactant_mat, __pyx_n_s_rates, __pyx_n_s_tau_scale, __pyx_n_s_epsilon, __pyx_n_s_rates_view, __pyx_n_s_n_rates, __pyx_n_s_x_view, __pyx_n_s_reactant_mat_view, __pyx_n_s_n_reactants, __pyx_n_s_mu, __pyx_n_s_max_cdf, __pyx_n_s_new_cdf, __pyx_n_s_total_rate, __pyx_n_s_safe, __pyx_n_s_count, __pyx_n_s_cdf_val, __pyx_n_s_i, __pyx_n_s_j); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__22); - __Pyx_GIVEREF(__pyx_tuple__22); - __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pygom_model__tau_leap_pyx, __pyx_n_s_cy_test_tau_leap_safety, 8, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) __PYX_ERR(0, 8, __pyx_L1_error) + __pyx_tuple__23 = PyTuple_Pack(19, __pyx_n_s_x, __pyx_n_s_reactant_mat, __pyx_n_s_rates, __pyx_n_s_tau_scale, __pyx_n_s_epsilon, __pyx_n_s_rates_view, __pyx_n_s_n_rates, __pyx_n_s_x_view, __pyx_n_s_reactant_mat_view, __pyx_n_s_n_reactants, __pyx_n_s_mu, __pyx_n_s_max_cdf, __pyx_n_s_new_cdf, __pyx_n_s_total_rate, __pyx_n_s_safe, __pyx_n_s_count, __pyx_n_s_cdf_val, __pyx_n_s_i, __pyx_n_s_j); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__23); + __Pyx_GIVEREF(__pyx_tuple__23); + __pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pygom_model__tau_leap_pyx, __pyx_n_s_cy_test_tau_leap_safety, 8, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 8, __pyx_L1_error) __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; @@ -21559,23 +22016,23 @@ static int __Pyx_modinit_type_import_code(void) { #endif __Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(3, 9, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule("numpy"); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 202, __pyx_L1_error) + __pyx_t_1 = PyImport_ImportModule("numpy"); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 271, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_5numpy_dtype = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "dtype", sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArray_Descr),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_dtype) __PYX_ERR(2, 202, __pyx_L1_error) - __pyx_ptype_5numpy_flatiter = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "flatiter", sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayIterObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_flatiter) __PYX_ERR(2, 225, __pyx_L1_error) - __pyx_ptype_5numpy_broadcast = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "broadcast", sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayMultiIterObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_broadcast) __PYX_ERR(2, 229, __pyx_L1_error) - __pyx_ptype_5numpy_ndarray = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "ndarray", sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_ndarray) __PYX_ERR(2, 238, __pyx_L1_error) - __pyx_ptype_5numpy_generic = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "generic", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_generic) __PYX_ERR(2, 809, __pyx_L1_error) - __pyx_ptype_5numpy_number = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "number", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_number) __PYX_ERR(2, 811, __pyx_L1_error) - __pyx_ptype_5numpy_integer = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "integer", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_integer) __PYX_ERR(2, 813, __pyx_L1_error) - __pyx_ptype_5numpy_signedinteger = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "signedinteger", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_signedinteger) __PYX_ERR(2, 815, __pyx_L1_error) - __pyx_ptype_5numpy_unsignedinteger = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "unsignedinteger", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_unsignedinteger) __PYX_ERR(2, 817, __pyx_L1_error) - __pyx_ptype_5numpy_inexact = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "inexact", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_inexact) __PYX_ERR(2, 819, __pyx_L1_error) - __pyx_ptype_5numpy_floating = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "floating", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_floating) __PYX_ERR(2, 821, __pyx_L1_error) - __pyx_ptype_5numpy_complexfloating = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "complexfloating", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_complexfloating) __PYX_ERR(2, 823, __pyx_L1_error) - __pyx_ptype_5numpy_flexible = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "flexible", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_flexible) __PYX_ERR(2, 825, __pyx_L1_error) - __pyx_ptype_5numpy_character = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "character", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_character) __PYX_ERR(2, 827, __pyx_L1_error) - __pyx_ptype_5numpy_ufunc = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "ufunc", sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyUFuncObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_ufunc) __PYX_ERR(2, 866, __pyx_L1_error) + __pyx_ptype_5numpy_dtype = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "dtype", sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArray_Descr),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_dtype) __PYX_ERR(2, 271, __pyx_L1_error) + __pyx_ptype_5numpy_flatiter = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "flatiter", sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayIterObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_flatiter) __PYX_ERR(2, 316, __pyx_L1_error) + __pyx_ptype_5numpy_broadcast = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "broadcast", sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayMultiIterObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_broadcast) __PYX_ERR(2, 320, __pyx_L1_error) + __pyx_ptype_5numpy_ndarray = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "ndarray", sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_ndarray) __PYX_ERR(2, 359, __pyx_L1_error) + __pyx_ptype_5numpy_generic = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "generic", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_generic) __PYX_ERR(2, 848, __pyx_L1_error) + __pyx_ptype_5numpy_number = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "number", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_number) __PYX_ERR(2, 850, __pyx_L1_error) + __pyx_ptype_5numpy_integer = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "integer", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_integer) __PYX_ERR(2, 852, __pyx_L1_error) + __pyx_ptype_5numpy_signedinteger = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "signedinteger", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_signedinteger) __PYX_ERR(2, 854, __pyx_L1_error) + __pyx_ptype_5numpy_unsignedinteger = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "unsignedinteger", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_unsignedinteger) __PYX_ERR(2, 856, __pyx_L1_error) + __pyx_ptype_5numpy_inexact = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "inexact", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_inexact) __PYX_ERR(2, 858, __pyx_L1_error) + __pyx_ptype_5numpy_floating = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "floating", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_floating) __PYX_ERR(2, 860, __pyx_L1_error) + __pyx_ptype_5numpy_complexfloating = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "complexfloating", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_complexfloating) __PYX_ERR(2, 862, __pyx_L1_error) + __pyx_ptype_5numpy_flexible = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "flexible", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_flexible) __PYX_ERR(2, 864, __pyx_L1_error) + __pyx_ptype_5numpy_character = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "character", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_character) __PYX_ERR(2, 866, __pyx_L1_error) + __pyx_ptype_5numpy_ufunc = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "ufunc", sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyUFuncObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_ufunc) __PYX_ERR(2, 930, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_RefNannyFinishContext(); return 0; @@ -21920,12 +22377,12 @@ if (!__Pyx_RefNanny) { * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence * else: */ - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 100, __pyx_L2_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 100, __pyx_L2_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_version_info); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 100, __pyx_L2_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_tuple__12, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 100, __pyx_L2_error) + __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_tuple__13, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 100, __pyx_L2_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(1, 100, __pyx_L2_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; @@ -21938,7 +22395,7 @@ if (!__Pyx_RefNanny) { * else: * __pyx_collections_abc_Sequence = __import__("collections").Sequence */ - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 101, __pyx_L2_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 101, __pyx_L2_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_abc); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 101, __pyx_L2_error) __Pyx_GOTREF(__pyx_t_5); @@ -21969,7 +22426,7 @@ if (!__Pyx_RefNanny) { * */ /*else*/ { - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 103, __pyx_L2_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 103, __pyx_L2_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Sequence); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 103, __pyx_L2_error) __Pyx_GOTREF(__pyx_t_5); @@ -22134,7 +22591,7 @@ if (!__Pyx_RefNanny) { * cdef strided = Enum("") # default * cdef indirect = Enum("") */ - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 309, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 309, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_XGOTREF(generic); __Pyx_DECREF_SET(generic, __pyx_t_7); @@ -22148,7 +22605,7 @@ if (!__Pyx_RefNanny) { * cdef indirect = Enum("") * */ - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 310, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 310, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_XGOTREF(strided); __Pyx_DECREF_SET(strided, __pyx_t_7); @@ -22162,7 +22619,7 @@ if (!__Pyx_RefNanny) { * * */ - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 311, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 311, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_XGOTREF(indirect); __Pyx_DECREF_SET(indirect, __pyx_t_7); @@ -22176,7 +22633,7 @@ if (!__Pyx_RefNanny) { * cdef indirect_contiguous = Enum("") * */ - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 314, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 314, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_XGOTREF(contiguous); __Pyx_DECREF_SET(contiguous, __pyx_t_7); @@ -22190,7 +22647,7 @@ if (!__Pyx_RefNanny) { * * */ - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 315, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 315, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_XGOTREF(indirect_contiguous); __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_7); @@ -22427,7 +22884,7 @@ if (!__Pyx_RefNanny) { * @cython.wraparound(False) # Deactivate negative indexing. * @cython.cdivision(True) # Deactivate the div 0 error checking */ - __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety, 0, __pyx_n_s_cy_test_tau_leap_safety, NULL, __pyx_n_s_pygom_model__tau_leap, __pyx_d, ((PyObject *)__pyx_codeobj__23)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 8, __pyx_L1_error) + __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety, 0, __pyx_n_s_cy_test_tau_leap_safety, NULL, __pyx_n_s_pygom_model__tau_leap, __pyx_d, ((PyObject *)__pyx_codeobj__24)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 8, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); if (PyDict_SetItem(__pyx_d, __pyx_n_s_cy_test_tau_leap_safety, __pyx_t_7) < 0) __PYX_ERR(0, 8, __pyx_L1_error) __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; @@ -28371,6 +28828,160 @@ static int __Pyx_ValidateAndInit_memviewslice( #endif #endif +/* Declarations */ + #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_long_double_complex __pyx_t_long_double_complex_from_parts(long double x, long double y) { + return ::std::complex< long double >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_long_double_complex __pyx_t_long_double_complex_from_parts(long double x, long double y) { + return x + y*(__pyx_t_long_double_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_long_double_complex __pyx_t_long_double_complex_from_parts(long double x, long double y) { + __pyx_t_long_double_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ + #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) +#else + static CYTHON_INLINE int __Pyx_c_eq_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_sum_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { + __pyx_t_long_double_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_diff_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { + __pyx_t_long_double_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_prod_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { + __pyx_t_long_double_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_quot_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { + if (b.imag == 0) { + return __pyx_t_long_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabsl(b.real) >= fabsl(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_long_double_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + long double r = b.imag / b.real; + long double s = (long double)(1.0) / (b.real + b.imag * r); + return __pyx_t_long_double_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + long double r = b.real / b.imag; + long double s = (long double)(1.0) / (b.imag + b.real * r); + return __pyx_t_long_double_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_quot_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { + if (b.imag == 0) { + return __pyx_t_long_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + long double denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_long_double_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_neg_long__double(__pyx_t_long_double_complex a) { + __pyx_t_long_double_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_long__double(__pyx_t_long_double_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_conj_long__double(__pyx_t_long_double_complex a) { + __pyx_t_long_double_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE long double __Pyx_c_abs_long__double(__pyx_t_long_double_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrtl(z.real*z.real + z.imag*z.imag); + #else + return hypotl(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_pow_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { + __pyx_t_long_double_complex z; + long double r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + long double denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + return __Pyx_c_prod_long__double(a, a); + case 3: + z = __Pyx_c_prod_long__double(a, a); + return __Pyx_c_prod_long__double(z, a); + case 4: + z = __Pyx_c_prod_long__double(a, a); + return __Pyx_c_prod_long__double(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if ((b.imag == 0) && (a.real >= 0)) { + z.real = powl(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2l(0.0, -1.0); + } + } else { + r = __Pyx_c_abs_long__double(a); + theta = atan2l(a.imag, a.real); + } + lnr = logl(r); + z_r = expl(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cosl(z_theta); + z.imag = z_r * sinl(z_theta); + return z; + } + #endif +#endif + /* MemviewSliceCopyTemplate */ static __Pyx_memviewslice __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, @@ -29867,7 +30478,7 @@ __Pyx_PyType_GetName(PyTypeObject* tp) if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) { PyErr_Clear(); Py_XDECREF(name); - name = __Pyx_NewRef(__pyx_n_s__24); + name = __Pyx_NewRef(__pyx_n_s__25); } return name; } diff --git a/pygom/model/_tau_leap.pyx b/pygom/model/_tau_leap.pyx index 09e75b27..fcb700db 100644 --- a/pygom/model/_tau_leap.pyx +++ b/pygom/model/_tau_leap.pyx @@ -28,33 +28,39 @@ def _cy_test_tau_leap_safety(np.ndarray[np.float64_t] x, cdef double mu, max_cdf, new_cdf cdef double total_rate = np.sum(rates) - safe = False - cdef int count = 0 + safe = False # when True, indicates that tau_scale is sufficiently small + cdef int count = 0 # number of attempts to find acceptable tau_scale while safe is False: + # print(count) + # print(tau_scale) cdf_val = 1.0 - for i in range(n_rates): - #xi = x[reactant_mat[:, i]] - #new_cdf = _ppois(xi, mu=tau_scale*r).min() - for j in range(n_reactants): - if reactant_mat_view[j, i] == 1: - mu = rates_view[i] * tau_scale - new_cdf = csc.pdtr(floor(x_view[i]), mu) - if new_cdf < cdf_val: - cdf_val = new_cdf - if new_cdf < cdf_val: - cdf_val = new_cdf + for i in range(n_rates): # loop over transitions, i + for j in range(n_reactants): # loop over states, j + if reactant_mat_view[j, i] == 1: # is state j involved in transition i? + mu = rates_view[i] * tau_scale # expected number of events for transition i + new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop + if new_cdf < cdf_val: + cdf_val = new_cdf + # if new_cdf < cdf_val: # think this extra condition is redundant + # cdf_val = new_cdf #cdf_val[i * reactant_mat.shape[0] : (i * reactant_mat.shape[0]) + len(rates)] = _ppois(xi, mu=tau_scale*r) # the expected probability that our jump will exceed the value max_cdf = 1.0 - cdf_val + # print(max_cdf) # cannot allow it to exceed out epsilon if max_cdf > epsilon: tau_scale /= (max_cdf / epsilon) else: safe = True - if tau_scale*total_rate <= 1.0 or count > 256: + if count > 256: + print("count error") return False + + # if tau_scale*total_rate <= 1.0: # leave out Gillespie regime catch for now + # print("scale error") + # return False count += 1 return tau_scale, True diff --git a/pygom/model/base_ode_model.py b/pygom/model/base_ode_model.py index e58a373e..dea78f0d 100644 --- a/pygom/model/base_ode_model.py +++ b/pygom/model/base_ode_model.py @@ -112,6 +112,7 @@ def __init__(self, self._lambdaMat = None self._vMat = None self._GMat = None + self._lambdaMatOD = None # also trialing this matrix indicating if a state is an origin or destination in a transition self._add_list_attr(state, "state_list") self._add_list_attr(param, "param_list") @@ -987,7 +988,9 @@ def _computeReactantMatrix(self): _f, _t, eqn = self._unrollTransitionList(self._getAllTransition()) for j, eqn in enumerate(eqn): for i, state in enumerate(self._stateList): - if self._stateDict[state.ID] in eqn.atoms(): + if type(eqn)==int: + self._lambdaMat[i, j] = 0 + elif self._stateDict[state.ID] in eqn.atoms(): self._lambdaMat[i, j] = 1 return self._lambdaMat @@ -1019,6 +1022,24 @@ def _computeStateChangeMatrix(self): self._vMat[k2, j] += -1 return self._vMat + + # Might replace _computeReactantMatrix. This function gives a matrix + def _computeReactantMatrixOD(self): + """ + The alternative reactant matrix, where + + .. math:: + \\lambda_{i,j} = \\left\\{ 1, &if state i is an origin or destination in transition j, \\\\ + 0, &otherwise \\right. + + OD imples this refers to origin and destination + """ + + x=self._vMat!=0 + x=x.astype(int) + self._lambdaMatOD=x + + return self._lambdaMatOD def _computeDependencyMatrix(self): """ @@ -1029,6 +1050,8 @@ def _computeDependencyMatrix(self): self._computeReactantMatrix() if self._vMat is None: self._computeStateChangeMatrix() + if self._lambdaMatOD is None: + self._computeReactantMatrixOD() nt = self.num_transitions self._GMat = np.zeros((nt, nt), int) diff --git a/pygom/model/simulate.py b/pygom/model/simulate.py index 61a829c5..453da856 100644 --- a/pygom/model/simulate.py +++ b/pygom/model/simulate.py @@ -567,7 +567,7 @@ def _jump(self, finalT, exact=False, full_output=True, seed=None): xList = [x.copy()] tList = [t] - # we want to construct some jump times + # we want to construct some jump times (TODO: doesn't seem like _GMat is used anywhere) if self._GMat is None: self._computeDependencyMatrix() @@ -582,7 +582,8 @@ def _jump(self, finalT, exact=False, full_output=True, seed=None): else: if np.min(x) > 10: x_tmp, t_tmp, success = tauLeap(x, t, - self._vMat, self._lambdaMat, + # self._vMat, self._lambdaMat, + self._vMat, self._lambdaMatOD, # I think that the wrong matrix has been used, trying this one instead self.transition_vector, self.transition_mean, self.transition_var, @@ -1171,24 +1172,27 @@ def get_bd_from_ode(self, A=None): else: return [] - def _generateTransitionMatrix(self, A=None):#, transitionExpressionList=None): - ''' - Finds the transition matrix from the set of ode. It is - important to note that although some of the functions used - in this method appear to be the same as _getReactantMatrix - and _getStateChangeMatrix, they are different in the sense - that the functions called here is focused on the terms of - the equation rather than the states. - ''' + def _get_A(self, A=None): if A is None: if not ode_utils.none_or_empty_list(self._odeList): eqn_list = [t.equation for t in self._odeList] A = sympy.Matrix(checkEquation(eqn_list, *self._getListOfVariablesDict(), subs_derived=False)) + return A else: raise Exception("Object was not initialized using a set of ode") + def _generateTransitionMatrix(self, A=None):#, transitionExpressionList=None): + ''' + Finds the transition matrix from the set of ode. It is + important to note that although some of the functions used + in this method appear to be the same as _getReactantMatrix + and _getStateChangeMatrix, they are different in the sense + that the functions called here is focused on the terms of + the equation rather than the states. + ''' + A=self._get_A(A) bdList, _term = _ode_composition.getUnmatchedExpressionVector(A, True) fx = _ode_composition.stripBDFromOde(A, bdList) states = [s for s in self._iterStateList()] From 4780f5899f032ac427eebe7bc3f6b723f550367c Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Tue, 30 Jul 2024 13:00:44 +0100 Subject: [PATCH 040/123] Polish common models doc section and some underlying code too --- .../common_models/Legrand_Ebola_SEIHFR.ipynb | 2 +- docs/notebooks/common_models/SEIR.ipynb | 133 ++++++++++++++--- ...IR_Birth_Death_Periodic_Waning_Intro.ipynb | 127 ++++++++++++++++ docs/notebooks/common_models/SIR.ipynb | 89 +++++++---- .../common_models/SIR_Birth_Death.ipynb | 138 ++++++++++++++++-- docs/notebooks/common_models/SIS.ipynb | 79 ++++++++-- .../common_models/SIS_Periodic.ipynb | 89 ++++++++--- pygom/model/common_models.py | 92 +++++++++--- 8 files changed, 626 insertions(+), 123 deletions(-) create mode 100644 docs/notebooks/common_models/SEIR_Birth_Death_Periodic_Waning_Intro.ipynb diff --git a/docs/notebooks/common_models/Legrand_Ebola_SEIHFR.ipynb b/docs/notebooks/common_models/Legrand_Ebola_SEIHFR.ipynb index 7affc240..457443b1 100644 --- a/docs/notebooks/common_models/Legrand_Ebola_SEIHFR.ipynb +++ b/docs/notebooks/common_models/Legrand_Ebola_SEIHFR.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# `Legrand_Ebola_SEIHFR`\n", + "# Legrand Ebola SEIHFR\n", "\n", "{func}`Legrand_Ebola_SEIHFR`\n", "\n", diff --git a/docs/notebooks/common_models/SEIR.ipynb b/docs/notebooks/common_models/SEIR.ipynb index 3875aa0b..f01627de 100644 --- a/docs/notebooks/common_models/SEIR.ipynb +++ b/docs/notebooks/common_models/SEIR.ipynb @@ -7,49 +7,140 @@ "# SEIR\n", "{func}`.SEIR`\n", "\n", - "A natural extension to the SIR is the SEIR model. An extra parameter\n", - "$\\alpha$, which is the inverse of the incubation period is introduced.\n", + "A Susceptible-Exposed-Infectious-Recovered (SEIR) model is a more realistic extension of the standard SIR model in which individuals do not become instantly infectious upon exposure, but undergo an incubation period, the timescale of which is governed by the parameter, $\\alpha$:\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dS}{dt} &= -\\beta SI \\\\\n", - "\\end{aligned}$$$$\\begin{aligned}\n", - "\\frac{dE}{dt} &= \\beta SI - \\alpha E \\\\\n", - "\\end{aligned}$$$$\\begin{aligned}\n", - "\\frac{dI}{dt} &= \\alpha E - \\gamma I \\\\\n", - "\\end{aligned}$$$$\\frac{dR}{dt} &= \\gamma I$$\n", - "\n", - "We use the parameters from {cite:t}`Aron1984` here to generate our plots,\n", - "which does not yield a *nice* and *sensible* epidemic curve as the birth\n", - "and death processes are missing.\n", - "\n" + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= - \\frac{\\beta SI}{N} \\\\\n", + "\\frac{\\mathrm{d}E}{\\mathrm{d}t} &= \\frac{\\beta SI}{N} - \\alpha E \\\\\n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= \\alpha E - \\gamma I \\\\\n", + "\\frac{\\mathrm{d}R}{\\mathrm{d}t} &= \\gamma I\n", + "\\end{aligned}$$\n", + "\n", + "We use the flu-like parameters of the SIR model demonstration with an incubation period of 2 days." ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "id": "bd15619d", "metadata": {}, + "outputs": [], "source": [ "from pygom import common_models\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import random\n", + "import math\n", + "\n", + "#####################\n", + "# Set up PyGOM object\n", + "#####################\n", + "\n", + "# Parameters\n", + "n_pop=1e4\n", + "gamma=1/4\n", + "alpha=1/2\n", + "R0=1.3\n", + "beta=R0*gamma\n", "\n", - "import numpy\n", + "ode = common_models.SEIR({'beta':beta, 'gamma':gamma, 'alpha':alpha, 'N':n_pop})\n", "\n", - "ode = common_models.SEIR({'beta':1800, 'gamma':100, 'alpha':35.84})\n", + "# Time range and increments\n", + "tmax=365 # maximum time over which to run solver\n", + "dt=0.1 # timestep\n", + "n_timestep=math.ceil(tmax/dt) # number of iterations\n", + "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated\n", "\n", - "t = numpy.linspace(0, 50, 1001)\n", + "# Initial conditions\n", + "i0=1\n", + "x0=[n_pop-i0, 0, i0, 0]\n", + "ode.initial_values = (x0, t[0])\n", "\n", - "Ix0 = [0.0658, 0.0007, 0.0002, 0.0]\n", + "# Deterministic evolution\n", + "solution=ode.solve_determ(t[1::])" + ] + }, + { + "cell_type": "markdown", + "id": "abe9b989", + "metadata": {}, + "source": [ + "We also run an SIR model with the same parameters to compare the outputs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "282ebfbd", + "metadata": {}, + "outputs": [], + "source": [ + "ode = common_models.SIR({'beta':beta, 'gamma':gamma, 'N':n_pop})\n", "\n", + "x0=[n_pop-i0, i0, 0]\n", "ode.initial_values = (x0, t[0])\n", "\n", - "solution = ode.integrate(t[1::])\n", + "solution2=ode.solve_determ(t[1::])" + ] + }, + { + "cell_type": "markdown", + "id": "2fab3cb6", + "metadata": {}, + "source": [ + "We see that the SEIR model changes the profile of the epidemic as compared with an SIR model, but the overall final sizes are the same." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0403f7c2", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "# Plot\n", + "\n", + "f, axarr = plt.subplots(1,4, layout='constrained', figsize=(10, 4))\n", "\n", - "ode.plot()" + "# Plot colours\n", + "colours=[\"C1\", \"C3\", \"C0\", \"C2\"]\n", + "stateList=[\"S\", \"E\", \"I\", \"R\"]\n", + "\n", + "for i in range(0, 4):\n", + " axarr[i].plot(t, solution[:,i], color=colours[i])\n", + " if i in [0,2,3]:\n", + " if i in [2,3]:\n", + " axarr[i].plot(t, solution2[:,i-1], color=colours[i], linestyle=\"dashed\")\n", + " else:\n", + " axarr[i].plot(t, solution2[:,i], color=colours[i], linestyle=\"dashed\")\n", + " axarr[i].set_ylabel(stateList[i], rotation=0)\n", + " axarr[i].set_xlabel('Time')\n", + "\n", + "plt.show()" ] } ], "metadata": { + "kernelspec": { + "display_name": "pygom_development", + "language": "python", + "name": "python3" + }, "language_info": { - "name": "python" + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" } }, "nbformat": 4, diff --git a/docs/notebooks/common_models/SEIR_Birth_Death_Periodic_Waning_Intro.ipynb b/docs/notebooks/common_models/SEIR_Birth_Death_Periodic_Waning_Intro.ipynb new file mode 100644 index 00000000..976823ef --- /dev/null +++ b/docs/notebooks/common_models/SEIR_Birth_Death_Periodic_Waning_Intro.ipynb @@ -0,0 +1,127 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e5455073", + "metadata": {}, + "source": [ + "# SEIR, birth, death, periodic, waning and introductions\n", + "{func}`.SEIR_Birth_Death_Periodic_Waning_Intro`\n", + "\n", + "This model includes relatively more detail than the other pre-defined models provided and may serve as a template for more complex models.\n", + "\n", + "In addition to the processes of births, deaths and seasonal driving, we have included (i) immune waning, which transitions recovered individuals back to susceptible at a rate $w$ and (ii) an external force of infection, which allows individuals to be infected from outside the population (analogous to case importation) at a rate $\\epsilon$.\n", + "\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= - \\frac{\\beta(t) SI}{N} + w R + \\mu N - \\mu S\\\\\n", + "\\frac{\\mathrm{d}E}{\\mathrm{d}t} &= \\frac{\\beta(t) SI}{N} + \\epsilon S - \\alpha E - \\mu E \\\\\n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= \\alpha E - \\gamma I - \\mu I \\\\\n", + "\\frac{\\mathrm{d}R}{\\mathrm{d}t} &= \\gamma I - w R - \\mu R \\\\\n", + "\\beta(t) &= \\beta_0 \\left(1+\\delta \\cos \\left(\\frac{2 \\pi t}{P} \\right) \\right)\n", + "\\end{aligned}$$\n", + "\n", + "We solve this set of equations deterministically:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "e7321259", + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import common_models\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import math\n", + "\n", + "# Set up PyGOM object\n", + "n_pop=1e5\n", + "mu=0.01/365\n", + "alpha=1/2\n", + "gamma=1/4\n", + "epsilon=100/(365*n_pop) # approximately 100*n_sus*365/(365*n_pop)=100*frac_sus~30 infections from external sources per year\n", + "w=1/(2*365) # waning rate, immunity lasts ~ 2 years.\n", + "beta0=1\n", + "delta=0.2\n", + "period=365\n", + "\n", + "ode = common_models.SEIR_Birth_Death_Periodic_Waning_Intro({'mu':mu,\n", + " 'alpha':alpha,\n", + " 'gamma':gamma,\n", + " 'epsilon':epsilon,\n", + " 'w':w,\n", + " 'beta0':beta0,\n", + " 'delta':delta,\n", + " 'period':period,\n", + " 'N':n_pop})\n", + "\n", + "# Time range and increments\n", + "tmax=365*20 # maximum time over which to run solver\n", + "dt=0.1 # timestep\n", + "n_timestep=math.ceil(tmax/dt) # number of iterations\n", + "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated\n", + "\n", + "# Initial conditions\n", + "x0 = [n_pop, 0, 0, 0, t[0]]\n", + "\n", + "ode.initial_values = (x0, t[0])\n", + "\n", + "solution=ode.solve_determ(t[1::])" + ] + }, + { + "cell_type": "markdown", + "id": "5eefb897", + "metadata": {}, + "source": [ + "Plotting the infection prevalence reveals that the system eventually reaches a state of annual epidemics." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30368b0d", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "f, ax = plt.subplots(figsize=(10, 2))\n", + "\n", + "ax.set_xlabel(\"Time\")\n", + "ax.set_ylabel(\"Infection prevalence\")\n", + "ax.plot(t[30000:]/365, solution[30000:,2])\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/notebooks/common_models/SIR.ipynb b/docs/notebooks/common_models/SIR.ipynb index 73dceb7e..6d98dfd9 100644 --- a/docs/notebooks/common_models/SIR.ipynb +++ b/docs/notebooks/common_models/SIR.ipynb @@ -8,19 +8,15 @@ "\n", "{func}`.SIR`\n", "\n", - "A standard SIR model defined by the following equations.\n", + "The standard Susceptible-Infected-Recovered (SIR) model, which features heavily throughout this documentation, is defined by the following equations:\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dS}{dt} &= -\\beta SI \\\\\n", - "\\frac{dI}{dt} &= \\beta SI - \\gamma I \\\\\n", - "\\frac{dR}{dt} &= \\gamma I\n", + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= - \\frac{\\beta SI}{N} \\\\\n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= \\frac{\\beta SI}{N} - \\gamma I \\\\\n", + "\\frac{\\mathrm{d}R}{\\mathrm{d}t} &= \\gamma I\n", "\\end{aligned}$$\n", "\n", - "Note that the examples and parameters are taken from {cite:t}`Brauer2008`,\n", - "namely Figure 1.4. Hence, the first example below may not appear to make\n", - "much sense.\n", - "\n", - "#TODO don't understand\n" + "We solve deterministically for flu-like parameters:" ] }, { @@ -31,22 +27,36 @@ "outputs": [], "source": [ "from pygom import common_models\n", - "\n", - "import numpy\n", - "\n", - "ode = common_models.SIR({'beta':3.6, 'gamma':0.2})\n", - "\n", - "t = numpy.linspace(0, 730, 1001)\n", - "\n", - "N = 7781984.0\n", - "\n", - "x0 = [1.0, 10.0/N, 0.0]\n", - "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import random\n", + "import math\n", + "\n", + "#####################\n", + "# Set up PyGOM object\n", + "#####################\n", + "\n", + "# Parameters\n", + "n_pop=1e4\n", + "gamma=1/4\n", + "R0=1.3\n", + "beta=R0*gamma\n", + "\n", + "ode = common_models.SIR({'beta':beta, 'gamma':gamma, 'N':n_pop})\n", + "\n", + "# Time range and increments\n", + "tmax=365 # maximum time over which to run solver\n", + "dt=0.1 # timestep\n", + "n_timestep=math.ceil(tmax/dt) # number of iterations\n", + "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated\n", + "\n", + "# Initial conditions\n", + "i0=1\n", + "x0=[n_pop-i0, i0, 0]\n", "ode.initial_values = (x0, t[0])\n", "\n", - "solution = ode.integrate(t[1::])\n", - "\n", - "ode.plot()\n" + "# Deterministic evolution\n", + "solution=ode.solve_determ(t[1::])" ] }, { @@ -54,25 +64,32 @@ "id": "2b5252ff", "metadata": {}, "source": [ - "\n", - "Now we have the more sensible plot, where the initial susceptible population is\n", - "only a fraction of 1.\n" + "Plotting the result recovers the familiar epidemic trajectory:" ] }, { "cell_type": "code", "execution_count": null, "id": "bd78eb6c", - "metadata": {}, + "metadata": { + "tags": [ + "hide-input" + ] + }, "outputs": [], "source": [ - "x0 = [0.065, 123*(5.0/30.0)/N, 0.0]\n", + "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 4))\n", "\n", - "ode.initial_values = (x0, t[0])\n", + "# Plot colours\n", + "colours=[\"C1\", \"C0\", \"C2\"]\n", + "stateList=[\"S\", \"I\", \"R\"]\n", "\n", - "solution = ode.integrate(t[1::])\n", + "for i in range(0, 3):\n", + " axarr[i].plot(t, solution[:,i], color=colours[i])\n", + " axarr[i].set_ylabel(stateList[i], rotation=0)\n", + " axarr[i].set_xlabel('Time')\n", "\n", - "ode.plot()" + "plt.show()" ] } ], @@ -83,8 +100,16 @@ "name": "python3" }, "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", "name": "python", - "version": "3.9.15" + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" }, "vscode": { "interpreter": { diff --git a/docs/notebooks/common_models/SIR_Birth_Death.ipynb b/docs/notebooks/common_models/SIR_Birth_Death.ipynb index e93b3599..812b7c14 100644 --- a/docs/notebooks/common_models/SIR_Birth_Death.ipynb +++ b/docs/notebooks/common_models/SIR_Birth_Death.ipynb @@ -7,16 +7,19 @@ "# SIR, birth and death \n", "{func}`.SIR_Birth_Death`\n", "\n", - "Next, we look at an SIR model with birth and death processes, where populations are added (birth) or removed (death).\n", + "Here we consider an SIR model in which individuals may be removed by death from each compartment at a uniform rate per person, $\\gamma$.\n", + "The population is replenished via births into the susceptible compartment at the same rate, thus conserving the total population by design.\n", + "For deterministic evolution, the population size remains constant whereas for stochastic evolution, the size fluctuates around this value.\n", + "The equations are as follows:\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dS}{dt} &= B -\\beta SI - \\mu S \\\\\n", - "\\frac{dI}{dt} &= \\beta SI - \\gamma I - \\mu I \\\\\n", - "\\frac{dR}{dt} &= \\gamma I\n", + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= \\mu N - \\frac{\\beta SI}{N} - \\mu S \\\\\n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= \\frac{\\beta SI}{N} - \\gamma I - \\mu I \\\\\n", + "\\frac{\\mathrm{d}R}{\\mathrm{d}t} &= \\gamma I - \\mu R\n", "\\end{aligned}$$\n", "\n", - "Continuing from the example above, but now with a much longer time\n", - "frame. Note that the birth and death rate are the same to maintain a constant population.\n" + "As an example, we study stochastic evolution of this system with measles-like parameters in 3 differently sized populations.\n", + "This provides a demonstration of threshold population sizes in order to support endemic circulation of certain pathogens." ] }, { @@ -27,30 +30,135 @@ "outputs": [], "source": [ "from pygom import common_models\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import math\n", + "import random\n", "\n", - "import numpy\n", + "#####################\n", + "# Set up PyGOM object\n", + "#####################\n", "\n", - "B = 126372.0/365.0\n", + "# Parameters\n", + "n_pop=1e4\n", + "mu=0.01/365 # birth/death rate 1% per year\n", + "gamma=1/20 \n", + "R0=15\n", + "beta=R0*gamma\n", "\n", - "N = 7781984.0\n", + "ode = common_models.SIR_Birth_Death({'beta':beta, 'gamma':gamma, 'mu':mu, 'N':n_pop})\n", "\n", - "ode = common_models.SIR_Birth_Death({'beta':3.6, 'gamma':0.2, 'B':B/N, 'mu':B/N})\n", + "# Time range and increments\n", + "tmax=365*10 # maximum time over which to run solver\n", + "dt=1 # timestep\n", + "n_timestep=math.ceil(tmax/dt) # number of iterations\n", + "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated\n", "\n", - "t = numpy.linspace(0, 35*365, 10001)\n", + "# Initial conditions (endemic equilibrium derived from stationary point)\n", + "def sir_bd_endemic_eq(mu, beta, gamma, n_pop):\n", + " s0=math.floor((gamma+mu)*n_pop/beta)\n", + " i0=math.floor(mu*(n_pop-s0)*n_pop/(beta*s0))\n", + " r0=n_pop-(s0+i0)\n", + " return [s0, i0, r0]\n", "\n", - "x0 = [0.065, 123.0*(5.0/30.0)/N, 0.0]\n", + "x0=sir_bd_endemic_eq(mu, beta, gamma, n_pop)\n", + "ode.initial_values = (x0, t[0])\n", + "\n", + "##########\n", + "# Simulate\n", + "##########\n", + "n_sim=10\n", + "random.seed(1)\n", + "\n", + "solution, simT = ode.solve_stochast(t, n_sim, full_output=True)\n", + "y=np.dstack(solution)\n", "\n", + "############################\n", + "# try larger population size\n", + "############################\n", + "n_pop=1e5\n", + "ode = common_models.SIR_Birth_Death({'beta':beta, 'gamma':gamma, 'mu':mu, 'N':n_pop}) # update parameter\n", + "x0=sir_bd_endemic_eq(mu, beta, gamma, n_pop) # recalculate IC's\n", "ode.initial_values = (x0, t[0])\n", + "solution_2, simT_2 = ode.solve_stochast(t, n_sim, full_output=True) # simulate\n", + "y_2=np.dstack(solution_2)\n", "\n", - "solution = ode.integrate(t[1::])\n", + "#################################\n", + "# try even larger population size\n", + "#################################\n", + "n_pop=1e6\n", + "ode = common_models.SIR_Birth_Death({'beta':beta, 'gamma':gamma, 'mu':mu, 'N':n_pop}) # update parameter\n", + "x0=sir_bd_endemic_eq(mu, beta, gamma, n_pop) # recalculate IC's\n", + "ode.initial_values = (x0, t[0])\n", + "solution_3, simT_3 = ode.solve_stochast(t, n_sim, full_output=True) # simulate\n", + "y_3=np.dstack(solution_3)" + ] + }, + { + "cell_type": "markdown", + "id": "bbc9ac4f", + "metadata": {}, + "source": [ + "Plotting the results, we see that for populations of sizes 10,000 and 100,000, the infected population is critically close to zero, such that stochastic fluctuations eventually lead to disease extinction.\n", + "This is of course signified by the infected class reaching zero, but also by the recovered and susceptible classes undergoing stable linear growth due to population turnover.\n", + "When the population size is 1,000,000, we see that the infected subset, of typical size 500, is able to persist for the full 10 years of the simulation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0f5389b0", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "f, axarr = plt.subplots(3,3, layout='constrained', figsize=(10, 5))\n", + "\n", + "for i in range(0,3):\n", + " # Plot individual trajectories\n", + " for j in range(0, n_sim):\n", + " axarr[0][i].plot(t/365, y[:,i,j], alpha=0.4, color=\"C0\")\n", + " axarr[1][i].plot(t/365, y_2[:,i,j], alpha=0.4, color=\"C1\")\n", + " axarr[2][i].plot(t/365, y_3[:,i,j], alpha=0.4, color=\"C2\")\n", + "\n", + "# Add titles\n", + "stateList = ['S', 'I', 'R']\n", + "for idx, state in enumerate(stateList):\n", + " axarr[0][idx].set_ylabel(state, rotation=0)\n", + " axarr[1][idx].set_ylabel(state, rotation=0)\n", + " axarr[2][idx].set_ylabel(state, rotation=0)\n", + " axarr[0][idx].set_xlabel('Time (years)')\n", + " axarr[1][idx].set_xlabel('Time (years)')\n", + " axarr[2][idx].set_xlabel('Time (years)')\n", "\n", - "ode.plot()" + "axarr[0][1].set_title(\"Population size = 10,000\")\n", + "axarr[1][1].set_title(\"Population size = 100,000\")\n", + "axarr[2][1].set_title(\"Population size = 1,000,000\")\n", + "\n", + "plt.show()" ] } ], "metadata": { + "kernelspec": { + "display_name": "pygom_development", + "language": "python", + "name": "python3" + }, "language_info": { - "name": "python" + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" } }, "nbformat": 4, diff --git a/docs/notebooks/common_models/SIS.ipynb b/docs/notebooks/common_models/SIS.ipynb index cb09e523..cd9237ee 100644 --- a/docs/notebooks/common_models/SIS.ipynb +++ b/docs/notebooks/common_models/SIS.ipynb @@ -7,17 +7,14 @@ "# SIS\n", "{func}`.SIS`\n", "\n", - "A standard SIS model without the total population $N$. We assume here\n", - "that $S + I = N$ so we can always normalize to 1. The state\n", - "$S$ is not required for understanding the model because it is a\n", - "deterministic function of state $I$.\n", + "Perhaps the simplest epidemic model is a Susceptible-Infected-Susceptible (SIS) system, in which susceptible individuals may be infected and then do not have any immunity upon recovery.\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dS}{dt} &= -\\beta S I + \\gamma I \\\\\n", - "\\frac{dI}{dt} &= \\beta S I - \\gamma I.\n", + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= -\\frac{\\beta S I}{N} + \\gamma I \\\\\n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= \\frac{\\beta S I}{N} - \\gamma I.\n", "\\end{aligned}$$\n", "\n", - "An example of an implementation is given below.\n" + "We see how this evolves deterministically:" ] }, { @@ -28,28 +25,80 @@ "outputs": [], "source": [ "from pygom import common_models\n", - "\n", "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import math\n", "\n", - "import numpy\n", + "# Set up PyGOM object\n", + "n_pop=1e4\n", "\n", - "ode = common_models.SIS({'beta':0.5,'gamma':0.2})\n", + "ode = common_models.SIS({'beta':0.5, 'gamma':0.2, 'N':n_pop})\n", "\n", - "t = numpy.linspace(0, 20, 101)\n", + "# Initial conditions\n", + "i0=10\n", + "x0 = [n_pop-i0, i0]\n", "\n", - "x0 = [1.0, 0.1]\n", + "# Time range and increments\n", + "tmax=50 # maximum time over which to run solver\n", + "dt=0.1 # timestep\n", + "n_timestep=math.ceil(tmax/dt) # number of iterations\n", + "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated\n", "\n", "ode.initial_values = (x0, t[0])\n", + "solution=ode.solve_determ(t[1::])" + ] + }, + { + "cell_type": "markdown", + "id": "b272c27d", + "metadata": {}, + "source": [ + "After sufficiently long time, the system reaches an equilibrium state:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2bce7cd0", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "f, axarr = plt.subplots(1,2, layout='constrained', figsize=(10, 4))\n", "\n", - "solution = ode.integrate(t[1::])\n", + "# Plot colours\n", + "colours=[\"C1\", \"C0\"]\n", + "stateList=[\"S\", \"I\"]\n", "\n", - "ode.plot()\n" + "for i in range(0, 2):\n", + " axarr[i].plot(t, solution[:,i], color=colours[i])\n", + " axarr[i].set_ylabel(stateList[i], rotation=0)\n", + " axarr[i].set_xlabel('Time')\n", + "\n", + "plt.show()" ] } ], "metadata": { + "kernelspec": { + "display_name": "pygom_development", + "language": "python", + "name": "python3" + }, "language_info": { - "name": "python" + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" } }, "nbformat": 4, diff --git a/docs/notebooks/common_models/SIS_Periodic.ipynb b/docs/notebooks/common_models/SIS_Periodic.ipynb index c19fe77d..622cfc6b 100644 --- a/docs/notebooks/common_models/SIS_Periodic.ipynb +++ b/docs/notebooks/common_models/SIS_Periodic.ipynb @@ -7,17 +7,30 @@ "# SIS, periodic\n", "{func}`.SIS_Periodic`\n", "\n", - "Now we look at an extension of the SIS model by incorporating a periodic\n", - "contact rate. Note how our equation is defined by a single ODE for state\n", - "**I**.\n", + "This is an extension of the SIS model which incorporates a periodic infection rate, $\\beta(t)$.\n", + "This could be used to mimic seasonal variation in infectivity due to yearly contact rate patterns or climate drivers, for example.\n", + "We define $\\beta(t)$ as follows:\n", "\n", - "$$\\frac{dI}{dt} = (\\beta(t)N - \\alpha) I - \\beta(t)I^{2}$$\n", + "$$\\begin{aligned}\n", + "\\beta(t) &= \\beta_0 \\left(1+\\delta \\cos \\left(\\frac{2 \\pi t}{P} \\right) \\right)\n", + "\\end{aligned}$$\n", "\n", - "where $\\beta(t) = 2 - 1.8 \\cos(5t)$. As the name suggests, it achieves a\n", - "(stable) periodic solution. Note how the plots have two sub-graphs,\n", - "where $\\tau$ is in fact our time component which we have taken out of\n", - "the original equation when converting it to a autonomous system.\n", - "\n" + "where $\\beta_0$ is the baseline infection rate, $\\delta$ is the magnitude of oscillations from the baseline ($-1<\\delta<1$ so that $\\beta>0$) and $P$ is the period of oscillations.\n", + "\n", + "Also, note how we can use $I+S=N$ to eliminate the equation for $S$:\n", + "\n", + "$$\\begin{aligned}\n", + "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= (\\beta(t)N - \\alpha) I - \\beta(t)I^{2} \\\\\n", + "\\end{aligned}$$\n", + "\n", + "In Heathcote's classical model, $\\gamma=1$ and:\n", + "\n", + "$$\\begin{aligned}\n", + "\\beta(t) &= 2 - 1.8 \\cos(5t) \\\\\n", + "&= 2\\left(1 - 0.9 \\cos \\left( \\frac{2 \\pi t}{ \\frac{2 \\pi}{5} } \\right) \\right)\n", + "\\end{aligned}$$\n", + "\n", + "so that $\\beta_0=2$, $\\delta=0.9$ and $P=\\frac{2 \\pi}{5}$." ] }, { @@ -28,22 +41,54 @@ "outputs": [], "source": [ "from pygom import common_models\n", - "\n", "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import math\n", "\n", - "import numpy\n", + "# Set up PyGOM object\n", + "n_pop=1e4\n", "\n", - "ode = common_models.SIS_Periodic({'alpha':1.0})\n", + "ode = common_models.SIS_Periodic({'gamma':1, 'beta0':2, 'delta':0.9, 'period':(2*math.pi/5), 'N':n_pop})\n", "\n", - "t = numpy.linspace(0, 10, 101)\n", + "# Time range and increments\n", + "tmax=10 # maximum time over which to run solver\n", + "dt=0.01 # timestep\n", + "n_timestep=math.ceil(tmax/dt) # number of iterations\n", + "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated\n", "\n", - "x0 = [0.1,0.]\n", + "# Initial conditions\n", + "i0=0.1*n_pop\n", + "x0 = [i0, t[0]]\n", "\n", "ode.initial_values = (x0, t[0])\n", + "solution=ode.solve_determ(t[1::])" + ] + }, + { + "cell_type": "markdown", + "id": "5eefb897", + "metadata": {}, + "source": [ + "We plot the infected trajectory which shows periodic evolution." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "510dd216", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ + "f, ax = plt.subplots(figsize=(10, 4))\n", "\n", - "solution = ode.integrate(t[1::])\n", - "\n", - "ode.plot()" + "ax.set_xlabel(\"Time\")\n", + "ax.set_ylabel(\"I\", rotation=0)\n", + "ax.plot(t, solution[:,0])\n", + "plt.show()" ] } ], @@ -54,8 +99,16 @@ "name": "python3" }, "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", "name": "python", - "version": "3.9.15" + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" }, "vscode": { "interpreter": { diff --git a/pygom/model/common_models.py b/pygom/model/common_models.py index add15970..632d165c 100644 --- a/pygom/model/common_models.py +++ b/pygom/model/common_models.py @@ -33,9 +33,9 @@ def SIS(param=None): """ state = ['S', 'I'] - param_list = ['beta', 'gamma'] + param_list = ['beta', 'gamma', 'N'] transition = [ - Transition(origin='S', destination='I', equation='beta*S*I',transition_type=TransitionType.T), + Transition(origin='S', destination='I', equation='beta*S*I/N',transition_type=TransitionType.T), Transition(origin='I', destination='S', equation='gamma*I',transition_type=TransitionType.T) ] # initialize the model @@ -78,20 +78,22 @@ def SIS_Periodic(param=None): """ state = ['I', 'tau'] - param_list = ['alpha'] - derived_param = [('betaT', '2 - 1.8*cos(5*tau)')] + param_list = ['gamma', 'beta0', 'delta', 'period', 'N'] + # derived_param = [('betaT', '2 - 1.8*cos(5*tau)')] + derived_param = [('betaT', 'beta0*(1-delta*cos(2*3.14159*tau/period))')] ode = [ Transition(origin='I', - equation='(betaT - alpha)*I - betaT*I*I', + equation='(betaT - gamma)*I - (betaT*I*I/N)', transition_type=TransitionType.ODE), Transition(origin='tau', equation='1', transition_type=TransitionType.ODE) ] # initialize the model - ode_obj = SimulateOde(state, param_list, - derived_param=derived_param, - ode=ode) + ode_obj = SimulateOde(state, + param_list, + derived_param=derived_param, + ode=ode) # set return, depending on whether we have input the parameters if param is None: @@ -140,9 +142,9 @@ def SIR(param=None): """ state = ['S', 'I', 'R'] - param_list = ['beta', 'gamma'] + param_list = ['beta', 'gamma', 'N'] transition = [ - Transition(origin='S', destination='I', equation='beta*S*I', + Transition(origin='S', destination='I', equation='beta*S*I/N', transition_type=TransitionType.T), Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T) @@ -297,27 +299,30 @@ def SIR_Birth_Death(param=None): :func:`.SIR` """ state = ['S', 'I', 'R'] - param_list = ['beta', 'gamma', 'B', 'mu'] + param_list = ['beta', 'gamma', 'mu', 'N'] transition = [ - Transition(origin='S', destination='I', equation='beta*S*I', + Transition(origin='S', destination='I', equation='beta*S*I/N', transition_type=TransitionType.T), Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T) ] # our birth and deaths birth_death = [ - Transition(origin='S', equation='B', + Transition(origin='S', equation='mu*N', transition_type=TransitionType.B), Transition(origin='S', equation='mu*S', transition_type=TransitionType.D), Transition(origin='I', equation='mu*I', + transition_type=TransitionType.D), + Transition(origin='R', equation='mu*R', transition_type=TransitionType.D) ] # initialize the model - ode_obj = SimulateOde(state, param_list, - birth_death=birth_death, - transition=transition) + ode_obj = SimulateOde(state, + param_list, + birth_death=birth_death, + transition=transition) # set return, depending on whether we have input the parameters if param is None: @@ -355,10 +360,10 @@ def SEIR(param=None): """ state = ['S', 'E', 'I', 'R'] - param_list = ['beta', 'alpha', 'gamma'] + param_list = ['beta', 'alpha', 'gamma', 'N'] transition = [ - Transition(origin='S', destination='E', equation='beta*S*I', + Transition(origin='S', destination='E', equation='beta*S*I/N', transition_type=TransitionType.T), Transition(origin='E', destination='I', equation='alpha*E', transition_type=TransitionType.T), @@ -406,10 +411,10 @@ def SEIR_Birth_Death(param=None): """ state = ['S', 'E', 'I', 'R'] - param_list = ['beta', 'alpha', 'gamma', 'mu'] + param_list = ['beta', 'alpha', 'gamma', 'mu', 'N'] transition = [ - Transition(origin='S', destination='E', equation='beta*S*I', + Transition(origin='S', destination='E', equation='beta*S*I/N', transition_type=TransitionType.T), Transition(origin='E', destination='I', equation='alpha*E', transition_type=TransitionType.T), @@ -424,7 +429,7 @@ def SEIR_Birth_Death(param=None): transition_type=TransitionType.D), Transition(origin='I', equation='mu*I', transition_type=TransitionType.D), - Transition(origin='S', equation='mu', + Transition(origin='S', equation='mu*N', transition_type=TransitionType.B) ] @@ -505,6 +510,51 @@ def SEIR_Birth_Death_Periodic(param=None): ode_obj.parameters = param return ode_obj + +def SEIR_Birth_Death_Periodic_Waning_Intro(param=None): + state = ['S', 'E', 'I', 'R', 'tau'] + param_list = ['mu', 'alpha', 'gamma', 'epsilon', 'w', 'beta0', 'delta', 'period', 'N'] + + derived_param = [('betaT', 'beta0*(1-delta*cos(2*3.14159*tau/period))')] + + transition = [ + Transition(origin='S', destination='E', equation='betaT*S*I/N', + transition_type=TransitionType.T), + Transition(origin='S', destination='E', equation='epsilon*S', + transition_type=TransitionType.T), + Transition(origin='E', destination='I', equation='alpha*E', + transition_type=TransitionType.T), + Transition(origin='I', destination='R', equation='gamma*I', + transition_type=TransitionType.T), + Transition(origin='R', destination='S', equation='w*R', + transition_type=TransitionType.T) + ] + + bd_list = [ + Transition(origin='S', equation='mu*S', + transition_type=TransitionType.D), + Transition(origin='E', equation='mu*E', + transition_type=TransitionType.D), + Transition(origin='I', equation='mu*I', + transition_type=TransitionType.D), + Transition(origin='R', equation='mu*R', + transition_type=TransitionType.D), + Transition(origin='S', equation='mu*N', + transition_type=TransitionType.B), + Transition(origin='tau', equation='1', + transition_type=TransitionType.B) + ] + + ode_obj = SimulateOde(state, param_list, derived_param=derived_param, + transition=transition, + birth_death=bd_list) + + if param is None: + return ode_obj + else: + ode_obj.parameters = param + return ode_obj + def SEIR_Multiple(n=2, param=None): """ An SEIR model that describe spatial heterogeneity [Brauer2008]_, page 180. From e4a8484b3f800ba0ad28e26e47cde4915dca6622 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:19:15 +0100 Subject: [PATCH 041/123] update tests to replect SIR common models changes --- tests/test_unroll.ipynb | 263 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 tests/test_unroll.ipynb diff --git a/tests/test_unroll.ipynb b/tests/test_unroll.ipynb new file mode 100644 index 00000000..08f94257 --- /dev/null +++ b/tests/test_unroll.ipynb @@ -0,0 +1,263 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pygom import SimulateOde, Transition, TransitionType\n", + "from pygom.model import _ode_composition, ode_utils, _model_verification\n", + "\n", + "odeList = [\n", + " Transition(transition_type=TransitionType.ODE, origin='S', equation='-beta*S*I/(S+I+R) + B*(S+I+R) - mu*S+G'),\n", + " Transition(transition_type=TransitionType.ODE, origin='I', equation='beta*S*I/(S+I+R) - gamma*I - mu*I'),\n", + " Transition(transition_type=TransitionType.ODE, origin='R', equation='gamma*I*p - mu*R'),\n", + " Transition(transition_type=TransitionType.ODE, origin='D', equation='gamma*I*(1-p)') \n", + "]\n", + "\n", + "stateList = ['S', 'I', 'R']\n", + "paramList = ['beta', 'gamma', 'B', 'mu', 'G', 'p']\n", + "\n", + "model = SimulateOde(state=stateList, param=paramList, ode=odeList)\n", + "A=model._get_A()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "bdList, _term = _ode_composition.getUnmatchedExpressionVector(A, True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "map(_ode_composition.getExpressions, A)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from functools import reduce\n", + "\n", + "print(A)\n", + "transition = reduce(lambda x, y: x + y, map(_ode_composition.getExpressions, A))\n", + "print(transition)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def _getBasis(expr):\n", + " \"\"\"\n", + " Given an expression, find the constituent terms.\n", + " e.g. expr=a+b*(c-d) returns [a, b*c, -b*d]\n", + "\n", + " Parameters\n", + " ----------\n", + " expr: sympy type\n", + " An algebraic expression\n", + "\n", + " Returns\n", + " -------\n", + " list:\n", + " Each element being a term of the expression\n", + " \"\"\"\n", + " args=expr.expand().args\n", + "\n", + " #print(args)\n", + "\n", + " for i in range(0, len(args)-1, 1):\n", + " for j in range(i+1, len(args), 1):\n", + " j=j\n", + " #print(args[i]/args[j])\n", + "\n", + " return args\n", + "\n", + "x=_getBasis(A[3])\n", + "\n", + "import sympy\n", + "print(x[0])\n", + "g, I=sympy.symbols('gamma, I')\n", + "print(g)\n", + "(g+2).has(g)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Find basis functions\n", + "\n", + "# x1, x2, x3, x4, x5\n", + "\n", + "# Coefficients in each equation\n", + "\n", + "# (a1, a2, a3, a4, a5)\n", + "# (b1, b2, b3, b4, b5)\n", + "# (c1, c2, c3, c4, c5)\n", + "\n", + "sympy.Symbol('G') in A[0].atoms(sympy.Symbol)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import sympy\n", + "x = sympy.Symbol('x')\n", + "y = sympy.Symbol('y')\n", + "a = [4 + x**2 + y, 4 + y**2]\n", + "\n", + "x in a[0].free_symbols" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "param=\"hello there,how are, you\"\n", + "\n", + "import re\n", + "\n", + "re_split_string = re.compile(r',|\\s') # split string into list at commas or spaces.\n", + "\n", + "print(param)\n", + "if param is not None:\n", + " if isinstance(param, str):\n", + " param = re_split_string.split(param)\n", + " print(param)\n", + " param = filter(lambda x: not len(x.strip()) == 0, param)\n", + " param_list = list(param)\n", + "\n", + "print(param_list)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('beta', 1), ('alpha', 1), ('gamma', 1)]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import re\n", + "re_split_string = re.compile(r',|\\s')\n", + "\n", + "class Pets:\n", + " def __init__(self, param):\n", + " self.param=param\n", + " self._add_list_attr(\"param\")\n", + "\n", + " def _add_list_attr(self, attr_name):\n", + " \"\"\"\n", + " Given an attribute (name attr_name), which is a string of comma\n", + " or space separated values, create a new attribute (name attr_name_list)\n", + " which is a list of those separated values.\n", + " e.g. \"a,b,c d ef\" returns [a, b, c, d, ef]\n", + " \"\"\"\n", + " attr=self.__getattribute__(attr_name)\n", + " if attr is not None:\n", + " if isinstance(attr, str):\n", + " attr = re_split_string.split(attr)\n", + " attr = filter(lambda x: not len(x.strip()) == 0, attr)\n", + " self.__setattr__(\"_\".join([attr_name, \"list\"]), list(attr))\n", + "\n", + "params=[('beta', 1), ('alpha', 1), ('gamma', 1)]\n", + "\n", + "x=Pets(params)\n", + "\n", + "x.param_list" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'dog, cat, bird'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mypets.animals" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['dog', 'cat', 'bird']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mypets.animals__list" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "pygom_development", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 789b079b9cf12f7fd482737c418468e03f23124d Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:21:11 +0100 Subject: [PATCH 042/123] separate unrolling and plotting functions --- pygom/model/_ode_composition.py | 123 +----------------------------- pygom/model/_transition_graph.py | 126 +++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 121 deletions(-) create mode 100644 pygom/model/_transition_graph.py diff --git a/pygom/model/_ode_composition.py b/pygom/model/_ode_composition.py index 8972981b..69ea22cc 100644 --- a/pygom/model/_ode_composition.py +++ b/pygom/model/_ode_composition.py @@ -15,129 +15,10 @@ from .base_ode_model import BaseOdeModel from .transition import TransitionType -greekLetter = ('alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', - 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', 'omicron', 'pi', 'rho', - 'sigma', 'tau', 'upsilon', 'phi', 'chi', 'psi', 'omega') - - -def generateTransitionGraph(ode_model, file_name=None): - """ - Generates the transition graph in graphviz given an ode model with transitions - - Parameters - ---------- - ode_model: OperateOdeModel - an ode model object - file_name: str - location of the file, if none entered, then the default directory is used - - Returns - ------- - dot: graphviz object - """ - assert isinstance(ode_model, BaseOdeModel), "An ode model object required" - - from graphviz import Digraph - - if file_name is None: - dot = Digraph(comment='ode model') - else: - dot = Digraph(comment='ode model', filename=file_name) - - dot.body.extend(['rankdir=LR']) - - param = [str(p) for p in ode_model.param_list] - states = [str(s) for s in ode_model.state_list] - - for s in states: - dot.node(s) - - transition = ode_model.transition_list - bd_list = ode_model.birth_death_list - - for transition in (transition + bd_list): - s1 = transition.origin - eq = _makeEquationPretty(transition.equation, param) - - if transition.transition_type is TransitionType.T: - s2 = transition.destination - dot.edge(s1, s2, label=eq) - elif transition.transition_type is TransitionType.B: - # when we have a birth or death process, do not make the box - dot.node(eq, shape="plaintext", width="0", height="0", margin="0") - dot.edge(eq, s1) - elif transition.transition_type is TransitionType.D: - dot.node(eq, shape="plaintext", width="0", height="0", margin="0") - dot.edge(s1, eq) - else: - pass - - return dot - - -def _makeEquationPretty(eq, param): - """ - Make the equation suitable for graphviz format by converting - beta to β and remove all the multiplication sign - - We do not process ** and convert it to a superscript because - it is only possible with svg (which is a real pain to convert - back to png) and only available from graphviz versions after - 14 Oct 2011 - """ - for p in param: - if p.lower() in greekLetter: - eq = re.sub('(\\W?)(' + p + ')(\\W?)', '\\1&' + p + ';\\3', eq) - # eq = re.sub('\*{1}[^\*]', '', eq) - # eq = re.sub('([^\*]?)\*([^\*]?)', '\\1 \\2', eq) - # eq += " blahYo + haBoo" - return eq - - -def generateDirectedDependencyGraph(ode_matrix, transition=None): - """ - Returns a binary matrix that contains the direction of the transition in - a state - - Parameters - ---------- - ode_matrix: :class:`sympy.matrcies.MatrixBase` - A matrix of size [number of states x 1]. Obtained by - invoking :meth:`DeterministicOde.get_ode_eqn` - transition: list, optional - list of transitions. Can be generated by - :func:`getMatchingExpressionVector` - - Returns - ------- - G: :class:`numpy.ndarray` - Two dimensional array of size [number of state x number of transitions] - where each column has two entry, - -1 and 1 to indicate the direction of the transition and the state. - All column sum to one, i.e. transition must have a source and target. - """ - assert isinstance(ode_matrix, MatrixBase), \ - "Expecting a vector of expressions" - - if transition is None: - transition = getMatchingExpressionVector(ode_matrix, True) - else: - assert isinstance(transition, list), "Require a list of transitions" - - B = np.zeros((len(ode_matrix), len(transition))) - for i, a in enumerate(ode_matrix): - for j, transitionTuple in enumerate(transition): - t1, t2 = transitionTuple - if _hasExpression(a, t1): - B[i, j] += -1 # going out - if _hasExpression(a, t2): - B[i, j] += 1 # coming in - return B - - def getUnmatchedExpressionVector(expr_vec, full_output=False): """ - Return the unmatched expressions from a vector of equations + Return the unmatched expressions from a vector of ODE equations. + e.g [a+b, -a+c, -c+b-d] returns [b, -d, b] Parameters ---------- diff --git a/pygom/model/_transition_graph.py b/pygom/model/_transition_graph.py new file mode 100644 index 00000000..048b3ff6 --- /dev/null +++ b/pygom/model/_transition_graph.py @@ -0,0 +1,126 @@ +import re + +from .base_ode_model import BaseOdeModel +from .transition import TransitionType +from sympy.matrices import MatrixBase +from ._ode_composition import getMatchingExpressionVector, _hasExpression + +# Functions to produce transition graph + +greekLetter = ('alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', + 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', 'omicron', 'pi', 'rho', + 'sigma', 'tau', 'upsilon', 'phi', 'chi', 'psi', 'omega') + +def generateTransitionGraph(ode_model, file_name=None): + """ + Generates the transition graph in graphviz given an ode model with transitions + + Parameters + ---------- + ode_model: OperateOdeModel + an ode model object + file_name: str + location of the file, if none entered, then the default directory is used + + Returns + ------- + dot: graphviz object + """ + assert isinstance(ode_model, BaseOdeModel), "An ode model object required" + + from graphviz import Digraph + + if file_name is None: + dot = Digraph(comment='ode model') + else: + dot = Digraph(comment='ode model', filename=file_name) + + dot.body.extend(['rankdir=LR']) + + param = [str(p) for p in ode_model.param_list] + states = [str(s) for s in ode_model.state_list] + + for s in states: + dot.node(s) + + transition = ode_model.transition_list + bd_list = ode_model.birth_death_list + + for transition in (transition + bd_list): + s1 = transition.origin + eq = _makeEquationPretty(transition.equation, param) + + if transition.transition_type is TransitionType.T: + s2 = transition.destination + dot.edge(s1, s2, label=eq) + elif transition.transition_type is TransitionType.B: + # when we have a birth or death process, do not make the box + dot.node(eq, shape="plaintext", width="0", height="0", margin="0") + dot.edge(eq, s1) + elif transition.transition_type is TransitionType.D: + dot.node(eq, shape="plaintext", width="0", height="0", margin="0") + dot.edge(s1, eq) + else: + pass + + return dot + + +def _makeEquationPretty(eq, param): + """ + Make the equation suitable for graphviz format by converting + beta to β and remove all the multiplication sign + + We do not process ** and convert it to a superscript because + it is only possible with svg (which is a real pain to convert + back to png) and only available from graphviz versions after + 14 Oct 2011 + """ + for p in param: + if p.lower() in greekLetter: + eq = re.sub('(\\W?)(' + p + ')(\\W?)', '\\1&' + p + ';\\3', eq) + # eq = re.sub('\*{1}[^\*]', '', eq) + # eq = re.sub('([^\*]?)\*([^\*]?)', '\\1 \\2', eq) + # eq += " blahYo + haBoo" + return eq + + +def generateDirectedDependencyGraph(ode_matrix, transition=None): + """ + Returns a binary matrix that contains the direction of the transition in + a state + + Parameters + ---------- + ode_matrix: :class:`sympy.matrcies.MatrixBase` + A matrix of size [number of states x 1]. Obtained by + invoking :meth:`DeterministicOde.get_ode_eqn` + transition: list, optional + list of transitions. Can be generated by + :func:`getMatchingExpressionVector` + + Returns + ------- + G: :class:`numpy.ndarray` + Two dimensional array of size [number of state x number of transitions] + where each column has two entry, + -1 and 1 to indicate the direction of the transition and the state. + All column sum to one, i.e. transition must have a source and target. + """ + assert isinstance(ode_matrix, MatrixBase), \ + "Expecting a vector of expressions" + + if transition is None: + transition = getMatchingExpressionVector(ode_matrix, True) + else: + assert isinstance(transition, list), "Require a list of transitions" + + B = np.zeros((len(ode_matrix), len(transition))) + for i, a in enumerate(ode_matrix): + for j, transitionTuple in enumerate(transition): + t1, t2 = transitionTuple + if _hasExpression(a, t1): + B[i, j] += -1 # going out + if _hasExpression(a, t2): + B[i, j] += 1 # coming in + return B From fe8faf855b8c07c293fb1888d55a75bde01e732b Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:26:00 +0100 Subject: [PATCH 043/123] more updated tests --- tests/test_abc.py | 2 +- tests/test_epijson.py | 2 +- tests/test_model_existing.py | 2 +- tests/test_ode_func.py | 2 +- tests/test_ode_simulate_param.py | 2 +- tests/test_sir_estimate.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_abc.py b/tests/test_abc.py index 9918f746..6827e724 100644 --- a/tests/test_abc.py +++ b/tests/test_abc.py @@ -10,7 +10,7 @@ class TestABC(TestCase): def setUp(self): # define the model and parameters - self.ode = common_models.SIR({'beta':0.5, 'gamma':1.0/3.0}) + self.ode = common_models.SIR_norm({'beta':0.5, 'gamma':1.0/3.0}) # the initial state, normalized to one self.x0 = [1, 1.27e-6, 0] diff --git a/tests/test_epijson.py b/tests/test_epijson.py index d0253478..48c8bc77 100644 --- a/tests/test_epijson.py +++ b/tests/test_epijson.py @@ -18,7 +18,7 @@ def test_read_epijson(self): def test_initialize_epijson_loss(self): data = pkgutil.get_data('pygom', 'data/eg1.json') - ode = common_models.SIR() + ode = common_models.SIR_norm() ode.parameters = [0.5, 0.3] obj = EpijsonLoss([0.005, 0.03], ode, data, 'Death', 'R', [300, 2, 0]) self.assertTrue(np.allclose(obj.cost(), 10.86559460256)) diff --git a/tests/test_model_existing.py b/tests/test_model_existing.py index 2af12ce4..8e53d24e 100644 --- a/tests/test_model_existing.py +++ b/tests/test_model_existing.py @@ -13,7 +13,7 @@ def test_SIR(self): Test the SIR model from the set of pre-defined models in common_models ''' # We we wish to test another (simpler) model - ode = common_models.SIR() + ode = common_models.SIR_norm() # define the parameters param_eval = [ diff --git a/tests/test_ode_func.py b/tests/test_ode_func.py index 22e660ef..127f64f8 100644 --- a/tests/test_ode_func.py +++ b/tests/test_ode_func.py @@ -18,7 +18,7 @@ def setUp(self): self.x0 = np.array([1, 1.27e-6, 0]) # params param_eval = [('beta', 0.5), ('gamma', 1.0 / 3.0)] - self.ode = common_models.SIR(param_eval) + self.ode = common_models.SIR_norm(param_eval) self.ode.initial_values = (self.x0, self.t0) self.d = self.ode.num_state self.p = self.ode.num_param diff --git a/tests/test_ode_simulate_param.py b/tests/test_ode_simulate_param.py index 5d9ff629..61403e2d 100644 --- a/tests/test_ode_simulate_param.py +++ b/tests/test_ode_simulate_param.py @@ -19,7 +19,7 @@ def setUp(self): # set the time sequence that we would like to observe self.t = np.linspace(0, 150, 100) # Standard. Find the solution. - ode = common_models.SIR() + ode = common_models.SIR_norm() ode.parameters = [0.5, 1.0 / 3.0] ode.initial_values = (self.x0, self.t0) self.solution = ode.integrate(self.t[1::], full_output=False) diff --git a/tests/test_sir_estimate.py b/tests/test_sir_estimate.py index 629bcc99..b3d42b07 100644 --- a/tests/test_sir_estimate.py +++ b/tests/test_sir_estimate.py @@ -11,7 +11,7 @@ class TestModelEstimate(TestCase): def setUp(self): # define the model and parameters - self.ode = common_models.SIR({'beta': 0.5, 'gamma': 1.0/3.0}) + self.ode = common_models.SIR_norm({'beta': 0.5, 'gamma': 1.0/3.0}) # the initial state, normalized to zero one self.x0 = [1, 1.27e-6, 0] From 6664cb8b3e951beade73a8d6e4a18bf1d2eb641d Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:27:14 +0100 Subject: [PATCH 044/123] documentation, mainly common model examples --- docs/notebooks/common_models/FitzHugh.ipynb | 47 +- .../common_models/Legrand_Ebola_SEIHFR.ipynb | 26 +- .../common_models/Lotka_Volterra.ipynb | 151 ++-- .../common_models/SEIR_Multiple.ipynb | 8 +- .../common_models/SIR_Birth_Death.ipynb | 3 +- docs/notebooks/epijson.ipynb | 8 +- docs/notebooks/extract_info.ipynb | 17 +- docs/notebooks/model_params.ipynb | 6 +- docs/notebooks/model_solver.ipynb | 228 ++++-- docs/notebooks/model_spec.ipynb | 92 ++- docs/notebooks/paramfit/bvpSimple.ipynb | 2 +- docs/notebooks/paramfit/ebola_estimate.ipynb | 763 ++++++++++++++++++ docs/notebooks/paramfit/mle_ci_theory.ipynb | 483 +++++++++++ docs/notebooks/paramfit/params_via_abc.ipynb | 13 +- .../paramfit/params_via_optimization.ipynb | 104 ++- docs/notebooks/time_dependent_params.ipynb | 62 +- docs/notebooks/unroll/unrollSimple.ipynb | 59 +- 17 files changed, 1761 insertions(+), 311 deletions(-) create mode 100644 docs/notebooks/paramfit/ebola_estimate.ipynb create mode 100644 docs/notebooks/paramfit/mle_ci_theory.ipynb diff --git a/docs/notebooks/common_models/FitzHugh.ipynb b/docs/notebooks/common_models/FitzHugh.ipynb index 9d694ea3..1e9fdc8a 100644 --- a/docs/notebooks/common_models/FitzHugh.ipynb +++ b/docs/notebooks/common_models/FitzHugh.ipynb @@ -6,19 +6,19 @@ "source": [ "# FitzHugh\n", "\n", - "{func}`.FitzHugh` - the {cite:t}`FitzHugh1961` model without external stimulus\n", + "{func}`.FitzHugh` - the {cite:t}`FitzHugh1961` model without external stimulus.\n", "\n", - "This is a commonly used model when developing new methodology\n", - "with regards to ODEs, see {cite:p}`Ramsay2007` and {cite}`Girolami2011`.\n", - "\n", - "#TODO why common model?\n", + "The FitzHugh model is commonly used to test ODE software {cite:p}`Ramsay2007` {cite}`Girolami2011`, the model itself describes the excitation state of a neuron membrane as an excitation spike passes. PyGOM also includes other functions which are commonly used to test numerical integrators such as:\n", + "{func}`.vanDerPol` - the Van der Pol oscillator {cite}`vanderPol1926` and\n", + "{func}`.Robertson` - the Robertson reaction {cite}`Robertson1966`.\n", + "The FitzHugh model equations are as follows:\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dV}{dt} &= c ( V - \\frac{V^{3}}{3} + R) \\\\\n", - "\\frac{dR}{dt} &= -\\frac{1}{c}(V - a + bR).\n", + "\\frac{\\mathrm{d} V}{\\mathrm{d} t} &= c ( V - \\frac{V^{3}}{3} + R) \\\\\n", + "\\frac{\\mathrm{d} R}{\\mathrm{d} t} &= -\\frac{1}{c}(V - a + bR).\n", "\\end{aligned}$$\n", "\n", - "An example of using this model follows.\n" + "We solve for the deterministic time evolution of the system:" ] }, { @@ -28,41 +28,31 @@ "metadata": {}, "outputs": [], "source": [ - "import numpy\n", - "\n", + "import numpy as np\n", "from pygom import common_models\n", - "\n", "import matplotlib.pyplot as plt\n", "\n", "ode = common_models.FitzHugh({'a':0.2, 'b':0.2, 'c':3.0})\n", "\n", - "t = numpy.linspace(0, 20, 101)\n", - "\n", + "t = np.linspace(0, 20, 101)\n", "x0 = [1.0, -1.0]\n", - "\n", "ode.initial_values = (x0, t[0])\n", "\n", - "solution = ode.integrate(t[1::])" + "solution = ode.solve_determ(t[1::])" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "ccee969d", - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [], + "cell_type": "markdown", + "id": "a9061aff", + "metadata": {}, "source": [ - "ode.plot()" + "Plotting the function reveals frequent sharp transitions, which makes it an appropriate system to test ODE solving methods." ] }, { "cell_type": "code", "execution_count": null, - "id": "98a5e32e", + "id": "ccee969d", "metadata": { "tags": [ "hide-input" @@ -70,10 +60,7 @@ }, "outputs": [], "source": [ - "fig = plt.figure()\n", - "\n", - "plt.plot(solution[:,0], solution[:,1], 'b')\n", - "plt.show()\n" + "ode.plot()" ] } ], diff --git a/docs/notebooks/common_models/Legrand_Ebola_SEIHFR.ipynb b/docs/notebooks/common_models/Legrand_Ebola_SEIHFR.ipynb index 457443b1..82cbc0db 100644 --- a/docs/notebooks/common_models/Legrand_Ebola_SEIHFR.ipynb +++ b/docs/notebooks/common_models/Legrand_Ebola_SEIHFR.ipynb @@ -8,9 +8,8 @@ "\n", "{func}`Legrand_Ebola_SEIHFR`\n", "\n", - "A commonly used model in the literature to capture the dynamics of Ebola outbreaks is the\n", - "SEIHFR model proposed by {cite}`Legrand2007`. There are two extra\n", - "compartments on top of the SEIR: $H$ for hospitializations and\n", + "A commonly used model in the literature to capture the dynamics of Ebola outbreaks is the SEIHFR model proposed by Legrand _et al_ {cite}`legrand2007utd`.\n", + "There are two extra compartments on top of the SEIR: $H$ for hospitializations and\n", "$F$ for funerals. A total of ten parameters (with some describing the\n", "inverse) are required for the model.\n", "\n", @@ -33,7 +32,7 @@ "$\\omega$'s, i.e. $\\omega_{i} = \\gamma_{i}^{-1}$ for $i \\in \\{I,D,H,F\\}$.\n", "We also used $\\alpha^{-1}$ in our model instead of $\\alpha$ so that\n", "reading the parameters directly gives a more intuitive meaning. There\n", - "arw five additional parameters that is derived. The two derived case\n", + "are five additional parameters that is derived. The two derived case\n", "fatality ratio as\n", "\n", "$$\\begin{aligned}\n", @@ -69,8 +68,7 @@ "\n", "$$\\beta_{F}(t) = \\beta_{F} \\left(1 - \\frac{1}{1 + \\exp(-\\kappa (t - c))} \\right)$$\n", "\n", - "A brief example is given here with a slightly more in depth\n", - "example in {doc}`estimate2`.\n", + "A brief example is given here:\n", "\n" ] }, @@ -89,8 +87,18 @@ "\n", "t = numpy.linspace(1, 25, 100)\n", "\n", - "ode = common_models.Legrand_Ebola_SEIHFR([('beta_I',0.588), ('beta_H',0.794), ('beta_F',7.653), ('omega_I',10.0/7.0), ('omega_D',9.6/7.0),\n", - "('omega_H',5.0/7.0), ('omega_F',2.0/7.0), ('alphaInv',7.0/7.0), ('delta',0.81), ('theta',0.80), ('kappa',300.0), ('interventionTime',7.0)])\n", + "ode = common_models.Legrand_Ebola_SEIHFR([('beta_I',0.588),\n", + " ('beta_H',0.794),\n", + " ('beta_F',7.653),\n", + " ('omega_I',10.0/7.0),\n", + " ('omega_D',9.6/7.0),\n", + " ('omega_H',5.0/7.0),\n", + " ('omega_F',2.0/7.0),\n", + " ('alphaInv',7.0/7.0),\n", + " ('delta',0.81),\n", + " ('theta',0.80),\n", + " ('kappa',300.0),\n", + " ('interventionTime',7.0)])\n", "\n", "ode.initial_values = (x0, t[0])\n", "\n", @@ -108,7 +116,7 @@ "```{note}\n", "We have standardized the states so that the number of\n", "susceptible is 1 and equal to the whole population, i.e. $N$ does not\n", - "exist in our set of ODEs as defined in {mod}`common_models`.\n", + "exist in our set of ODEs.\n", "```" ] } diff --git a/docs/notebooks/common_models/Lotka_Volterra.ipynb b/docs/notebooks/common_models/Lotka_Volterra.ipynb index ddf146b7..d38a2228 100644 --- a/docs/notebooks/common_models/Lotka_Volterra.ipynb +++ b/docs/notebooks/common_models/Lotka_Volterra.ipynb @@ -6,14 +6,16 @@ "source": [ "# Lotka Volterra\n", "\n", - "{func}`.Lotka_Volterra` - the standard predator and prey model with two states and four parameters {cite}`Lotka1920`\n", + "The model {func}`.Lotka_Volterra` is a basic predator and prey model {cite}`Lotka1920`.\n", + "This is more commonly expressed in terms of predator and prey population area densities, $x$ and $y$ respectively, though we define the model in terms of absolute numbers, $X$ and $Y$, in a given area, $A$.\n", + "This decision to define in terms of population numbers, rather than densities, permits us to perform stochastic simulations.\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dx}{dt} &= \\alpha x - cxy \\\\\n", - "\\frac{dy}{dt} &= -\\delta y + \\gamma xy\n", + "\\frac{\\mathrm{d} X}{\\mathrm{d} t} &= \\alpha X - \\frac{\\beta X Y}{A} \\\\\n", + "\\frac{\\mathrm{d} Y}{\\mathrm{d} t} &= -\\gamma Y + \\frac{\\delta X Y}{A}\n", "\\end{aligned}$$\n", "\n", - "with both birth and death processes." + "We first solve this model for the deterministic case:" ] }, { @@ -24,128 +26,117 @@ "outputs": [], "source": [ "from pygom import common_models\n", - "\n", - "import numpy\n", - "\n", + "import numpy as np\n", "import matplotlib.pyplot as plt\n", + "import math\n", "\n", - "x0 = [2.0, 6.0]\n", + "# population density of predators and prey per square m\n", + "x0 = [1, 0.5]\n", "\n", - "ode = common_models.Lotka_Volterra({'alpha':1, 'delta':3, 'c':2, 'gamma':6})\n", + "# total area we wish to consider\n", + "area=200\n", "\n", - "ode.initial_values = (x0, 0)\n", + "# total animal populations\n", + "x0 = [x * area for x in x0]\n", "\n", - "t = numpy.linspace(0.1, 100, 10000)\n", + "ode = common_models.Lotka_Volterra({'alpha':0.1,\n", + " 'beta':0.2,\n", + " 'gamma':0.3,\n", + " 'delta':0.25,\n", + " 'A':area})\n", "\n", - "solution = ode.integrate(t)\n", + "tmax=200 # maximum time over which to run solver\n", + "dt=0.1 # timestep\n", + "n_timestep=math.ceil(tmax/dt) # number of iterations\n", + "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated\n", "\n", - "ode.plot()\n" + "ode.initial_values = (x0, t[0])\n", + "\n", + "solution = ode.solve_determ(t[1::])" ] }, { "cell_type": "markdown", - "id": "1943441d", + "id": "4d951b55", "metadata": {}, "source": [ - "Then we can generate the graph at [Wolfram\n", - "Alpha](http://www.wolframalpha.com/input/?i=lotka-volterra+equations)\n", - "with varying initial conditions.\n" + "We see that the predator and prey populations show periodic behaviour with a phase shift between them." ] }, { - "cell_type": "markdown", - "id": "b5c82937", - "metadata": {}, + "cell_type": "code", + "execution_count": null, + "id": "004de679", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], "source": [ - "x1List = numpy.linspace(0.2, 2.0, 5)\n", + "f, ax = plt.subplots(figsize=(10, 2))\n", "\n", - "x2List = numpy.linspace(0.6, 6.0, 5)\n", - "\n", - "fig = plt.figure()\n" + "ax.set_xlabel(\"Time\")\n", + "ax.set_ylabel(\"Population number\")\n", + "ax.plot(t, solution[:,0], label=\"prey\")\n", + "ax.plot(t, solution[:,1], label=\"predator\")\n", + "ax.legend(loc=\"upper right\")\n", + "plt.show()" ] }, { "cell_type": "markdown", - "id": "5a492117", + "id": "5918419c", "metadata": {}, "source": [ - "\n", - "solutionList = list()\n", - "\n" + "We can also see how the system evolves stochastically" ] }, { "cell_type": "code", "execution_count": null, - "id": "f2a1d859", + "id": "9858cacf", "metadata": {}, "outputs": [], "source": [ - "ode = common_models.Lotka_Volterra({'alpha':1, 'delta':3, 'c':2, 'gamma':6})\n", - "\n", - "for i in range(len(x1List)): \n", - " ode.initial_values = ([x1List[i], x2List[i]], 0)\n", + "np.random.seed(1)\n", "\n", - "solutionList += [ode.integrate(t)]\n", + "n_sim=1\n", + "solution, simT = ode.solve_stochast(t, n_sim, full_output=True)\n", "\n", - "for i in range(len(x1List)):\n", - " plt.plot(solutionList[i][100::,0], solutionList[i][100::,1], 'b')\n", + "f, ax = plt.subplots(figsize=(10, 2))\n", "\n", - "plt.xlabel('x')\n", - "\n", - "plt.ylabel('y')\n", + "y=np.dstack(solution)\n", "\n", + "ax.set_xlabel(\"Time\")\n", + "ax.set_ylabel(\"Population number\")\n", + "ax.plot(t, y[:,0], label=\"prey\")\n", + "ax.plot(t, y[:,1], label=\"predator\")\n", + "ax.legend(loc=\"upper right\")\n", "plt.show()" ] }, { "cell_type": "markdown", - "id": "c628f283", + "id": "39ce9a40", "metadata": {}, "source": [ - "We also know that the system has the critical points at\n", - "$x = \\delta / \\gamma$ and $y=\\alpha / c$. If we changes the parameters\n", - "in such a way that the ration between $x$ and $y$ remains the same, then\n", - "we get a figure as below.\n" + "This appears to be unstable, since the populations undergo increasingly extreme peaks and troughs.\n", + "This can be confirmed by examining a phase diagram, whereby the trajectory in state space spirals outwards." ] }, { "cell_type": "code", "execution_count": null, - "id": "837940dd", + "id": "b7717689", "metadata": {}, "outputs": [], "source": [ - "cList = numpy.linspace(0.1, 2.0, 5)\n", - "\n", - "gammaList = numpy.linspace(0.6, 6.0, 5)\n", - "\n", - "fig = plt.figure()\n", - "\n", - "for i in range(len(x1List)): \n", - " ode = common_models.Lotka_Volterra({'alpha':1, 'delta':3, 'c':cList[i], 'gamma':gammaList[i]})\n", - "\n", - "ode.initial_values = (x0, 0) \n", - "solutionList += [ode.integrate(t)]\n", - "\n", - "for i in range(len(cList)):\n", - " plt.plot(solutionList[i][100::,0], solutionList[i][100::,1])\n", - "\n", - "plt.xlabel('x')\n", - "\n", - "plt.ylabel('y')\n", - "\n", - "plt.show()\n" - ] - }, - { - "cell_type": "markdown", - "id": "f05ce4a3", - "metadata": {}, - "source": [ - "\n", - "\n", - "where all the cycles goes through the same points." + "f, ax = plt.subplots(figsize=(10, 6))\n", + "ax.plot(y[:,0], y[:,1])\n", + "ax.set_xlabel(\"Prey population\")\n", + "ax.set_ylabel(\"Predator population\")\n", + "plt.show()" ] } ], @@ -156,8 +147,16 @@ "name": "python3" }, "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", "name": "python", - "version": "3.9.15" + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" }, "vscode": { "interpreter": { diff --git a/docs/notebooks/common_models/SEIR_Multiple.ipynb b/docs/notebooks/common_models/SEIR_Multiple.ipynb index b9ff28df..ced9c1d6 100644 --- a/docs/notebooks/common_models/SEIR_Multiple.ipynb +++ b/docs/notebooks/common_models/SEIR_Multiple.ipynb @@ -10,10 +10,10 @@ "Multiple SEIR coupled together, without any birth death process.\n", "\n", "$$\\begin{aligned}\n", - "\\frac{dS_{i}}{dt} &= dN_{i} - dS_{i} - \\lambda_{i}S_{i} \\\\\n", - "\\frac{dE_{i}}{dt} &= \\lambda_{i}S_{i} - (d+\\epsilon)E_{i} \\\\\n", - "\\frac{dI_{i}}{dt} &= \\epsilon E_{i} - (d+\\gamma) I_{i} \\\\\n", - "\\frac{dR_{i}}{dt} &= \\gamma I_{i} - dR_{i}\n", + "\\frac{\\mathrm{d} S_{i}}{\\mathrm{d} t} &= dN_{i} - dS_{i} - \\lambda_{i}S_{i} \\\\\n", + "\\frac{\\mathrm{d} E_{i}}{\\mathrm{d} t} &= \\lambda_{i}S_{i} - (d+\\epsilon)E_{i} \\\\\n", + "\\frac{\\mathrm{d} I_{i}}{\\mathrm{d} t} &= \\epsilon E_{i} - (d+\\gamma) I_{i} \\\\\n", + "\\frac{\\mathrm{d} R_{i}}{\\mathrm{d}t} &= \\gamma I_{i} - dR_{i}\n", "\\end{aligned}$$\n", "\n", "where\n", diff --git a/docs/notebooks/common_models/SIR_Birth_Death.ipynb b/docs/notebooks/common_models/SIR_Birth_Death.ipynb index 812b7c14..b0123894 100644 --- a/docs/notebooks/common_models/SIR_Birth_Death.ipynb +++ b/docs/notebooks/common_models/SIR_Birth_Death.ipynb @@ -33,7 +33,6 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import math\n", - "import random\n", "\n", "#####################\n", "# Set up PyGOM object\n", @@ -68,7 +67,7 @@ "# Simulate\n", "##########\n", "n_sim=10\n", - "random.seed(1)\n", + "np.random.seed(1)\n", "\n", "solution, simT = ode.solve_stochast(t, n_sim, full_output=True)\n", "y=np.dstack(solution)\n", diff --git a/docs/notebooks/epijson.ipynb b/docs/notebooks/epijson.ipynb index 7ad54f4f..73ddd29e 100644 --- a/docs/notebooks/epijson.ipynb +++ b/docs/notebooks/epijson.ipynb @@ -6,12 +6,8 @@ "source": [ "# Reading and using EpiJSON data\n", "\n", - "```{warning}\n", - "JG: Not entirely sure what is going on in this section.\n", - "```\n", - "\n", "[EpiJSON](https://github.com/Hackout2/EpiJSON) is a framework which tries to capture epidemiological information in a JSON format {cite}`Finnie2016`.\n", - "PyGOM provides the functionality to process EpiJSON data with a view to preparing it for it's various modelling features previously discussed in this guide.\n", + "PyGOM provides the functionality to process EpiJSON data with a view to preparing it for its various modelling features previously discussed in this guide.\n", "The input can be in a string format, a file or already a `dict`.\n", "The output is in the cumulative form as default, shown below, in a [`pandas.DataFrame`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html) format. " ] @@ -53,7 +49,7 @@ "\n", "from pygom.loss.epijson_loss import EpijsonLoss\n", "\n", - "ode = common_models.SIR([0.5, 0.3])\n", + "ode = common_models.SIR_norm([0.5, 0.3])\n", "\n", "obj = EpijsonLoss([0.005, 0.03], ode, data, 'Death', 'R', [300, 2, 0])\n", "\n", diff --git a/docs/notebooks/extract_info.ipynb b/docs/notebooks/extract_info.ipynb index 8c542c14..84875e30 100644 --- a/docs/notebooks/extract_info.ipynb +++ b/docs/notebooks/extract_info.ipynb @@ -8,9 +8,9 @@ "# Extracting model information\n", "\n", "In the study of ODE systems, there are many calculations which are frequently performed and PyGOM has some functionality to provide assistance.\n", - "We will again use the SIR model as our example system, but this time we will make use of the from PyGOM `common_models` module, where many predefined models are stored.\n", + "We will again use the SIR model as our example system, but this time we will make use of the PyGOM `common_models` module, where many predefined models are stored.\n", "This means we avoid having to build the model from scratch again, saving time and lines of code.\n", - "Here we initialise a `SIR_N` model, the suffix, $N$, indicating that we have standard incidence and thus $N$ appears in the denominator of the force of infection:" + "Here we initialise a `SIR` model:" ] }, { @@ -21,7 +21,7 @@ "outputs": [], "source": [ "from pygom import common_models\n", - "ode = common_models.SIR_N()" + "ode = common_models.SIR()" ] }, { @@ -88,7 +88,8 @@ "id": "9c7b5c60", "metadata": {}, "source": [ - "Where only the upper off diagonal triangle is necessary to fully define the system.\n", + "where only the upper off diagonal triangle is necessary to fully define the system.\n", + "\n", "We can even inspect the transitions graphically:" ] }, @@ -127,7 +128,11 @@ "id": "c3fa0e62", "metadata": {}, "source": [ - "For stability analysis and speeding up numerical integrators, it may be useful to know the Jacobian, Hessian or gradient which PyGOM has functions for respectively:" + "For stability analysis and speeding up numerical integrators, it may be useful to know the Jacobian, Hessian (where three 2D arrays are returned, rather than one 3D array) or gradient which PyGOM has functions for respectively:\n", + "\n", + "```{warning}\n", + "In different contexts it can be useful to know the derivatives with respect to the state variables or the parameters. Make sure you know which one you require and check that the PyGOM function you are using provides it.\n", + "```" ] }, { @@ -168,7 +173,7 @@ "## Epidemiology specific insights\n", "\n", "Under development are functions to obtain numeric and algebraic expressions for the basic reproduction number, $R_0$.\n", - "Currently, these can be obtained in two steps, first by finding the disease progression matrix and then calculating $R_0$ from this.\n", + "Currently, these can be obtained in two steps, first by finding the next generation matrix and then calculating $R_0$ from this, assuming in the initial conditions that $S(0)=N$.\n", "We must specify which state represents the *infectious state*, which in this case is the state **I**." ] }, diff --git a/docs/notebooks/model_params.ipynb b/docs/notebooks/model_params.ipynb index f6d64c5a..7ddbbf50 100644 --- a/docs/notebooks/model_params.ipynb +++ b/docs/notebooks/model_params.ipynb @@ -22,7 +22,7 @@ "outputs": [], "source": [ "from pygom import common_models\n", - "ode = common_models.SIR_N()" + "ode = common_models.SIR()" ] }, { @@ -59,7 +59,7 @@ "\n", "Instead, imagine that we have some prior uncertainty on the values of our model parameters.\n", "We may wish to reflect this by running model simulations over a variety of parameter values drawn randomly from a probability distribution.\n", - "A suitable choice of distribution for $\\gamma$ and $\\beta$ is a Gamma distribution, since it ensures that both parameters are positive as required.\n", + "A suitable choice of distribution for $\\gamma$ and $\\beta$ is a gamma distribution, since it ensures that both parameters are positive as required.\n", "In this example, we'll keep the total population, $N$, fixed, showing that a mixture of parameter types (fixed and random) is possible.\n", "\n", "To define our random distributions, we make use of the familiar syntax from [R](http://www.r-project.org/).\n", @@ -97,7 +97,7 @@ "metadata": {}, "outputs": [], "source": [ - "ode = common_models.SIR_N_stochastic()\n", + "ode = common_models.SIR()\n", "ode.parameters=random_param_set" ] }, diff --git a/docs/notebooks/model_solver.ipynb b/docs/notebooks/model_solver.ipynb index 1f1f9ec3..2c018cd2 100644 --- a/docs/notebooks/model_solver.ipynb +++ b/docs/notebooks/model_solver.ipynb @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "1679a48a", "metadata": {}, "outputs": [], @@ -23,6 +23,7 @@ "from pygom import SimulateOde, Transition, TransitionType\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", + "import random\n", "\n", "###################\n", "# ODE specification\n", @@ -79,13 +80,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "5dc7996d", "metadata": {}, "outputs": [], "source": [ - "import random\n", - "random.seed(1)" + "np.random.seed(1)" ] }, { @@ -94,16 +94,18 @@ "metadata": {}, "source": [ "In order to determine the time evolution of the system, we must supply initial conditions as well as the desired time points for the numerical solver.\n", - "Timesteps should be sufficiently short to minimise numerical integration errors, but not too short such that the computational time costs become too large." + "Timesteps should be sufficiently short to reduce numerical integration errors, but not too short such that the computational time costs become too large." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "9e31cc4f", "metadata": {}, "outputs": [], "source": [ + "import math\n", + "\n", "# Initial conditions\n", "i0=10\n", "x0 = [n_pop-i0, i0, 0]\n", @@ -111,7 +113,7 @@ "# Time range and increments\n", "tmax=200 # maximum time over which to run solver\n", "dt=0.1 # timestep\n", - "n_timestep=int(tmax/dt) # number of iterations\n", + "n_timestep=math.ceil(tmax/dt) # number of iterations\n", "t = np.linspace(0, tmax, n_timestep) # times at which solution will be evaluated" ] }, @@ -120,7 +122,7 @@ "id": "ecd39e70", "metadata": {}, "source": [ - "## Deterministic time evolution\n", + "## Deterministic evolution\n", "\n", "To solve for the deterministic time evolution of the system, PyGOM uses {func}`scipy.integrate.odeint` which is wrapped by the member function {func}`solve_determ`.\n", "We begin with the simple (and likely familiar) case of fixed parameters.\n", @@ -182,14 +184,19 @@ "source": [ "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", "\n", - "axarr[0].plot(t, solution_D_F[:,0], color='C1')\n", - "axarr[1].plot(t, solution_D_F[:,1], color='C0')\n", - "axarr[2].plot(t, solution_D_F[:,2], color='C2')\n", + "# Plot colours\n", + "colours=[\"C1\", \"C0\", \"C2\"]\n", + "\n", + "for i in range(0, 3):\n", + " axarr[i].plot(t, solution_D_F[:,i], color=colours[i])\n", "\n", "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_title(state)\n", + " axarr[idx].set_ylabel(state, rotation=0)\n", " axarr[idx].set_xlabel('Time')\n", - "\n" + "\n", + "axarr[1].set_title(\"Deterministic simulation with fixed parameters\")\n", + "\n", + "plt.show()\n" ] }, { @@ -271,21 +278,10 @@ "#########################\n", "# Individual trajectories\n", "#########################\n", - "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", "\n", "# Select 50 simulations to plot\n", "i_rand=random.sample(range(n_param_draws), 50)\n", "\n", - "# Plot colours\n", - "colours=[\"C1\", \"C0\", \"C2\"]\n", - "\n", - "for i in i_rand:\n", - " for j in range(y_D_R.shape[1]):\n", - " axarr[j].plot(t, y_D_R[:,j,i], color=colours[j], alpha=0.2)\n", - "\n", - "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_title(state)\n", - "\n", "######################\n", "# Confidence intervals\n", "######################\n", @@ -297,15 +293,32 @@ "y_D_R_hihi=np.percentile(y_D_R, 97.5, axis=2)\n", "y_D_R_md=np.percentile(y_D_R, 50, axis=2)\n", "\n", - "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", - " \n", + "f, axarr = plt.subplots(2,3, layout='constrained', figsize=(10, 5))\n", + "\n", + "# Plot colours\n", + "colours=[\"C1\", \"C0\", \"C2\"]\n", + "\n", "for i in range(0,3):\n", - " axarr[i].fill_between(t, y_D_R_lolo[:,i], y_D_R_hihi[:,i], alpha=0.2, facecolor=colours[i])\n", - " axarr[i].fill_between(t, y_D_R_lo[:,i], y_D_R_hi[:,i], alpha=0.4, facecolor=colours[i])\n", - " axarr[i].plot(t, y_D_R_md[:,i], color=colours[i])\n", + " # Plot individual trajectories\n", + " for j in i_rand:\n", + " axarr[0][i].plot(t, y_D_R[:,i,j], color=colours[i], alpha=0.2)\n", + "\n", + " # Plot CI's\n", + " axarr[1][i].fill_between(t, y_D_R_lolo[:,i], y_D_R_hihi[:,i], alpha=0.2, facecolor=colours[i])\n", + " axarr[1][i].fill_between(t, y_D_R_lo[:,i], y_D_R_hi[:,i], alpha=0.4, facecolor=colours[i])\n", + " axarr[1][i].plot(t, y_D_R_md[:,i], color=colours[i])\n", "\n", + "# Add titles\n", "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_xlabel('Time')\n" + " axarr[0][idx].set_ylabel(state, rotation=0)\n", + " axarr[1][idx].set_ylabel(state, rotation=0)\n", + " axarr[0][idx].set_xlabel('Time')\n", + " axarr[1][idx].set_xlabel('Time')\n", + "\n", + "axarr[0][1].set_title(\"50 deterministic simulations, each with randomly drawn parameters\")\n", + "axarr[1][1].set_title(\"Median (line), 50% CI (dark shaded) and 95% CI (light shaded) over 1000 simulations\")\n", + "\n", + "plt.show()\n" ] }, { @@ -336,8 +349,8 @@ "The approximation that numbers of individuals in each state may be treated as a continuum break down when their sizes are small.\n", "In this regime, transitions between states do not represent continuous flows but are instead stochastic events that occur at rates governed by the current state of the system. The simplifying assumption that waiting times for these events to occur are exponentially distributed (memoryless), allows for quicker evaluation of the dynamics.\n", "\n", - "Two common algorithms have been implemented for use during simulation; the reaction method [\\[Gillespie1977\\]]() and the $\\tau$-Leap method\n", - "[\\[Cao2006\\]]().\n", + "Two common algorithms have been implemented for use during simulation; the reaction method {cite}`Gillespie1977` and the $\\tau$-Leap method\n", + "{cite}`Cao2006`.\n", "The two change interactively depending on the size of the states.\n", "\n", "### Fixed parameters\n", @@ -348,7 +361,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "118a869b", "metadata": {}, "outputs": [], @@ -372,41 +385,86 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "a3698023", "metadata": { "tags": [ "hide-input" ] }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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uXPnKjo6WiEhIb94T1oAAACgspUp5L7++utavny5hg4dWt71AAAAANetTPfJzc3N5T60AAAA8FplCrmjR4/WqlWryrsWAAAAoFyUabnCzz//rCVLlmjTpk1q3bq1/Pz83PbPnz+/XIoDAAAAyqJMIXffvn1q27atJOnAgQNu+/gQGgAAADytTCF369at5V0HAAAAUG7KtCYXAAAA8GZlmsnt3r37Ly5L2LJlS5kLAgAAAK5XmUJuwXrcApcuXdLevXt14MABDR8+vDzqAgAAAMqsTCH35ZdfLrI9Pj5eP/7443UVBAAAAFyvcl2TO2TIEC1btqw8TwkAAACUWrmG3O3bt6tatWrleUoAAACg1Mq0XGHAgAFuj40xOn36tD799FPNmjWrXAoDAAAAyqpMIdfhcLg9rlKlipo2baq5c+cqLi6uXAoDAAAAyqpMITcpKam86wAAAADKTZlCboFdu3bp8OHDstlsatGihdq1a1dedQEAAABlVqaQm5GRoUceeUTbtm1TzZo1ZYxRVlaWunfvruTkZNWrV6+86wQAAABKrEx3V5g0aZKys7N18OBB/fDDD8rMzNSBAweUnZ2tJ554orxrBAAAAEqlTDO5GzZs0KZNm9S8eXNXW4sWLfTaa6/xwTMAAAB4XJlmcvPz8+Xn51eo3c/PT/n5+dddFAAAAHA9yhRy7777bk2ePFnffvutq+2bb77R7373O/Xo0aPcigMAAADKokzLFRYuXKj+/fsrPDxcYWFhstlsOnHihFq1aqWVK1eWd40AAACWFz59faG2Y8/38UAl1lCmkBsWFqbdu3crJSVFn3/+uYwxatGihe65557yrg8AAAAotVItV9iyZYtatGih7OxsSVLPnj01adIkPfHEE+rQoYNatmypjz76qEIKBQAAAEqqVDO5CxYs0OOPP66goKBC+xwOh8aMGaP58+frzjvvLLcCAQAAivpTPvBLSjWT+9lnn6lXr17F7o+Li9OuXbuuuygAAADgepQq5H733XdF3jqsgK+vr86cOXPdRQEAAADXo1Qh95ZbbtH+/fuL3b9v3z6FhIRcd1EAAADA9ShVyL3vvvv07LPP6ueffy607+LFi5o9e7b69u1bbsUBAAAAZVGqD54988wzWrNmjZo0aaKJEyeqadOmstlsOnz4sF577TXl5eVp5syZFVUrAAAAUCKlCrnB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0qRJqlu3rqpXr65+/frp1KlTbn0yMzM1dOhQORwOORwODR06VOfOnavgZ+fdEhMT1aFDBwUGBqp+/fp64IEHdOTIEbc+jH/FWrx4sVq3bu26oXrnzp3173//27Wf8a88iYmJstlsmjJliquN8a9Y8fHxstlsbpvT6XTtZ/wr3jfffKMhQ4aoTp06CggIUNu2bbVr1y7Xfq96DQwqTXJysvHz8zNLly41hw4dMpMnTzbVq1c3x48f93RpN5T333/fzJw507zzzjtGklm7dq3b/ueff94EBgaad955x+zfv98MHDjQhISEmOzsbFefsWPHmltuucWkpKSY3bt3m+7du5s2bdqYy5cvu/r06tXLREVFmbS0NJOWlmaioqJM3759K+tpeqV7773XJCUlmQMHDpi9e/eaPn36mIYNG5off/zR1Yfxr1jr1q0z69evN0eOHDFHjhwxTz/9tPHz8zMHDhwwxjD+leWTTz4x4eHhpnXr1mby5Mmudsa/Ys2ePdu0bNnSnD592rVlZGS49jP+FeuHH34wjRo1MiNGjDAff/yxOXr0qNm0aZP56quvXH286TUg5Faijh07mrFjx7q1NWvWzEyfPt1DFd34rg25+fn5xul0mueff97V9vPPPxuHw2Fef/11Y4wx586dM35+fiY5OdnV55tvvjFVqlQxGzZsMMYYc+jQISPJ7Nixw9Vn+/btRpL5/PPPK/hZ3TgyMjKMJJOammqMYfw9pVatWuYvf/kL419Jzp8/byIjI01KSoqJjY11hVzGv+LNnj3btGnTpsh9jH/Fe+qpp0zXrl2L3e9trwHLFSpJbm6udu3apbi4OLf2uLg4paWleagq6zl69KjS09Pdxtlutys2NtY1zrt27dKlS5fc+oSGhioqKsrVZ/v27XI4HOrUqZOrzx133CGHw8HrdZWsrCxJUu3atSUx/pUtLy9PycnJunDhgjp37sz4V5IJEyaoT58+uueee9zaGf/K8eWXXyo0NFQRERF65JFH9PXXX0ti/CvDunXrFB0drd/85jeqX7++2rVrp6VLl7r2e9trQMitJN9//73y8vIUHBzs1h4cHKz09HQPVWU9BWP5S+Ocnp6uqlWrqlatWr/Yp379+oXOX79+fV6v/58xRk8++aS6du2qqKgoSYx/Zdm/f79q1Kghu92usWPHau3atWrRogXjXwmSk5O1e/duJSYmFtrH+Fe8Tp066c0339QHH3ygpUuXKj09XTExMTp79izjXwm+/vprLV68WJGRkfrggw80duxYPfHEE3rzzTcled97wBJf63sjsdlsbo+NMYXacP3KMs7X9imqP6/X/5k4caL27dun//znP4X2Mf4Vq2nTptq7d6/OnTund955R8OHD1dqaqprP+NfMU6ePKnJkydr48aNqlatWrH9GP+K07t3b9d/t2rVSp07d9att96qFStW6I477pDE+Fek/Px8RUdHKyEhQZLUrl07HTx4UIsXL9awYcNc/bzlNWAmt5LUrVtXPj4+hf4FkpGRUehfPCi7gk/Z/tI4O51O5ebmKjMz8xf7fPfdd4XOf+bMGV4vSZMmTdK6deu0detWNWjQwNXO+FeOqlWr6rbbblN0dLQSExPVpk0bvfLKK4x/Bdu1a5cyMjLUvn17+fr6ytfXV6mpqfrf//1f+fr6usaG8a881atXV6tWrfTll1/y818JQkJC1KJFC7e25s2b68SJE5K873cAIbeSVK1aVe3bt1dKSopbe0pKimJiYjxUlfVERETI6XS6jXNubq5SU1Nd49y+fXv5+fm59Tl9+rQOHDjg6tO5c2dlZWXpk08+cfX5+OOPlZWVdVO/XsYYTZw4UWvWrNGWLVsUERHhtp/x9wxjjHJychj/CtajRw/t379fe/fudW3R0dEaPHiw9u7dq8aNGzP+lSwnJ0eHDx9WSEgIP/+VoEuXLoVuG/nFF1+oUaNGkrzwd0CJP6KG61ZwC7E33njDHDp0yEyZMsVUr17dHDt2zNOl3VDOnz9v9uzZY/bs2WMkmfnz55s9e/a4bsX2/PPPG4fDYdasWWP2799vHn300SJvX9KgQQOzadMms3v3bnP33XcXefuS1q1bm+3bt5vt27ebVq1a3fS3kBk3bpxxOBxm27Ztbrfw+emnn1x9GP+KNWPGDPPhhx+ao0ePmn379pmnn37aVKlSxWzcuNEYw/hXtqvvrmAM41/Rpk6darZt22a+/vprs2PHDtO3b18TGBjo+j3K+FesTz75xPj6+po//elP5ssvvzRvvfWWCQgIMCtXrnT18abXgJBbyV577TXTqFEjU7VqVXP77be7br2Ektu6dauRVGgbPny4MebKLUxmz55tnE6nsdvt5q677jL79+93O8fFixfNxIkTTe3atY2/v7/p27evOXHihFufs2fPmsGDB5vAwEATGBhoBg8ebDIzMyvpWXqnosZdkklKSnL1Yfwr1mOPPeb6f0i9evVMjx49XAHXGMa/sl0bchn/ilVwz1U/Pz8TGhpqBgwYYA4ePOjaz/hXvH/9618mKirK2O1206xZM7NkyRK3/d70GtiMMabk874AAACA92NNLgAAACyHkAsAAADLIeQCAADAcgi5AAAAsBxCLgAAACyHkAsAAADLIeQCAADAcgi5AAAAsBxCLgB4SLdu3TRlypRyPWd8fLzatm1bpmOPHTsmm82mvXv3lmtNAOAJvp4uAACsbMSIEVqxYkWh9i+//FJr1qyRn5+fB6oqWlhYmE6fPq26det6uhQAuG6EXACoYL169VJSUpJbW7169eTj4+Ohiorm4+Mjp9Pp6TIAoFywXAEAKpjdbpfT6XTbfHx8Ci1XCA8PV0JCgh577DEFBgaqYcOGWrJkidu5nnrqKTVp0kQBAQFq3LixZs2apUuXLpW4lszMTA0ePFj16tWTv7+/IiMjXQH82uUKI0aMkM1mK7Rt27ZNkpSbm6tp06bplltuUfXq1dWpUyfXPgDwNEIuAHiRl156SdHR0dqzZ4/Gjx+vcePG6fPPP3ftDwwM1PLly3Xo0CG98sorWrp0qV5++eUSn3/WrFk6dOiQ/v3vf+vw4cNavHhxscsTXnnlFZ0+fdq1TZ48WfXr11ezZs0kSSNHjtR///tfJScna9++ffrNb36jXr166csvv7y+QQCAcsByBQCoYO+9955q1Kjhety7d2/9/e9/L7Lvfffdp/Hjx0u6Mmv78ssva9u2ba5g+cwzz7j6hoeHa+rUqXr77bc1bdq0EtVy4sQJtWvXTtHR0a5zFMfhcMjhcEiS1qxZo9dff12bNm2S0+nU//t//0+rV6/WqVOnFBoaKkn6/e9/rw0bNigpKUkJCQklqgcAKgohFwAqWPfu3bV48WLX4+rVqxfbt3Xr1q7/ttlscjqdysjIcLX94x//0IIFC/TVV1/pxx9/1OXLlxUUFFTiWsaNG6eHHnpIu3fvVlxcnB544AHFxMT84jF79uzRsGHD9Nprr6lr166SpN27d8sYoyZNmrj1zcnJUZ06dUpcDwBUFEIuAFSw6tWr67bbbitR32vvtmCz2ZSfny9J2rFjhx555BHNmTNH9957rxwOh5KTk/XSSy+VuJbevXvr+PHjWr9+vTZt2qQePXpowoQJevHFF4vsn56ern79+mnUqFEaNWqUqz0/P18+Pj7atWtXoQ/QXT1rDQCeQsgFgBvEf//7XzVq1EgzZ850tR0/frzU56lXr55GjBihESNG6M4779Qf/vCHIkPuzz//rP79+6tZs2aaP3++27527dopLy9PGRkZuvPOO0v/ZACgghFyAeAGcdttt+nEiRNKTk5Whw4dtH79eq1du7ZU53j22WfVvn17tWzZUjk5OXrvvffUvHnzIvuOGTNGJ0+e1ObNm3XmzBlXe+3atdWkSRMNHjxYw4YN00svvaR27drp+++/15YtW9SqVSvdd9991/VcAeB6cXcFALhB9O/fX7/73e80ceJEtW3bVmlpaZo1a1apzlG1alXNmDFDrVu31l133SUfHx8lJycX2Tc1NVWnT59WixYtFBIS4trS0tIkSUlJSRo2bJimTp2qpk2bql+/fvr4448VFhZ23c8VAK6XzRhjPF0EAAAAUJ6YyQUAAIDlEHIBAABgOYRcAAAAWA4hFwAAAJZDyAUAAIDlEHIBAABgOYRcAAAAWA4hFwAAAJZDyAUAAIDlEHIBAABgOYRcAAAAWM7/B4YpDqNG2d+zAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "y_S_F=np.dstack(solution_S_F) # unpack the data\n", "final_size_S_F=y_S_F[-1, 2, :]\n", "\n", - "plt.figure(figsize=(3, 2.5))\n", + "plt.figure(figsize=(8, 4))\n", "plt.title(\"Epidemic final size distribution\")\n", + "plt.xlabel(\"Final size\")\n", + "plt.ylabel(\"Count\")\n", "plt.hist(final_size_S_F, bins=100, color=\"C0\")\n", - "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "39f93f66", + "metadata": {}, + "source": [ + "We see that 28 of the 1000 simulations (2.8%) have final sizes very close to zero.\n", + "In these cases, the chain of infections reaches stochastic extinction before an epidemic is able to take off, as can be seen when plotting a selection of these failed epidemics." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "08572965", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [], + "source": [ "# Plot failed epidemics\n", "i_success_S_F=np.where(final_size_S_F>2000)\n", "y_fail_S_F=np.delete(y_S_F, obj=i_success_S_F, axis=2) \n", - "f, ax = plt.subplots(figsize=(3, 2.5))\n", + "f, ax = plt.subplots(figsize=(8, 4))\n", "\n", "ax.set_title(\"Stochastically extinct epidemic trajectories\")\n", "ax.set_xlabel(\"Time\")\n", + "ax.set_ylabel(\"Infected count\")\n", "for i in range(min(y_fail_S_F.shape[2], 3)):\n", " ax.plot(t[0:300], y_fail_S_F[0:300,1,i], color=\"C0\", alpha=0.5)" ] }, { "cell_type": "markdown", - "id": "39f93f66", + "id": "e8c41b94", "metadata": {}, "source": [ - "We see that a fraction, just under 4%, of the simulations have final sizes very close to zero.\n", - "In these cases, the chain of infections reaches stochastic extinction before an epidemic is able to take off.\n", - "We proceed to eliminate these when plotting our simulation outputs, since we'd like to compare the output here with our deterministic results (which, by definition, no not exhibit stochastic extinction):" + "\n", + "We proceed to eliminate these when plotting our simulation outputs, since we'd like to compare the output here with our deterministic results (which, by definition, do not exhibit stochastic extinction):" ] }, { @@ -427,21 +485,10 @@ "#########################\n", "# Individual trajectories\n", "#########################\n", - "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", "\n", "# Select 50 simulations to plot\n", "i_rand=random.sample(range(y_success_S_F.shape[2]), 50)\n", "\n", - "# Plot colours\n", - "colours=[\"C1\", \"C0\", \"C2\"]\n", - "\n", - "for i in i_rand:\n", - " for j in range(y_S_F.shape[1]):\n", - " axarr[j].plot(t, y_success_S_F[:,j,i], color=colours[j], alpha=0.2)\n", - "\n", - "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_title(state)\n", - "\n", "######################\n", "# Confidence intervals\n", "######################\n", @@ -453,16 +500,33 @@ "y_S_F_hihi=np.percentile(y_success_S_F, 97.5, axis=2)\n", "y_S_F_md=np.percentile(y_success_S_F, 50, axis=2)\n", "\n", - "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", - " \n", + "\n", + "f, axarr = plt.subplots(2,3, layout='constrained', figsize=(10, 5))\n", + "\n", + "# Plot colours\n", + "colours=[\"C1\", \"C0\", \"C2\"]\n", + "\n", "for i in range(0,3):\n", - " axarr[i].fill_between(t, y_S_F_lolo[:,i], y_S_F_hihi[:,i], alpha=0.2, facecolor=colours[i])\n", - " axarr[i].fill_between(t, y_S_F_lo[:,i], y_S_F_hi[:,i], alpha=0.4, facecolor=colours[i])\n", - " axarr[i].plot(t, y_S_F_md[:,i], color=colours[i])\n", + " # Plot individual trajectories\n", + " for j in i_rand:\n", + " axarr[0][i].plot(t, y_success_S_F[:,i,j], color=colours[i], alpha=0.2)\n", + "\n", + " # Plot CI's\n", + " axarr[1][i].fill_between(t, y_S_F_lolo[:,i], y_S_F_hihi[:,i], alpha=0.2, facecolor=colours[i])\n", + " axarr[1][i].fill_between(t, y_S_F_lo[:,i], y_S_F_hi[:,i], alpha=0.4, facecolor=colours[i])\n", + " axarr[1][i].plot(t, y_S_F_md[:,i], color=colours[i])\n", "\n", + "# Add titles\n", "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_xlabel(\"Time\")\n", - "\n" + " axarr[0][idx].set_ylabel(state, rotation=0)\n", + " axarr[1][idx].set_ylabel(state, rotation=0)\n", + " axarr[0][idx].set_xlabel('Time')\n", + " axarr[1][idx].set_xlabel('Time')\n", + "\n", + "axarr[0][1].set_title(\"50 stochastic simulations with shared parameters\")\n", + "axarr[1][1].set_title(\"Median (line), 50% CI (dark shaded) and 95% CI (light shaded) over 1000 simulations\")\n", + "\n", + "plt.show()" ] }, { @@ -514,8 +578,10 @@ "y_S_R=np.dstack(solution_S_R)\n", "\n", "final_size_S_R=y_S_R[-1, 2, :]\n", - "plt.figure(figsize=(3, 2.5))\n", + "plt.figure(figsize=(8, 4))\n", "plt.title(\"Epidemic final size distribution\")\n", + "plt.xlabel(\"Final size\")\n", + "plt.ylabel(\"Count\")\n", "plt.hist(final_size_S_R, bins=100)\n", "plt.show()" ] @@ -548,21 +614,10 @@ "#########################\n", "# Individual trajectories\n", "#########################\n", - "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", "\n", "# Select 50 simulations to plot\n", "i_rand=random.sample(range(y_success_S_R.shape[2]), 50)\n", "\n", - "# Plot colours\n", - "colours=[\"C1\", \"C0\", \"C2\"]\n", - "\n", - "for i in i_rand:\n", - " for j in range(y_S_R.shape[1]):\n", - " axarr[j].plot(t, y_success_S_R[:,j,i], color=colours[j], alpha=0.2)\n", - "\n", - "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_title(state)\n", - "\n", "######################\n", "# Confidence intervals\n", "######################\n", @@ -574,15 +629,32 @@ "y_S_R_hihi=np.percentile(y_success_S_R, 97.5, axis=2)\n", "y_S_R_md=np.percentile(y_success_S_R, 50, axis=2)\n", "\n", - "f, axarr = plt.subplots(1,3, layout='constrained', figsize=(10, 2.5))\n", - " \n", + "f, axarr = plt.subplots(2,3, layout='constrained', figsize=(10, 5))\n", + "\n", + "# Plot colours\n", + "colours=[\"C1\", \"C0\", \"C2\"]\n", + "\n", "for i in range(0,3):\n", - " axarr[i].fill_between(t, y_S_R_lolo[:,i], y_S_R_hihi[:,i], alpha=0.2, facecolor=colours[i])\n", - " axarr[i].fill_between(t, y_S_R_lo[:,i], y_S_R_hi[:,i], alpha=0.4, facecolor=colours[i])\n", - " axarr[i].plot(t, y_S_R_md[:,i], color=colours[i])\n", + " # Plot individual trajectories\n", + " for j in i_rand:\n", + " axarr[0][i].plot(t, y_success_S_R[:,i,j], color=colours[i], alpha=0.2)\n", + "\n", + " # Plot CI's\n", + " axarr[1][i].fill_between(t, y_S_R_lolo[:,i], y_S_R_hihi[:,i], alpha=0.2, facecolor=colours[i])\n", + " axarr[1][i].fill_between(t, y_S_R_lo[:,i], y_S_R_hi[:,i], alpha=0.4, facecolor=colours[i])\n", + " axarr[1][i].plot(t, y_S_R_md[:,i], color=colours[i])\n", "\n", + "# Add titles\n", "for idx, state in enumerate(stateList):\n", - " axarr[idx].set_xlabel(\"Time\")" + " axarr[0][idx].set_ylabel(state, rotation=0)\n", + " axarr[1][idx].set_ylabel(state, rotation=0)\n", + " axarr[0][idx].set_xlabel('Time')\n", + " axarr[1][idx].set_xlabel('Time')\n", + "\n", + "axarr[0][1].set_title(\"50 stochastic simulations, each with randomly drawn parameters\")\n", + "axarr[1][1].set_title(\"Median (line), 50% CI (dark shaded) and 95% CI (light shaded) over 1000 simulations\")\n", + "\n", + "plt.show()" ] }, { diff --git a/docs/notebooks/model_spec.ipynb b/docs/notebooks/model_spec.ipynb index c4c6ce39..1d08ef2f 100644 --- a/docs/notebooks/model_spec.ipynb +++ b/docs/notebooks/model_spec.ipynb @@ -8,7 +8,7 @@ "# Defining an ODE system\n", "\n", "The starting point, when using PyGOM to study an ODE system, is to encapsulate the relevant information into a class {class}`.SimulateOde`.\n", - "Once defined as an instance of this class, the ODE system is prepared for the application of PyGOM's various features such as simulation and parameter fitting.\n", + "Once defined as an instance of this class, the ODE system is ready for the application of PyGOM's various features such as simulation and parameter fitting.\n", "\n", "## Equations vs Transitions\n", "\n", @@ -27,10 +27,10 @@ "\\end{aligned}$$\n", "\n", "where $i, j = \\{1,\\ldots, n\\}$ and $f_{i,j}$ are functions governing the rate at which members of group $i$ transition to group $j$.\n", - "Since flows are symmetric ($f_{i,j}=-f{i,j}$) and a group cannot flow into itself ($f_{i,i}=0$), we need only specify rates for one half of the transition matrix ($i>j$ or $j>i$).\n", + "Since flows are symmetric ($f_{i,j}=-f_{j,i}$) and a group cannot flow into itself ($f_{i,i}=0$), we need only specify rates for one half of the transition matrix ($i>j$ or $j>i$).\n", "\n", "PyGOM allows the user flexibility in choosing which of these perspectives to use, or indeed combine, in order to build their models.\n", - "If given transitions, PyGOM will automatically convert these into equations and, {doc}`as we'll see later`{unroll/unrollSimple}, it can also attempt to reverse engineer transitions from equations.\n", + "If given transitions, PyGOM will automatically convert these into equations and, {doc}`as we'll see later `, it can also attempt to reverse engineer transitions from equations.\n", "\n", "## Example: SIR model\n", "\n", @@ -45,9 +45,10 @@ "```\n", "\n", "The assumptions of the SIR model can be stated as:\n", - "1) An average member of the population makes contact sufficient to transmit or receive infection with $\\beta$ others per unit time. This fixed contact rate reflects what is referred to as *standard* incidence, as opposed to *mass-action* incidence, where contacts increase with population size as $\\beta N$ (where $N$ is the total population size).\n", - "2) The population interacts as if a well mixed continuum, such that a contact event is not between two individuals but the whole population on average.\n", - "3) The infective class is depleted through recovery at a rate $\\gamma I$.\n", + "1) An average member of the population makes contact sufficient to transmit or receive infection with $c$ others per unit time. Each of these events carries a probability, $p$, of transmission such that each individual has an average of $cp = \\beta$ infectious contacts per unit time. This fixed contact rate reflects what is referred to as *standard* incidence, as opposed to *mass-action* incidence, where contacts per person are proportional to the total population size, $N$.\n", + "2) The population interacts heterogeneously as if a well mixed continuum.\n", + "For instance, a susceptible does not have contacts with other individuals, but with the entire population on average.\n", + "3) The infective class recovers at a rate, $\\gamma$.\n", "4) No births, deaths (natural or from disease) or migration mean there is no entry into or departure from the population: $S(t)+I(t)+R(t)=N$.\n", "\n", "Under these assumptions, the rates of change of the population in each compartment (**S**usceptible, **I**nfected and **R**ecovered) are given by the following equations:\n", @@ -73,8 +74,8 @@ "\n", "## Defining the model with PyGOM\n", "\n", - "Defining the system is handled by feeding {class}`.Transition` objects into the central class we referred to at the start, {class}`.SimulateOde`.\n", - "The {class}`.Transition` class has 4 types, which are specified by the `transition_type` argument, letting {class}`.SimulateOde` know in which format we are inputting our information.\n", + "Defining the system is handled by feeding {class}`.Transition` objects into the central class, {class}`.SimulateOde`.\n", + "An instance of the {class}`.Transition` class takes one of four types, which are specified by the `transition_type` argument, letting {class}`.SimulateOde` know which type of information it is being given.\n", "This type could be `Transition` or `ODE`, as we've just been discussing, or one of two other available options, namely `Birth` and `Death` processes.\n", "The {class}`.Transition` class accepts 3 or 4 parameters depending on which type is being defined, as summarised in the below table:\n", "\n", @@ -98,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "4c80a36a", "metadata": {}, "outputs": [], @@ -130,7 +131,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "511317c9", "metadata": {}, "outputs": [], @@ -149,7 +150,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "aceb211a", "metadata": {}, "outputs": [], @@ -169,20 +170,54 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "d0fb6c20", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}- \\frac{I S \\beta}{N}\\\\- I \\gamma + \\frac{I S \\beta}{N}\\\\I \\gamma\\end{matrix}\\right]$" + ], + "text/plain": [ + "Matrix([\n", + "[ -I*S*beta/N],\n", + "[-I*gamma + I*S*beta/N],\n", + "[ I*gamma]])" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "model_ode.get_ode_eqn()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "4e8ec9a3", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}- \\frac{I S \\beta}{N}\\\\- I \\gamma + \\frac{I S \\beta}{N}\\\\I \\gamma\\end{matrix}\\right]$" + ], + "text/plain": [ + "Matrix([\n", + "[ -I*S*beta/N],\n", + "[-I*gamma + I*S*beta/N],\n", + "[ I*gamma]])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "model_tra.get_ode_eqn()" ] @@ -203,7 +238,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "0923151d", "metadata": {}, "outputs": [], @@ -221,7 +256,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "9b1546f8", "metadata": {}, "outputs": [], @@ -244,10 +279,27 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "6cc2ba1a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/latex": [ + "$\\displaystyle \\left[\\begin{matrix}- \\frac{I S \\beta}{N} + N \\mu - S \\mu\\\\- I \\gamma - I \\mu + \\frac{I S \\beta}{N}\\\\I \\gamma - R \\mu\\end{matrix}\\right]$" + ], + "text/plain": [ + "Matrix([\n", + "[ -I*S*beta/N + N*mu - S*mu],\n", + "[-I*gamma - I*mu + I*S*beta/N],\n", + "[ I*gamma - R*mu]])" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "model_ode.get_ode_eqn()" ] @@ -269,7 +321,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.15" + "version": "3.9.19" }, "vscode": { "interpreter": { diff --git a/docs/notebooks/paramfit/bvpSimple.ipynb b/docs/notebooks/paramfit/bvpSimple.ipynb index 0a746040..732badc2 100644 --- a/docs/notebooks/paramfit/bvpSimple.ipynb +++ b/docs/notebooks/paramfit/bvpSimple.ipynb @@ -37,7 +37,7 @@ "\n", "## Unknown initial conditions\n", "\n", - "First, assuming we know that the acceleration due to gravity is $g=-10ms^{-2}$, we must estimate the initial velocity ($v(t=0)$) required to ensure that the ball lands 3 seconds later.\n", + "First, assuming we know that the acceleration due to gravity is $g=10ms^{-2}$, we must estimate the initial velocity ($v(t=0)$) required to ensure that the ball lands 3 seconds later.\n", "This could be trivially solved via a quick analytical solution of the above equations resulting in $v(0)=15ms^{-1}$.\n", "Here we focus on demonstrating PyGOM's functionality, so this value will instead serve as a target we hope to reproduce.\n", "Another artefact of PyGOM, which will soon require changing, is that model parameters are automatically treated as unknowns.\n", diff --git a/docs/notebooks/paramfit/ebola_estimate.ipynb b/docs/notebooks/paramfit/ebola_estimate.ipynb new file mode 100644 index 00000000..64087a71 --- /dev/null +++ b/docs/notebooks/paramfit/ebola_estimate.ipynb @@ -0,0 +1,763 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a6b66278", + "metadata": {}, + "source": [ + "# Parameter Estimation: Example 2\n", + "\n", + "Continuing from the example in {doc}`.estimate1`, we show why estimating the parameters\n", + "for ODE's can be difficult. This is especially true if there is a lack of data\n", + "or when there are too much flexibility in the model. \n", + "\n", + "```{note}\n", + "For reproducibility purposes, only deterministic models are used here. If a stochastic algorithm is required we use a fixed seed.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "8897e924", + "metadata": {}, + "source": [ + "\n", + "## SEIR model\n", + "\n", + "We demonstrate the estimation on data collected from an Ebola outbreak in West\n", + "Africa. We use the number of deaths in Guinea and its corresponding time\n", + "the data was recorded. These data are publicly available and they can be\n", + "obtained [here](https://github.com/cmrivers/ebola). \n", + "\n", + "We provide the data here for reproducibility and ease." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "6826d12d", + "metadata": {}, + "outputs": [], + "source": [ + "# the number of deaths and cases in Guinea\n", + "\n", + "yDeath = [29.0, 59.0, 60.0, 62.0, 66.0, 70.0, 70.0, 80.0, 83.0, 86.0, 95.0, 101.0, 106.0, 108.0, 122.0, 129.0, 136.0, 141.0, 143.0, 149.0, 155.0, 157.0, 158.0,\n", + "157.0, 171.0, 174.0, 186.0, 193.0, 208.0, 215.0, 226.0, 264.0,\n", + "267.0, 270.0, 303.0, 305.0, 307.0, 309.0, 304.0, 310.0, 310.0,\n", + "314.0, 319.0, 339.0, 346.0, 358.0, 363.0, 367.0, 373.0, 377.0,\n", + "380.0, 394.0, 396.0, 406.0, 430.0, 494.0, 517.0, 557.0, 568.0, 595.0,\n", + "601.0, 632.0, 635.0, 648.0, 710.0, 739.0, 768.0, 778.0, 843.0,\n", + "862.0, 904.0, 926.0, 997.0]\n", + "\n", + "yCase = [49.0, 86.0, 86.0, 86.0, 103.0, 112.0, 112.0, 122.0, 127.0, 143.0, 151.0, 158.0, 159.0, 168.0, 197.0, 203.0, 208.0, 218.0, 224.0, 226.0, 231.0,\n", + "235.0, 236.0, 233.0, 248.0, 258.0, 281.0, 291.0, 328.0, 344.0,\n", + "351.0, 398.0, 390.0, 390.0, 413.0, 412.0, 408.0, 409.0, 406.0,\n", + "411.0, 410.0, 415.0, 427.0, 460.0, 472.0, 485.0, 495.0, 495.0,\n", + "506.0, 510.0, 519.0, 543.0, 579.0, 607.0, 648.0, 771.0, 812.0,\n", + "861.0, 899.0, 936.0, 942.0, 1008.0, 1022.0, 1074.0, 1157.0, 1199.0,\n", + "1298.0, 1350.0, 1472.0, 1519.0, 1540.0, 1553.0, 1906.0]" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "1d9b4bfb", + "metadata": {}, + "outputs": [], + "source": [ + "# the corresponding time\n", + "\n", + "t = [0.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 9.0, 10.0, 13.0, 16.0, 18.0, 20.0, 23.0, 25.0, 26.0, 29.0, 32.0, 35.0, 40.0, 42.0, 44.0, 46.0, 49.0, 51.0, 62.0, 66.0, 67.0,\n", + "71.0, 73.0, 80.0, 86.0, 88.0, 90.0, 100.0, 102.0, 106.0, 108.0,\n", + "112.0, 114.0, 117.0, 120.0, 123.0, 126.0, 129.0, 132.0, 135.0, 137.0, 140.0, 142.0, 144.0, 147.0, 149.0, 151.0, 157.0, 162.0, 167.0,\n", + "169.0, 172.0, 175.0, 176.0, 181.0, 183.0, 185.0, 190.0, 193.0,\n", + "197.0, 199.0, 204.0, 206.0, 211.0, 213.0, 218.0]" + ] + }, + { + "cell_type": "markdown", + "id": "fe8c48cf", + "metadata": {}, + "source": [ + "### Simple estimation\n", + "\n", + "First, we are going to fit a standard **SEIR** model to the data.\n", + "Details of the models can be found in {doc}`common_models` Defining the model\n", + "as usual with an approximation of what the parameters might be, here,\n", + "we choose the values to be the mid point of our feasible region (defined\n", + "by our box constraints later).\n", + "\n", + "Let's see what the data looks like:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "937db857", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import numpy\n", + "population = 1175e4\n", + "y = numpy.reshape(numpy.append(numpy.array(yCase), numpy.array(yDeath)),\n", + " (len(yCase),2), 'F')#/population\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "f, axarr = plt.subplots(1,2, layout='constrained', figsize=(10, 4))\n", + "\n", + "axarr[0].scatter(t, y[:,0])\n", + "axarr[1].scatter(t, y[:,1])\n", + "axarr[0].set_yscale('log')\n", + "axarr[1].set_yscale('log')" + ] + }, + { + "cell_type": "markdown", + "id": "07b101f6", + "metadata": {}, + "source": [ + "Let's set up model" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "5dfa5094", + "metadata": {}, + "outputs": [], + "source": [ + "# Define SIR model\n", + "from pygom import SimulateOde, Transition, TransitionType\n", + "stateList = ['S', 'E', 'I', 'R']\n", + "paramList = ['beta', 'alpha', 'gamma']\n", + "\n", + "transitionList = [Transition(origin='S', destination='E', equation='beta*S*I', transition_type=TransitionType.T),\n", + " Transition(origin='E', destination='I', equation='alpha*E', transition_type=TransitionType.T),\n", + " Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)]\n", + "\n", + "ode_obj = SimulateOde(stateList, paramList, transition=transitionList)\n", + "\n", + "theta = numpy.array([5.0, 5.0, 5.0])\n", + "ode_obj.parameters=theta\n", + "\n", + "from pygom import SquareLoss\n", + "\n", + "x0 = [1., 0., 49.0/population, 29.0/population]\n", + "\n", + "objLegrand = SquareLoss(theta, ode_obj,\n", + " t0=t[0], x0=x0,\n", + " t=t[1::], y=y[1::,:],\n", + " state_name=['I','R'],\n", + " state_weight=numpy.sqrt(population*2)) " + ] + }, + { + "cell_type": "markdown", + "id": "fdc428cc", + "metadata": {}, + "source": [ + "Now let's param" + ] + }, + { + "cell_type": "markdown", + "id": "288f8273", + "metadata": {}, + "source": [ + "\n", + "Then we optimize, first, assuming that the initial conditions are\n", + "accurate. Some relatively large bounds are used for this particular\n", + "problem.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "fc31ee5f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL\n", + " success: True\n", + " status: 0\n", + " fun: 9.045332633285773e-07\n", + " x: [ 4.919e+00 5.000e+00 5.079e+00]\n", + " nit: 10\n", + " jac: [ 9.551e-06 1.237e-08 -9.238e-06]\n", + " nfev: 11\n", + " njev: 11\n", + " hess_inv: <3x3 LbfgsInvHessProduct with dtype=float64>\n" + ] + } + ], + "source": [ + "import scipy.optimize\n", + "\n", + "boxBounds = [ (0.0,10.0), (0.0,10.0), (0.0,10.0)]\n", + "\n", + "res = scipy.optimize.minimize(fun=objLegrand.cost, jac=objLegrand.sensitivity, x0=theta, bounds=boxBounds, method='l-bfgs-b')\n", + "\n", + "print(res)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "d3e42fe2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "f = plt.figure()\n", + "\n", + "objLegrand.plot()\n", + "\n", + "plt.close()\n" + ] + }, + { + "cell_type": "markdown", + "id": "ef3374aa", + "metadata": {}, + "source": [ + "\n", + "We can see from our visual confirmation that the estimated parameters\n", + "are not exactly ideal. This is confirmed by the information returned\n", + "from the `scipy.optimize.minimize` routine, and probably caused by the\n", + "poor starting point. An attempt to find a more suitable value can be\n", + "done by some form of parameter space exploration. Given that the\n", + "evaluation of the objective function is not expensive here, we have\n", + "plenty of options to choose from. To reduce the number of packages\n", + "required to build this documentation, routines from `scipy.optimize`\n", + "remain our preferred option." + ] + }, + { + "cell_type": "markdown", + "id": "be511db4", + "metadata": {}, + "source": [ + "\n", + "### Improved initial guess" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "38badab5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 3.11038452e-09 7.85178078e-06 -3.60499243e-08]\n" + ] + } + ], + "source": [ + "resDE = scipy.optimize.differential_evolution(objLegrand.cost,\n", + "bounds=boxBounds, polish=False, seed=20921391)\n", + "\n", + "print(objLegrand.sensitivity(resDE['x']))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "9f68ff44", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "f = plt.figure()\n", + "\n", + "objLegrand.plot()\n", + "\n", + "plt.close()" + ] + }, + { + "cell_type": "markdown", + "id": "d06e8bdf", + "metadata": {}, + "source": [ + "\n", + "Looking at the output of the estimates (below this paragraph), we can\n", + "see our inference on Ebola is wrong when compared to the *known* values\n", + "(from field observations) even though the graphs looks *\\`\\`reasonable\"*.\n", + "Namely, $\\gamma^{-1}$, the third parameter in the vector below, our time\n", + "from infectiousness to death, is within the expected range but $\\alpha^{-1}$\n", + "(second parameter), the incubation period, is a lot higher than expected.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "3f01c604", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([7.13160861e-01, 1.88609866e+03, 8.00526800e+01])" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1/resDE['x']" + ] + }, + { + "cell_type": "markdown", + "id": "4bc57a74", + "metadata": {}, + "source": [ + "\n", + "### Multimodal surface\n", + "\n", + "A reason for this type of behavior is that we simply lack the\n", + "information/data to make proper inference. Without data on the state\n", + "$E$, the parameters $\\beta,\\alpha$ for the two states $I$ and $E$ are\n", + "dependent only on observations on $I$. Hence, some other random\n", + "combination of $\\beta,\\alpha$ that is capable of generating realizations\n", + "close to observations in $I$ is feasible. In such cases, the only\n", + "requirement is that there exist some $\\gamma$ in the feasible region\n", + "that can compensate for the ill suited $\\beta,\\alpha$. For example, we\n", + "know (obtained elsewhere and not shown here) that there is another set\n", + "of parameters capable of generating a similar looking curves as before.\n", + "Note the reversal of magnitude in $\\beta$ and $\\alpha$.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "f4797fe3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.90984074647533e-08" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "objLegrand.cost([3.26106524e+00, 2.24798702e-04, 1.23660721e-02])\n", + "\n", + "# objLegrand.cost([ 0.02701867, 9.00004776, 0.01031861])\n", + "# similar graph\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0573ccf8", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "objLegrand.plot()" + ] + }, + { + "cell_type": "markdown", + "id": "ce36ae9e", + "metadata": {}, + "source": [ + "### With initial values as parameters\n", + "\n", + "The assumption that the whole population being susceptible is\n", + "an overestimate, therefore we want to estimate the initial conditions of the\n", + "ODEs as well. Given previous estimates of the parameters\n", + "$\\hat{\\beta}, \\hat{\\alpha}, \\hat{\\gamma}$ it is appropriate to start our\n", + "initial guess there.\n", + "\n", + "Furthermore, given that we now estimate the initial values for all the\n", + "states, we can use the first time point as our observation. So our time\n", + "begins at $t = -1$ where our observations include the previous initial\n", + "condition, i.e. 49 and 29 for the number of cases and death at $t = 0$\n", + "respectively. The following code block demonstrates how we would do\n", + "that; feel free to try it out yourself to see the much improved result.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "fe0f36b4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[5.0, 5.0, 5.0, 0.99999999, 0.0, 4.170212765957447e-06, 2.468085106382979e-06]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "thetaIV = theta.tolist() + x0\n", + "\n", + "thetaIV[3] -= 1e-8 # to make sure that the initial guess satisfies the constraints\n", + "\n", + "thetaIV\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "2a07dc02", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: Optimization terminated successfully.\n", + " success: True\n", + " fun: 6.267485095752834\n", + " x: [ 3.850e+00 2.211e-02 4.114e+00 6.482e-01\n", + " 2.643e-06 4.215e-06 1.967e-05]\n", + " nit: 99\n", + " nfev: 10500\n", + " population: [[ 3.850e+00 2.211e-02 ... 4.215e-06 1.967e-05]\n", + " [ 4.083e+00 6.271e+00 ... 8.164e-06 1.845e-05]\n", + " ...\n", + " [ 4.550e+00 7.734e+00 ... 5.920e-06 1.729e-05]\n", + " [ 4.326e+00 3.862e-03 ... 8.806e-06 1.406e-05]]\n", + " population_energies: [ 6.267e+00 6.619e+00 ... 6.721e+00 6.385e+00]\n" + ] + } + ], + "source": [ + "objLegrand = SquareLoss(theta, ode_obj,\n", + " t0=t[0], x0=x0,\n", + " t=t[1::], y=y[1::,:],\n", + " state_name=['I','R'],\n", + " state_weight=numpy.sqrt(population*2)) \n", + "\n", + "boxBoundsIV = boxBounds + [(0.,1.), (0.,1.), (0.,1.), (0.,1.)]\n", + "\n", + "resDEIV = scipy.optimize.differential_evolution(objLegrand.costIV, bounds=boxBoundsIV, polish=False, seed=20921391)\n", + "\n", + "print(resDEIV)" + ] + }, + { + "cell_type": "markdown", + "id": "3331a258", + "metadata": {}, + "source": [ + "objLegrand.plot()\n" + ] + }, + { + "cell_type": "markdown", + "id": "2408c495", + "metadata": {}, + "source": [ + "## Legrand Ebola SEIHFR Model\n", + "\n", + "Next, we demonstrate the estimation on a model that has been widely used in\n", + "the 2014 Ebola outbreak in west Africa {citets}`Legrand`. This model has been\n", + "defined in {mod}`.common_models`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "4f726a4a", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'delta' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[21], line 9\u001b[0m\n\u001b[0;32m 2\u001b[0m ode \u001b[38;5;241m=\u001b[39m common_models\u001b[38;5;241m.\u001b[39mLegrand_Ebola_SEIHFR()\n\u001b[0;32m 4\u001b[0m \u001b[38;5;66;03m# initial guess from the paper that studied the outbreak in Congo\u001b[39;00m\n\u001b[0;32m 6\u001b[0m theta \u001b[38;5;241m=\u001b[39m numpy\u001b[38;5;241m.\u001b[39marray([\u001b[38;5;241m0.588\u001b[39m,\u001b[38;5;241m0.794\u001b[39m,\u001b[38;5;241m7.653\u001b[39m, \u001b[38;5;66;03m# the beta \u001b[39;00m\n\u001b[0;32m 7\u001b[0m \u001b[38;5;241m10.0\u001b[39m,\u001b[38;5;241m9.6\u001b[39m,\u001b[38;5;241m5.0\u001b[39m,\u001b[38;5;241m2.0\u001b[39m, \u001b[38;5;66;03m# the omega\u001b[39;00m\n\u001b[0;32m 8\u001b[0m \u001b[38;5;241m7.0\u001b[39m,\u001b[38;5;241m0.81\u001b[39m,\u001b[38;5;241m0.80\u001b[39m, \u001b[38;5;66;03m# alpha,\u001b[39;00m\n\u001b[1;32m----> 9\u001b[0m \u001b[43mdelta\u001b[49m, \n\u001b[0;32m 10\u001b[0m theta,\n\u001b[0;32m 11\u001b[0m \u001b[38;5;241m100.\u001b[39m,\u001b[38;5;241m1.0\u001b[39m]) \u001b[38;5;66;03m# kappa,intervention time\u001b[39;00m\n\u001b[0;32m 13\u001b[0m \u001b[38;5;66;03m# initial conditions, note that we have a 0.0 at the end because the model is a non-automonous ODE which we have converted the time component out of\u001b[39;00m\n\u001b[0;32m 15\u001b[0m x0 \u001b[38;5;241m=\u001b[39m numpy\u001b[38;5;241m.\u001b[39marray([population, \u001b[38;5;241m0.0\u001b[39m, \u001b[38;5;241m49.0\u001b[39m, \u001b[38;5;241m0.0\u001b[39m, \u001b[38;5;241m0.0\u001b[39m, \u001b[38;5;241m29.0\u001b[39m, \u001b[38;5;241m0.0\u001b[39m])\u001b[38;5;241m/\u001b[39mpopulation\n", + "\u001b[1;31mNameError\u001b[0m: name 'delta' is not defined" + ] + } + ], + "source": [ + "from pygom import common_models\n", + "ode = common_models.Legrand_Ebola_SEIHFR()\n", + "\n", + "# initial guess from the paper that studied the outbreak in Congo\n", + "\n", + "theta = numpy.array([0.588,0.794,7.653, # the beta \n", + " 10.0,9.6,5.0,2.0, # the omega\n", + " 7.0,0.81,0.80, # alpha,\n", + " delta, \n", + " theta,\n", + " 100.,1.0]) # kappa,intervention time\n", + "\n", + "# initial conditions, note that we have a 0.0 at the end because the model is a non-automonous ODE which we have converted the time component out of\n", + "\n", + "x0 = numpy.array([population, 0.0, 49.0, 0.0, 0.0, 29.0, 0.0])/population\n", + "\n", + "ode.parameters = theta\n", + "\n", + "ode.initial_values = (x0, t[0])\n", + "\n", + "objLegrand = SquareLoss(theta, ode, x0, t[0], t[1::], y[1::,:], \n", + " ['I','R'], numpy.sqrt([population]*2))" + ] + }, + { + "cell_type": "markdown", + "id": "71d2d4b6", + "metadata": {}, + "source": [ + "Now, it is important to set additional constraints accurately because a\n", + "simple box constraint is much larger than the feasible set. Namely,\n", + "$\\omega_{I}, \\omega_{D}$ are the time taken from onset until end of\n", + "infectious/death, which has to be bigger than $\\omega_{H}$, onset to\n", + "hospitalization given the nature of the disease. Therefore, we create\n", + "extra inequality constraints in addition to the box constraints" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d928c542", + "metadata": {}, + "outputs": [], + "source": [ + "boxBounds = [(0.001, 100.), #beta_I \n", + " (0.001, 100.), # beta_H\n", + " (0.001, 100.), # beta_F \n", + " (0.001, 100.), # omega_I \n", + " (0.001, 100.), # omega_D \n", + " (0.001, 100.), # omega_H \n", + " (0.001, 100.), # omega_F\n", + " (0.001, 100.), # alpha^{-1} \n", + " (0.0001, 1.), # delta \n", + " (0.0001, 1.), # theta .….: (0.001, 1000.), # kappa\n", + " (0.,218.) # intervention time \n", + " ]\n", + "\n", + "cons = ({'type': 'ineq', 'fun' : lambda x: numpy.array([x[3]-x[5], x[4]-x[5]])})" + ] + }, + { + "cell_type": "markdown", + "id": "df3e4a0a", + "metadata": {}, + "source": [ + "We can now try to find the optimal values, but because this is a\n", + "difficult problem that can take a very long time without guarantee on\n", + "the quality of solution." + ] + }, + { + "cell_type": "markdown", + "id": "e20c8987", + "metadata": {}, + "source": [ + "res = scipy.optimize.minimize(fun=objLegrand.cost, jac=objLegrand.sensitivity, \n", + " x0=theta, constraints=cons, bounds=boxBounds, method='SLSQP')\n", + "\n", + "print(res)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "b9e7a7d7", + "metadata": {}, + "source": [ + "objLegrand.plot()" + ] + }, + { + "cell_type": "markdown", + "id": "1d0c6889", + "metadata": {}, + "source": [ + "The estimated parameters are very much unrealistic given that\n", + "a lot of them are near the boundaries. It is also known from other\n", + "sources that some of the epidemiology properties of Ebola, with\n", + "incubation period of around 2 weeks and a mortality rate of around 80\n", + "percent.\n", + "\n", + "As the estimate does not appear to provide anything sensible, we also\n", + "provide a set of values previously obtained (that looks semi-reasonable)\n", + "here plot the epidemic curve with the observations layered on top.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "b383ece7", + "metadata": {}, + "source": [ + "theta = numpy.array([3.96915071e-02, 1.72302620e+01, 1.99749990e+01, 2.67759445e+01, \n", + " 4.99999990e+01, 5.56122691e+00, 4.99999990e+01, 8.51599523e+00, \n", + " 9.99999000e-01, 1.00000000e-06, 3.85807562e+00, 1.88385318e+00])\n", + "\n", + "print(objLegrand.cost(theta))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f9232353", + "metadata": { + "tags": [ + "hide-input" + ], + "vscode": { + "languageId": "javascript" + } + }, + "outputs": [], + "source": [ + "solution = ode.integrate(t[1::])\n", + "\n", + "f, axarr = plt.subplots(2,3)\n", + "\n", + "axarr[0,0].plot(t, solution[:,0]);\n", + "\n", + "axarr[0,0].set_title('Susceptible');\n", + "\n", + "axarr[0,1].plot(t, solution[:,1]);\n", + "\n", + "axarr[0,1].set_title('Exposed');\n", + "\n", + "axarr[0,2].plot(t, solution[:,2]);\n", + "\n", + " axarr[0,2].plot(t, y[:,0], 'r');\n", + "\n", + "axarr[0,2].set_title('Infectious');\n", + "\n", + "axarr[1,0].plot(t, solution[:,3]);\n", + "\n", + "axarr[1,0].set_title('Hospitalised');\n", + "\n", + "axarr[1,1].plot(t, solution[:,4]);\n", + "\n", + "axarr[1,1].set_title('Awaiting Burial');\n", + "\n", + "axarr[1,2].plot(t, solution[:,5]);\n", + "\n", + "axarr[1,2].plot(t, y[:,1], 'r');\n", + "\n", + "axarr[1,2].set_title('Removed');\n", + "\n", + "f.text(0.5, 0.04, 'Days from outbreak', ha='center');\n", + "\n", + "f.text(0.01, 0.5, 'Population', va='center', rotation='vertical');\n", + "\n", + "f.tight_layout();\n", + "\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/notebooks/paramfit/mle_ci_theory.ipynb b/docs/notebooks/paramfit/mle_ci_theory.ipynb new file mode 100644 index 00000000..dc3d264c --- /dev/null +++ b/docs/notebooks/paramfit/mle_ci_theory.ipynb @@ -0,0 +1,483 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "57f2bb3f", + "metadata": {}, + "source": [ + "# Confidence Interval of Estimated Parameters\n", + "\n", + "The easiest way to do this is by invoking the normality argument and use Fisher information of the likelihood.\n", + "As explained previously at the bottom of {ref}`gradient:hessian`, we can find the Hessian, $\\mathbf{H}$, or the approximated Hessian for the estimated parameters.\n", + "From the Cramer--Rao inequality, we know that\n", + "\n", + "$$Var(\\hat{\\theta}) \\ge \\frac{1}{I(\\theta)},$$\n", + "\n", + "where $I(\\theta)$ is the Fisher information, which is the Hessian subject to regularity condition.\n", + "Given the Hessian, computing the confidence intervals is trivial.\n", + "Note that this is also known as the asymptotic confidence interval where the normality comes from invoking the CLT.\n", + "There are other ways of obtaining a confidence intervals, we will the ones implemented in the package." + ] + }, + { + "cell_type": "markdown", + "id": "f4d8f8c5", + "metadata": {}, + "source": [ + "## Asymptotic\n", + "\n", + "When the estimate is obtained say, under a square loss or a normal\n", + "assumption, the corresponding likelihood can be written down. In\n", + "such a case, the likelihood ratio test under a Chi--squared distribution is\n", + "\n", + "$$2 (\\mathcal{L}(\\hat{\\boldsymbol{\\theta}}) - \\mathcal{L}(\\boldsymbol{\\theta})) \\le \\chi_{1 - \\alpha}^{2}(k)$$\n", + "\n", + "where $1-\\alpha$ is the size of the confidence region and $k$ is the\n", + "degree of freedom. The corresponding asymptotic confidence interval for\n", + "parameter $j$ can be derived as\n", + "\n", + "$$\\hat{\\theta}_{j} \\pm \\sqrt{\\chi_{1 - \\alpha}^{2}(k) H_{i,i}}.$$\n", + "\n", + "A point-wise confidence interval is obtained when $k = 1$. We assume in\n", + "our package that a point-wise confidence interval is desired. This can be\n", + "obtained with the following steps.\n" + ] + }, + { + "cell_type": "markdown", + "id": "19e92acb", + "metadata": {}, + "source": [ + "\n", + "## Profile Likelihood\n", + "\n", + "Another approach to calculate the confidence interval is to tackle one\n", + "parameter at a time, treating the rest of them as nuisance parameters,\n", + "hence the term *profile*. Let $\\mathcal{L}(\\boldsymbol{\\theta})$ be our\n", + "log--likelihood with parameter $\\boldsymbol{\\theta}$. Element\n", + "$\\theta_{j}$ is our parameter of interest and $\\boldsymbol{\\theta}_{-j}$\n", + "represents the complement such that\n", + "$\\boldsymbol{\\theta} = \\theta_{j} \\cup \\boldsymbol{\\theta}_{-j}$. For\n", + "simply models such as linear regression with only regression\n", + "coefficients $\\boldsymbol{\\beta}$, then\n", + "$\\boldsymbol{\\theta} = \\boldsymbol{\\beta}$.\n", + "\n", + "To shorten the notation, let\n", + "\n", + "$$\\mathcal{L}(\\boldsymbol{\\theta}_{-j} \\mid \\theta_{j}) = \\max \\mathcal{L}(\\boldsymbol{\\theta}_{-j} \\mid \\theta_{j})$$\n", + "\n", + "which is the maxima of $\\boldsymbol{\\theta}_{-j}$ given $\\theta_{j}$.\n", + "$\\hat{\\boldsymbol{\\theta}}$ denotes the MLE of the parameters as usual.\n", + "The profile--likelihood based confidence interval for $\\theta_{j}$ is\n", + "defined as\n", + "\n", + "$$\\begin{aligned}\n", + "\\theta_{j}^{U} &= \\sup \\left\\{ \\mathcal{L}(\\hat{\\boldsymbol{\\theta}}) - \\mathcal{L}(\\boldsymbol{\\theta} \\mid \\theta_{j}) \\le \\frac{1}{2} \\chi_{1 - \\alpha}^{2}(1) \\right\\} \\\\\n", + "\\theta_{j}^{L} &= \\inf \\left\\{ \\mathcal{L}(\\hat{\\boldsymbol{\\theta}}) - \\mathcal{L}(\\boldsymbol{\\theta} \\mid \\theta_{j}) \\le \\frac{1}{2} \\chi_{1 - \\alpha}^{2}(1) \\right\\}\n", + "\\end{aligned}$$\n", + "\n", + "where again we have made use of the normal approximation, but without\n", + "imposing symmetry. The set of equations above automatically implies that\n", + "the interval width is $\\theta_{j}^{U} - \\theta_{j}^{L}$ and\n", + "\n", + "$$\\mathcal{L}(\\hat{\\boldsymbol{\\theta}}) - \\frac{1}{2} \\chi_{1-\\alpha}^{2}(1) - \\mathcal{L}(\\boldsymbol{\\theta} \\mid \\theta_{j}) = 0.$$\n", + "\n", + "As mentioned previously, $\\boldsymbol{\\theta}_{-j}$ is the maximizer of\n", + "the nuisance parameters, which has a gradient of zero. Combining this\n", + "with the equation above yields a non-linear system of equations of size\n", + "$p$,\n", + "\n", + "$$\\begin{aligned}\n", + "g(\\boldsymbol{\\theta}) = \\left[ \\begin{array}{c} \\mathcal{L}(\\boldsymbol{\\theta} \\mid \\theta_{j}) - c \\\\ \\frac{\\partial \\mathcal{L}(\\boldsymbol{\\theta} \\mid \\theta_{j})}{\\partial \\boldsymbol{\\theta}_{-j}} \\end{array} \\right] = 0\n", + "\\end{aligned}$$\n", + "\n", + "where\n", + "$c = \\mathcal{L}(\\hat{\\boldsymbol{\\theta}}) + \\frac{1}{2} \\chi_{1-\\alpha}^{2}(1)$.\n", + "Solving this set of system of equations only need simple Newton like\n", + "steps, possibly with correction terms as per {cite:t}`Venzon1988`. We\n", + "provide a function to obtain such estimate, {func}`ci.profile`" + ] + }, + { + "cell_type": "markdown", + "id": "ecd49905", + "metadata": {}, + "source": [ + "but unfortunately this is not accurate most of the time due to the\n", + "complicated surface at locations not around $\\hat{\\theta}$. This is a\n", + "common scenario for non--linear least square problems because the\n", + "Hessian is not guaranteed to be a PSD everywhere. Therefore, a safeguard\n", + "is in place to obtain the $\\theta_{j}^{U},\\theta_{j}^{L}$ by iteratively updating $\\theta_{j}$ and find the solution to `nuisanceOptim`.\n", + "\n", + "#TODO what is nuisance optim?\n", + "\n", + "Furthermore, we also provide the functions necessary to obtain the\n", + "estimates such as the four below." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e58e47ee", + "metadata": {}, + "outputs": [], + "source": [ + "i = 0\n", + "\n", + "funcF = ci._profileF(xhat, i, 0.05, objSIR)\n", + "\n", + "funcG = ci._profileG(xhat, i, 0.05, objSIR)\n", + "\n", + "funcGC = ci._profileGSecondOrderCorrection(xhat, i, alpha, objSIR)\n", + "\n", + "funcH = ci._profileH(xhat, i, 0.05, objSIR)" + ] + }, + { + "cell_type": "markdown", + "id": "f2428994", + "metadata": {}, + "source": [ + "Where $i$ is the index of the parameter of interest. {func}`_profileF` is the\n", + "squared norm of {obj}`obj`, which easy the optimization process for solvers\n", + "which requires a converted form from system of equations to non-linear\n", + "least squares. {func}`_profileG` is the system of equations of {obj}`obj`,\n", + "and {func}`_profileH` is the derivative of {obj}`obj`.\n", + "\n", + "$$\\begin{aligned}\n", + "\\nabla g(\\boldsymbol{\\theta}) = \\left[ \\begin{array}{c} \\frac{\\partial \\mathcal{L}(\\boldsymbol{\\theta} \\mid \\theta_{j})}{\\partial \\theta_{j}} \\\\ \\frac{\\partial^{2} \\mathcal{L}(\\boldsymbol{\\theta} \\mid \\theta_{j})}{\\partial \\boldsymbol{\\beta}_{-j} \\partial \\theta_{j}} \\end{array} \\right]\n", + "\\end{aligned}$$\n", + "\n", + "{func}`_profileGSecondOrderCorrection` is the second order correction {cite}Venzon1988.\n", + "\n", + "## Geometric profile likelihood\n", + "\n", + "Due to the difficulty in obtain a profile likelihood via the standard\n", + "Newton like steps, we also provide a way to generate a similar result\n", + "using the geometric structure of the likelihood surface. We follow the\n", + "method in {cite:t}`Moolgavkar1987`, which involves solving a set of\n", + "differential equations\n", + "\n", + "$$\\begin{aligned}\n", + "\\frac{d\\beta_{j}}{dt} &= k g^{-1/2} \\\\\n", + "\\frac{d\\boldsymbol{\\beta}_{-j}}{dt} &= \\frac{d\\boldsymbol{\\beta}_{-j}}{d\\beta_{j}} \\frac{d\\beta_{j}}{dt},\n", + "\\end{aligned}$$\n", + "\n", + "where $k = \\Phi(1-\\alpha)$ is the quantile we want to obtain under a\n", + "normal distribution, and\n", + "\n", + "$$\\begin{aligned}\n", + "g = J_{\\beta_{j}}^{\\top} I^{\\boldsymbol{\\beta}} J_{\\beta_{j}}, \\quad J_{\\beta_{j}} = \\left( \\begin{array}{c} 1 \\\\ \\frac{d\\boldsymbol{\\beta}_{-j}}{d\\beta_{j}} \\end{array} \\right).\n", + "\\end{aligned}$$\n", + "\n", + "Here, $J_{\\beta_{j}}$ is the Jacobian between $\\beta_{j}$ and\n", + "$\\boldsymbol{\\beta}_{-j}$ with the term\n", + "\n", + "$$\\frac{d\\boldsymbol{\\beta}_{-j}}{d\\beta_{j}} = -\\left( \\frac{\\partial^{2} \\mathcal{L}}{\\partial \\boldsymbol{\\beta}_{-j}\\partial \\boldsymbol{\\beta}_{-j}^{\\top} } \\right)^{-1} \\frac{\\partial^{2} \\mathcal{L}}{\\partial \\beta_{j} \\partial \\beta_{-j}^{\\top}}$$\n", + "\n", + "and hence the first element is $1$ (identity transformation).\n", + "$I^{\\boldsymbol{\\beta}}$ is the Fisher information of\n", + "$\\boldsymbol{\\beta}$, which is\n", + "\n", + "$$I^{\\boldsymbol{\\beta}} = \\frac{\\partial \\boldsymbol{\\theta}}{\\partial \\boldsymbol{\\beta}^{\\top}} \\Sigma^{\\boldsymbol{\\theta}(\\boldsymbol{\\beta})} \\frac{\\partial \\boldsymbol{\\theta}}{\\partial \\boldsymbol{\\beta}}.$$\n", + "\n", + "It is simply $\\Sigma^{\\boldsymbol{\\beta}}$ if\n", + "$\\boldsymbol{\\theta} = \\boldsymbol{\\beta}$. Different Fisher information\n", + "can be used for $\\Sigma^{\\boldsymbol{\\beta}}$ such as the expected or\n", + "observed, at $\\hat{\\boldsymbol{\\beta}}$ or $\\boldsymbol{\\beta}$. After\n", + "some trivial algebraic manipulation, we can show that our ODE boils\n", + "downs to\n", + "\n", + "$$\\begin{aligned}\n", + "\\left[ \\begin{array}{c} \\frac{d\\beta_{j}}{dt} \\\\ \\frac{d\\boldsymbol{\\beta_{-j}}}{dt} \\end{array} \\right] = k \\left[ \\begin{array}{c} 1 \\\\ -A^{-1}w \\end{array} \\right] \\left( v - w^{\\top}A^{-1}w \\right)^{-1/2}\n", + "\\end{aligned}$$\n", + "\n", + "where the symbols on the RHS above correspond to partitions in the\n", + "Fisher information\n", + "\n", + "$$\\begin{aligned}\n", + "I^{\\boldsymbol{\\beta}} = \\left[ \\begin{array}{cc} v & w^{\\top} \\\\ w & A \\end{array} \\right].\n", + "\\end{aligned}$$\n", + "\n", + "The integration is perform from $t = 0$ to $1$ and is all handled\n", + "internally via {class}`geometric`." + ] + }, + { + "cell_type": "markdown", + "id": "75d6f904", + "metadata": {}, + "source": [ + "\n", + "## Bootstrap\n", + "\n", + "This is perhaps the favorite method to estimate confidence intervals for\n", + "a lot of people. Although there are many ways to implement bootstrap,\n", + "semi-parametric is the only logical choice (even though the underlying\n", + "assumptions may be violated at times). As we have only implemented OLS\n", + "type loss functions in this package, the parametric approach seem to be\n", + "inappropriate when there is no self-efficiency guarantee.\n", + "Non-parametric approaches requires at least a conditional independence\n", + "assumption, something easily violated by our **ODE**. Block bootstrap is\n", + "an option but we are also aware that the errors of an **ODE** can be\n", + "rather rigid, and consistently over/under estimate at certain periods of\n", + "time.\n", + "\n", + "#TODO refs for bootstrap?\n", + "\n", + "When we say semi-parametric, we mean the exchange of errors between the\n", + "observations. Let our raw error be\n", + "\n", + "$$\\varepsilon_{i} = y_{i} - \\hat{y}_{i}$$\n", + "\n", + "where $\\hat{y}_{i}$ will be the prediction under\n", + "$\\hat{\\boldsymbol{\\theta}}$ under our model. Then we construct a new set\n", + "of observations via\n", + "\n", + "$$y_{i}^{\\ast} = \\hat{y}_{i} + \\varepsilon^{\\ast}, \\quad \\varepsilon^{\\ast} \\sim \\mathcal{F}$$\n", + "\n", + "with $\\mathcal{F}$ being the empirical distribution of the raw errors. A\n", + "new set of parameters $\\theta^{\\ast}$ are then found for the\n", + "bootstrapped samples, and we obtain the $\\alpha$ confidence interval by\n", + "taking the $\\alpha/2$ quantiles. Invoking the corresponding python function\n", + "yields our bootstrap estimates. Unlike {func}`asymptotic`, the bounds here are\n", + "used when estimating the parameters of each bootstrap samples. An error\n", + "may be returned if estimation failed for any of the bootstrap samples." + ] + }, + { + "cell_type": "markdown", + "id": "0a8e31f0", + "metadata": {}, + "source": [ + "The additional information here can be used to compute the bias, tail\n", + "effects and test against the normality assumption. If desired, a\n", + "simultaneous confidence interval can also be approximated empirically.\n", + "Note however that because we are using a semi-parameter method here, if\n", + "the model specification is wrong then the resulting estimates for the\n", + "bias is also wrong. The confidence interval still has the normal\n", + "approximation guarantee if the number of samples is large.\n", + "\n", + "In this case, because the error in the observation is extremely small,\n", + "the confidence interval is narrow." + ] + }, + { + "cell_type": "markdown", + "id": "9edc8b6b", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "## Comparison Between Methods\n", + "\n", + "Although we have shown the numerical values for the confidence interval\n", + "obtained using different methods, it can be hard to comprehend how they\n", + "vary. As they say, a picture says a million word, and given that this\n", + "particular model only has two parameters, we can obtain inspect and\n", + "compare the methods visually via a contour plot. The code to perform\n", + "this is shown below but the code block will not be run to save time and\n", + "space.\n", + "\n", + "In the plot above, the bootstrap confidence interval were so close to\n", + "the MLE, it is impossible to distinguish the two on such a coarse scale.\n", + "\n", + "Furthermore, because the geometric confidence interval is the result of\n", + "an integration, we can trace the path that lead to the final output that\n", + "was shown previously. Again, we are space conscious (and time\n", + "constrained) so the code block below will not be run." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "6cef48a9", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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rERERKQWa1XJULCGlYiIiNRirSoZCv4UIiIiIrVYq0qGggkrERERsVaVDBoTViIionqOtapk6FjDSkREVM+xVpUMHX8iERER1XOsVSVDx4SViIionildr5odm81aVTJoLAkgIiKqR+T1qkVPiuCzxQcJwQkwkhrBSGYEmZdMsY21qmRImLASERHVI2XVq7be0xqm9qasVSWDxJ9ORERE9UhZ9arWftasVSWDxYSViIiojuLcqlRXMGElIiKqgzi3KtUlrGElIiKqgzi3KtUl/DlFRERUB3FuVapLmLASERHVAZxbleoylgQQERHVcpxbleo6JqxERES1HOdWpbqOP7OIiIhqEXVTVXFuVarrmLASERHVEmVNVcV6VarrmLASERHVEqUv/efeyEXRkyIA4NyqVKdJhBCipoOoSVlZWbC1tUVmZiZsbGxqOhwiIqJyZUZlKupUASDgdABsu9oiPy1fMbdqblIu61XrEOYq7GElIiIyWNpMVcW5Vaku4ywBREREBohTVRH9gwkrERGRAeJUVUT/4E8yIiIiA8Spqoj+wYSViIjIAHBpVaKysSSAiIiohrFelah8TFiJiIhqGOtVicrHn2lERETViEurEmmPCSsREVE14dKqRLphwkpERFRNuLQqkW4M7pMQHh4OT09PyGQydOjQASdPniy3/datW+Hn5wcLCws4OztjwoQJSE9Pr6ZoiYiIylb68r+RuVGZl/79jvnB/4Q/bLvawv+EP/yO+bEEgOj/GVTCumPHDsyePRuLFi1CdHQ0evTogf79+yMxMVFt+1OnTmHcuHGYOHEi4uLisHPnTly4cAGTJk2q5siJiIiUqbv8H909GvGvxiu149KqRBUzqIR11apVmDhxIiZNmgQfHx989tlncHNzw5o1a9S2P3v2LJo2bYpZs2bB09MT3bt3x+TJk3Hx4sVqjpyIiEiZusv/xbnFMJbx0j+RtgzmE5Kfn49Lly4hKChIaXtQUBCioqLU3qdr1664c+cODh48CCEE7t+/j127dmHgwIFlPk5eXh6ysrKU/hEREembupH/vtt84X/Sn5f+ibRkMAlrWloaioqK4OTkpLTdyckJKSkpau/TtWtXbN26FaNHj4aZmRkaN24MOzs7rF69uszHCQsLg62treKfm5ubXp8HERHVT5quVFWcU8xL/0RaMpiEVU4ikSj9LYRQ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g0lY5SQSidLfQgiVbeps374dS5cuxY4dO+Do6Fhmu3fffReZmZmKf0lJSZWOmdTLOpeFS90vaZSsOgU7of3p9pyyioiIiFQYzLRWDRs2hLGxsUpvampqqkqva2k7duzAxIkTsXPnTrz44ovltpVKpZBKpZWOl8qnSb2qRTsLNBrWCA79HZioEhERUZkMpofVzMwMHTp0QEREhNL2iIgIdO3atcz7bd++HePHj8e2bdswcODAqg6TNKBJvar9S/boGNsRnks9mawSERFRuQymhxUA5s6di+DgYAQGBqJLly746quvkJiYiClTpgB4djn/7t272Lx5M4Bnyeq4cePw+eefo3PnzoreWXNzc9ja2tbY86iPss5l4enfT3E3/C6yz3IRACIiItIfg0pYR48ejfT0dCxbtgzJyclo06YNDh48CA8PDwBAcnKy0pys69atQ2FhIaZPn47p06crtoeEhGDTpk3VHX69pc10VU7BThxURURERFoxqHlYawLnNqscbWYAaLaqGS//ExERaYm5ioH1sFLtommyyhIAIiIiqgyDGXRFtQuTVSIiIqouTFhJK9rOrcpklYiIiCqLJQGkkaxzWbg69yqyo8qfAcC6izVcp7rCooUF61WJiIhIL5iwUoU0nQWAl/+JiIioKjBhpXKxVpWIiIhqGmtYqUyaJqusVSUiIqKqxB5WUpF1LgtX511F9uny61U5tyoRERFVByaspKDpwCqAK1YRERFR9WHCSgA0H1hl0c4Crb5qxV5VIiIiqjZMWIkDq4iIiMigcdBVPceBVURERGTo2MNaT3FgFREREdUWTFjrGQ6sIiIiotqGCWs9woFVREREVBsxYa0nOLCKiIiIaisOuqoHOLCKiIiIajP2sNZxmiSrHFhFREREhowJax2l6SwAHFhFREREho4Jax2j6SwAHFhFREREtQUT1jpE01kAOLCKiIiIahMmrHUEZwEgIiKiuoqzBNQBnAWAiIiI6jL2sNZiXF6ViIiI6gMmrLWUpvWqnAWAiIiIajsmrLWQJiUAnAWAiIiI6gomrLWMJskqB1YRERFRXcJBV7WIJskqB1YRERFRXcMe1lpAk8FVHFhFREREdRUTVgOnyeAqlgAQERFRXcaSAAMWP47JKhERERETVgOVvD4ZqVuYrBIRERGxJMAAaVIGwPlViYiIqL5gwmpAOLiKiIiI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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure()\n", + "\n", + "#CS = plt.contour(xi, yi, zi, linewidth=0.5)\n", + "\n", + "#plt.clabel(CS, fontsize=10, inline=1)\n", + "\n", + "l1 = plt.scatter(xLList[0][:,0], xLList[0][:,1], marker='o', c='m', s=10);\n", + "\n", + "l2 = plt.scatter(xUList[0][:,0], xUList[0][:,1], marker='x', c='m', s=10);\n", + "\n", + "plt.legend((l1, l2), ('Lower CI path', 'Upper CI path'), loc='upper left');\n", + "\n", + "plt.ylabel(r'Estimates of $gamma$');\n", + "\n", + "plt.xlabel(r'Estimates of $beta$');\n", + "\n", + "plt.title('Integration path of the geometric confidence intervals on the likelihood surface');\n", + "\n", + "plt.tight_layout();\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "2b357c75", + "metadata": {}, + "source": [ + "\n", + "## Profile Likelihood Surface\n", + "\n", + "To investigate why it was hard to find the profile likelihood confidence\n", + "interval, we can look at the surface (which is a line as\n", + "we are profiling). We find the solution of {func}`nuisanceOptim` for each\n", + "$\\boldsymbol{\\theta}_{-j}$ at various points of $\\boldsymbol{\\theta}$.\n", + "Equivalently, we can minimize the original loss function as defined\n", + "previously, and this is the approach below. We focus out attention to\n", + "the parameter $\\beta$ of our SIR model. The results are not shown here\n", + "but the existence of a solution to {obj}`obj` is evident by *eyeballing* the plots." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "dc31f543", + "metadata": {}, + "outputs": [], + "source": [ + "numIter = 100\n", + "\n", + "x2 = numpy.linspace(0.0, 2.0, numIter)\n", + "\n", + "funcOut = numpy.linspace(0.0, 2.0, numIter)\n", + "\n", + "ode.parameters = [('beta',0.5), ('gamma',1.0/3.0)]\n", + "\n", + "for i in range(numIter):\n", + " paramEval = [('beta',x2[i]), ('gamma',x2[i])]\n", + " ode2 = copy.deepcopy(ode) \n", + " ode2.parameters = paramEval\n", + " ode2.initial_values = (x0, t[0])\n", + " objSIR2 = NormalLoss(x2[i], ode2, x0, t[0], t[1::], yObv.copy(), targetState, target_param='gamma')\n", + " res = scipy.optimize.minimize(fun=objSIR2.cost, jac=objSIR2.gradient, x0=x2[i], bounds=[(0,2)], method='L-BFGS-B')\n", + " funcOut[i] = res['fun']\n", + "\n", + "fig = plt.figure()\n", + "\n", + "plt.plot(x2, objSIR.cost(xhat) - funcOut)\n", + "\n", + "l1 = plt.axhline(-0.5*qchisq(1 - alpha, df=1), 0, 2, color='r')\n", + "\n", + "plt.ylabel(r'\\$mathcal{L}(hat{theta}) - mathcal{L}(theta mid beta)$');\n", + "\n", + "plt.xlabel(r'Fixed value of $beta$');\n", + "\n", + "plt.title('Difference in objective function between MLEn and the maximization of the nuisance parameters given then parameter of interest, beta in this case');\n", + "\n", + "plt.tight_layout();\n", + "\n", + "plt.legend((l1,), (r'$-0.5mathcal{X}_{1 - alpha}^{2}(1)$',), loc='lower right');\n", + "\n", + "plt.show() " + ] + }, + { + "cell_type": "markdown", + "id": "99c84d17", + "metadata": {}, + "source": [ + "\n", + "\n", + "Both the upper and lower confidence interval can be found in the\n", + "profiling procedure, but the part between of\n", + "$\\beta \\in \\left[0,\\hat{\\beta}\\right]$ is not convex, with $\\hat{\\beta}$\n", + "being the MLE. This non--quadratic profile likelihood is due to the\n", + "non-identifiability of the model given data {cite}`Raue2009`. For this\n", + "particular case, we can fix it simply by introducing additional\n", + "observations in the form of the $I$ state. We encourage the users to try\n", + "it out for themselves to confirm." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "67ae8521", + "metadata": {}, + "outputs": [], + "source": [ + "targetState = \\['I', 'R'\\]\n", + "\n", + "targetStateIndex = numpy.array(ode.get_state_index(targetState))\n", + "\n", + "y = solution[1::,targetStateIndex] + numpy.random.normal(0, 0.01, (len(solution[1::,targetStateIndex]), 1))\n", + "\n", + "objSIR = NormalLoss(theta, ode, x0, t[0], t[1::], y.copy(), targetState)\n", + "\n", + "xhat = objSIR.fit(theta, lb=boxBoundsArray[:,0], ub=boxBoundsArray[:,1])\n", + "\n", + "for i in range(numIter): \n", + " paramEval = [('beta', x2[i]), ('gamma', x2[i])] \n", + " ode2 = copy.deepcopy(ode)\n", + " ode2.parameters = paramEval\n", + " ode2.initial_values = (x0, t[0]) \n", + " objSIR2 = NormalLoss(x2[i], ode2, x0, t[0], t[1::], y.copy(), targetState, target_param='gamma')\n", + " res = scipy.optimize.minimize(fun=objSIR2.cost, jac=objSIR2.gradient, x0=x2[i], bounds=[(0,2)], method='L-BFGS-B')\n", + " funcOut[i] = res['fun']\n", + "\n", + "fig = plt.figure()\n", + "\n", + "plt.plot(x2, objSIR.cost(xhat) - funcOut);\n", + "\n", + "l1 = plt.axhline(-0.5*qchisq(1 - alpha, df=1), 0, 2, color='r')\n", + "\n", + "plt.ylabel(r'$mathcal{L}(hat{theta}) - mathcal{L}(theta mid beta)$');\n", + "\n", + "plt.xlabel(r'Fixed value of $beta$');\n", + "\n", + "plt.title('Profile likelihood curve for the parameter of interest with more observations');\n", + "\n", + "plt.tight_layout();\n", + "\n", + "plt.legend((l1,), (r'$-0.5mathcal{X}_{1 - alpha}^{2}(1)$',), loc='lower right');\n", + "\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.15 ('sphinx-doc')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.19" + }, + "vscode": { + "interpreter": { + "hash": "4dc1e323c80fe09539c74ad5c5a7c7d8d9ff99e04f7b3dbd3680daf878629d6e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/notebooks/paramfit/params_via_abc.ipynb b/docs/notebooks/paramfit/params_via_abc.ipynb index 9d2ca1f4..0777a0e0 100644 --- a/docs/notebooks/paramfit/params_via_abc.ipynb +++ b/docs/notebooks/paramfit/params_via_abc.ipynb @@ -69,7 +69,7 @@ "```{note}\n", "We typically do not have access to information regarding the total infected population. More commonly reported is the number of new cases in a given time period (or infection times).\n", "Furthermore, we are unlikely to know the removed population, unless, for example, the disease results in death with high probability.\n", - "Nevertheless, the purpose of this chapter is to demonstrate model fitting given a data set and so these departures from reality shouldn't undermine the key messages.\n", + "Nevertheless, the purpose of this chapter is to demonstrate model fitting given a data set and so these departures from reality do not undermine the key messages.\n", "```\n", "\n", "In the next sections, we are going to use PyGOM to obtain estimates for unknown values $\\beta$, $\\alpha$ and $\\gamma$ (assuming that the total population, $N$, and initial number of infecteds, $I(t=0)$, are known).\n", @@ -87,10 +87,10 @@ "## Fitting an SEIR model (with Infected and Removed known)\n", "\n", "To obtain parameter estimates from data, we must provide a candidate model and specify the unknown parameters which we are interested in. Information regarding the candidate model is contained in {func}`abc.create_loss`, which requires:\n", - "1) A {class}`.SimulateOde` object which describes the system of ODEs\n", + "1) A {class}`.SimulateOde` object which describes the system of ODEs.\n", "2) The loss function, which describes how we assume observations are distributed about the mean value predicted by the {class}`SimulateOde` object.\n", "3) `abc.Parameter` which indicates which parameters we are interested in and their prior distributions.\n", - "4) The data to which we are fitting the parameters\n", + "4) The data to which we are fitting the parameters.\n", "\n", "We start by specifying the ODE system. In this first example, we are going to assume (correctly) that the underlying process is an SEIR model.\n", "We need to let the model know the value of $N$, however, a feature of PyGOM is that we must pass values for all parameters.\n", @@ -143,7 +143,7 @@ "metadata": {}, "source": [ "Finally, we must specify how observations are produced from the underlying model.\n", - "If we assume that each data point is the result of a random draw from a poisson process with mean equal to the SEIR model output at that timepoint, we use the option `PoissonLoss` as our loss function when calling `create_loss` below.\n", + "If we assume that each data point is the result of a random draw from a Poisson distribution with mean equal to the SEIR model output at that timepoint, we can use the option `PoissonLoss` as our loss function when calling `create_loss` below.\n", "Now we combine everything together, including the initial conditions which we are assuming to be known." ] }, @@ -177,7 +177,7 @@ "A sequential Monte Carlo method (ABC-SMC) is used for parameter inference. This approach considers a series of generations, with each generation using a smaller threshold than the previous. The first generation is equivalent to the standard ABC algorithm, in the sense that parameters are sampled from prior distributions. In subsequent generations, candidate parameters are proposed by perturbing weighted samples from the previous generation. Here, we use a multivariate normal distribution with optimal local covariance matrix to perform the perturbation.\n", "\n", "The ABC-SMC method requires a couple of additional arguments to `get_posterior_sample`:\n", - "- G - the number of generations\n", + "- G - the number of generations.\n", "- q - a quantile (0 < q < 1). Whilst it is possible to specify a list of tolerances to use in each generation, it is difficult to know what these should be. When specifying q, the tolerance for the current generation is set to the q-th quantile of the distances from the previous generation. Larger values of q will result in smaller reductions in thresholds but a higher acceptance rate.\n", "\n", "We run for 6 generations on our data" @@ -190,8 +190,7 @@ "metadata": {}, "outputs": [], "source": [ - "import random\n", - "random.seed(1)\n", + "np.random.seed(1)\n", "\n", "abcSEIR.get_posterior_sample(N=250, tol=np.inf, G=6, q=0.25, progress=True)" ] diff --git a/docs/notebooks/paramfit/params_via_optimization.ipynb b/docs/notebooks/paramfit/params_via_optimization.ipynb index ef6745cc..3d24e6e6 100644 --- a/docs/notebooks/paramfit/params_via_optimization.ipynb +++ b/docs/notebooks/paramfit/params_via_optimization.ipynb @@ -42,14 +42,14 @@ "The syntax for setting up the solver is similar to the approach via ABC.\n", "We first form our candidate SEIR model.\n", "Currently, PyGOM requires us to provide numerical values for all model parameters, including the unknown ones we are trying to estimate.\n", - "These values are used to perform an additional prior check to verify that the function provided is integrable.\n", + "These values are used to perform an additional check before performing the MLE to verify that the function provided is integrable.\n", "This step will be likely removed for later versions, but for now it's probably best to input initial guesses as parameter values.\n", "For the current example, this means specifying $\\beta$, $\\alpha$ and $\\gamma$ from our initial guess `theta`." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "id": "857371e4", "metadata": {}, "outputs": [], @@ -73,7 +73,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "88ad9325", "metadata": {}, "outputs": [], @@ -117,10 +117,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "de043dc5", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-3473286.37537513 -648419.19492934 3962185.98738807]\n", + "[-3439949.96665268 -651037.898083 3920356.1433702 ]\n" + ] + } + ], "source": [ "print(objSEIR.sensitivity())\n", "print(objSEIR.adjoint())" @@ -136,20 +145,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "c74c5449", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "57 ms ± 6.71 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" + ] + } + ], "source": [ "%timeit objSEIR.sensitivity()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "20856aa8", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "440 ms ± 81.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], "source": [ "%timeit objSEIR.adjoint()" ] @@ -172,8 +197,6 @@ "Given solutions over the same length of time, fewer discretizations leads to a less accurate interpolation.\n", "Note that the interpolation is currently performed using a univariate spline, due to the limitation of Python packages.\n", "Ideally, one would prefer to use an (adaptive) Hermite or Chebyshev interpolation.\n", - "\n", - "#TODO refs or just leave this out?\n", "```" ] }, @@ -190,7 +213,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "ff093f77", "metadata": {}, "outputs": [], @@ -211,10 +234,26 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "83eca0ba", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: Optimization terminated successfully\n", + " success: True\n", + " status: 0\n", + " fun: 1651.128217170814\n", + " x: [ 3.537e-01 5.384e-01 2.559e-01]\n", + " nit: 17\n", + " jac: [-4.531e+00 -3.594e-01 4.575e+00]\n", + " nfev: 29\n", + " njev: 17\n" + ] + } + ], "source": [ "from scipy.optimize import minimize\n", "\n", @@ -237,10 +276,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "c826a9db", - "metadata": {}, - "outputs": [], + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "data": { + "image/png": "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ClVVxfDhw0Vubq6ora3VNvB75OTkiPj4eKGqqnA6nWLOnDmiqqrKf7/P5xPr1q0TDodDWK1WMWXKFHHq1CkNI+7Z999/LwCI6urqgHWZ61FcXNzlcyk3N1cI0bcaNDU1iaVLl4qoqChhs9lEVlbWgOfWUx4ul6vbfaa4uFgIIURtba2YMmWKiIqKEhaLRYwcOVK89dZb4tq1a9Lk0dfnkez16LBt2zZhs9nEjRs3Ov28LPXo7VgrhH72EWKv14qRej37vLbHMPb6u2SoiRF6vV76vPJXsERERERERESkE/ybeSIiIiIiIiKd4TBPREREREREpDMc5omIiIiIiIh0hsM8ERERERERkc5wmCciIiIiIiLSGQ7zRERERERERDrDYZ6IiIiIiIhIZzjMExEREREREekMh3ki6lVBQQEee+wxrcMgIiKih4S9nkh/FCGE0DoIItKOoig93p+bm4vNmzejpaUF0dHRAxQVERER9Rf2eiJj4jBPNMjV19f7v96zZw/ef/99VFdX+9dsNhvsdrsWoREREVE/YK8nMiaeZk80yDkcDv/NbrdDUZROa/eeerdgwQLMnj0bH330EeLi4hAREYH169ejtbUV77zzDqKiopCQkIAdO3YE/F+XLl1CTk4OIiMjER0djezsbJw7d25gEyYiIhpk2OuJjInDPBE9kMOHD+Py5csoKyvDpk2bUFBQgKysLERGRuLHH39EXl4e8vLycOHCBQCA2+3G9OnTMWTIEJSVleHo0aMYMmQIZs6cCY/Ho3E2REREdC/2eiK5cZgnogcSFRWFTz/9FGPGjMHChQsxZswYuN1uvPvuuxg1ahTWrFkDi8WCH374AQBQWFgIk8mEL7/8EikpKRg3bhx27tyJ2tpalJSUaJsMERERdcJeTyS3IK0DICJ9Gj9+PEymu68HxsXFITk52f+92WxGdHQ0GhoaAADl5eU4c+YMwsLCAh6nubkZf/zxx8AETURERH3GXk8kNw7zRPRAVFUN+F5RlC7XfD4fAMDn8yE9PR27d+/u9FhDhw59eIESERHRA2GvJ5Ibh3kiGhBpaWnYs2cPYmNjER4ernU4RERE1M/Y64kGFv9mnogGxPz58xETE4Ps7GwcOXIELpcLpaWlyM/Px8WLF7UOj4iIiP4h9nqigcVhnogGREhICMrKyjB8+HDMmTMH48aNw8KFC9HU1MRX74mIiAyAvZ5oYClCCKF1EERERERERETUd3xnnoiIiIiIiEhnOMwTERERERER6QyHeSIiIiIiIiKd4TBPREREREREpDMc5omIiIiIiIh0hsM8ERERERERkc5wmCciIiIiIiLSGQ7zRERERERERDrDYZ6IiIiIiIhIZzjMExEREREREekMh3kiIiIiIiIinfl/7Hi69POMlIwAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "pars=res.x\n", "\n", @@ -251,10 +305,16 @@ "import matplotlib.pyplot as plt\n", "f, axarr = plt.subplots(1,2, layout='constrained', figsize=(10, 2.5))\n", "\n", - "axarr[0].plot(t, sol_i_r[:,0], color='C0')\n", - "axarr[0].plot(t, solution[:,2], color='C1')\n", - "axarr[1].plot(t, sol_i_r[:,1], color='C0')\n", - "axarr[1].plot(t, solution[:,3], color='C1');" + "axarr[0].plot(t, sol_i_r[:,0], color='C0', label=\"data\")\n", + "axarr[0].plot(t, solution[:,2], color='C1', label=\"MLE fit\")\n", + "axarr[1].plot(t, sol_i_r[:,1], color='C0', label=\"data\")\n", + "axarr[1].plot(t, solution[:,3], color='C1', label=\"MLE fit\")\n", + "axarr[1].legend(loc=\"lower right\")\n", + "axarr[0].set_xlabel('Time')\n", + "axarr[1].set_xlabel('Time')\n", + "axarr[0].set_ylabel('I', rotation=0)\n", + "axarr[1].set_ylabel('R', rotation=0)\n", + "plt.show()" ] }, { @@ -276,7 +336,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "1ab2d9b6", "metadata": {}, "outputs": [], diff --git a/docs/notebooks/time_dependent_params.ipynb b/docs/notebooks/time_dependent_params.ipynb index a71f52dd..c0cf2bad 100644 --- a/docs/notebooks/time_dependent_params.ipynb +++ b/docs/notebooks/time_dependent_params.ipynb @@ -7,9 +7,9 @@ "source": [ "# Time dependent parameters\n", "\n", - "PyGOM may also be used with time dependent parameters.\n", - "Such situations commonly enter epidemic modelling if, for example, the rate of infection shows time dependence due to seasonal effects or interventions.\n", - "Let's consider an SIR model with periodic infectivity ($beta(t)$) and add in immune waning too (so we can witness multiple seasons):\n", + "PyGOM may also be used to model systems with time dependent parameters.\n", + "Such situations commonly enter epidemic modelling if, for example, the infectivity varies with time due to seasonal effects or interventions.\n", + "As an example, let's consider an SIR model with periodic infectivity ($\\beta(t)$) and add in immune waning too (so we can witness multiple seasons):\n", "\n", "$$\\begin{aligned}\n", "\\frac{\\mathrm{d} S}{\\mathrm{d} t} &= -\\frac{\\beta(t) SI}{N} + w R \\\\\n", @@ -20,7 +20,7 @@ "\n", "where $\\beta_0$ is some baseline infection rate, $\\delta$ is the magnitude of oscillations from the baseline ($-1<\\delta<1$ so that $\\beta>0$), $P$ is the oscillation period and $w$ is the waning rate.\n", "PyGOM cannot handle the time dependence explicitly, instead we must define a dummy variable, $\\tau$, to play the same role.\n", - "We thus append our set of equations with one extra:\n", + "We append our set of equations with an extra one:\n", "\n", "$$\\begin{aligned}\n", "\\frac{\\mathrm{d} \\tau}{\\mathrm{d} t} &= 1\n", @@ -30,15 +30,15 @@ "\n", "- Declaring it in our state list\n", "- Including the equation above in our ode list\n", - "- Providing an initial condition (doesn't matter too much, but best set $\\tau_0=0$ if $t_0=0$)\n", + "- Providing an initial condition (best set $\\tau_0=0$ if $t_0=0$ so that that $\\tau=t$)\n", "\n", - "We must also provide the functional form of $\\beta$.\n", - "It might be easiest to do so by including it as a `derived parameter`." + "We must also provide the functional form of $\\beta$ which we do by including it as a `derived parameter`.\n", + "In the following we put all of these requirements into code:" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "id": "1679a48a", "metadata": {}, "outputs": [], @@ -74,7 +74,7 @@ "\n", "# Initial conditions\n", "i0=1\n", - "x0 = [n_pop-i0, i0, 0, 0] # We specify tau(0)=0\n", + "x0 = [n_pop-i0, i0, 0, 0] # We specify tau0=0 in [s0, i0, r0, tau0]\n", "\n", "# Time range and increments\n", "tmax=10*365 # run for 10 years\n", @@ -97,36 +97,15 @@ "id": "1dcdfcc4", "metadata": {}, "source": [ - "Solve and plot" + "We may then solve this deterministically and plot the result:" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "id": "a8057a58", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 1.0, 'tau')" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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EEIIIYSoZSTMCyGEEEIIIYQQtYyEeSGEEEIIIYQQopaRMC+EEEIIIYQQQtQyEubt6L333iM6OhofHx+6d+/Ob7/95uom1QozZ86kZ8+e6PV6wsLCuP322zl06JCrm1VrzZw5E41GQ2JioqubUmucPXuWe+65h5CQEPz8/OjSpQs7duxwdbNqjfLycl588UWio6Px9fWlRYsWvPLKK5jNZlc3zS2tW7eO0aNHExkZiUaj4bvvvqv0vKIoTJ8+ncjISHx9fRk8eDD79+93TWPrCbl+14xcv+1Lrt81I9fwmpPrd/W44/VbwrydLFmyhMTERKZNm8auXbsYMGAAI0eO5PTp065umttLTk5mwoQJbN68mVWrVlFeXk58fDwFBQWublqts23bNj744AM6derk6qbUGtnZ2fTr1w+dTsfy5cs5cOAAb7/9Ng0aNHB102qNf//73/z3v/9l7ty5HDx4kDfeeIM333yTOXPmuLppbqmgoIDOnTszd+7cqz7/xhtvMGvWLObOncu2bduIiIhg+PDh5OXlObml9YNcv2tOrt/2I9fvmpFruG3k+l09bnn9VoRd9OrVS3n00UcrPda2bVvlueeec1GLaq/MzEwFUJKTk13dlFolLy9PiYmJUVatWqUMGjRImTx5squbVCs8++yzSv/+/V3djFrtlltuUR588MFKj91xxx3KPffc46IW1R6AsnTpUvXfZrNZiYiIUP71r3+pjxUXFysGg0H573//64IW1n1y/bYfuX7XjFy/a06u4baR63fNucv1W3rm7aC0tJQdO3YQHx9f6fH4+Hg2btzoolbVXkajEYDg4GAXt6R2mTBhArfccgvDhg1zdVNqlR9++IEePXpw1113ERYWRteuXfnwww9d3axapX///vzyyy8cPnwYgN27d7N+/XpuvvlmF7es9jlx4gTp6emVrife3t4MGjRIricOINdv+5Lrd83I9bvm5BpuG7l+24+rrt+eDttzPXLhwgVMJhPh4eGVHg8PDyc9Pd1FraqdFEVhypQp9O/fn9jYWFc3p9ZYvHgxO3fuZNu2ba5uSq1z/Phx5s2bx5QpU3jhhRfYunUrTzzxBN7e3tx7772ubl6t8Oyzz2I0Gmnbti0eHh6YTCZef/11/vrXv7q6abWO9ZpxtevJqVOnXNGkOk2u3/Yj1++akeu3beQabhu5ftuPq67fEubtSKPRVPq3oihXPCaub+LEiezZs4f169e7uim1RmpqKpMnT2blypX4+Pi4ujm1jtlspkePHsyYMQOArl27sn//fubNmydfBKpoyZIlLFiwgEWLFtGhQwdSUlJITEwkMjKS++67z9XNq5XkeuJccr5tJ9fv6pPrt+3kGm4buX7bn7OvJxLm7SA0NBQPD48r7uJnZmZecXdGXNukSZP44YcfWLduHU2aNHF1c2qNHTt2kJmZSffu3dXHTCYT69atY+7cuZSUlODh4eHCFrq3Ro0a0b59+0qPtWvXjm+++cZFLap9nn76aZ577jnuvvtuADp27MipU6eYOXOmfBmopoiICMByh79Ro0bq43I9cQy5ftuHXL9rRq7ftpNruG3k+m0/rrp+y5x5O/Dy8qJ79+6sWrWq0uOrVq2ib9++LmpV7aEoChMnTuTbb79lzZo1REdHu7pJtcrQoUPZu3cvKSkp6k+PHj3429/+RkpKinwRuIF+/fpdsZTS4cOHadasmYtaVPsUFhai1Va+nHh4eMjSNjUQHR1NREREpetJaWkpycnJcj1xALl+20au37aR67ft5BpuG7l+24+rrt/SM28nU6ZMYdy4cfTo0YO4uDg++OADTp8+zaOPPurqprm9CRMmsGjRIr7//nv0er3aQ2IwGPD19XVx69yfXq+/Yn6iv78/ISEhMm+xCp588kn69u3LjBkzGDNmDFu3buWDDz7ggw8+cHXTao3Ro0fz+uuv07RpUzp06MCuXbuYNWsWDz74oKub5pby8/M5evSo+u8TJ06QkpJCcHAwTZs2JTExkRkzZhATE0NMTAwzZszAz8+PsWPHurDVdZdcv2tOrt+2keu37eQabhu5flePW16/HVYnvx76v//7P6VZs2aKl5eX0q1bN1mapYqAq/588sknrm5arSVL21TPsmXLlNjYWMXb21tp27at8sEHH7i6SbVKbm6uMnnyZKVp06aKj4+P0qJFC2XatGlKSUmJq5vmln799der/s277777FEWxLG/z8ssvKxEREYq3t7cycOBAZe/eva5tdB0n1++akeu3/cn1u/rkGl5zcv2uHne8fmsURVEcd6tACCGEEEIIIYQQ9iZz5oUQQgghhBBCiFpGwrwQQgghhBBCCFHLSJgXQgghhBBCCCFqGQnzQgghhBBCCCFELSNhXgghhBBCCCGEqGUkzAshhBBCCCGEELWMhHkhhBBCCCGEEKKWkTAvhBBCCCGEEELUMhLmhRBCCCGEEEKIWkbCvBBCCCGEEEIIUctImBdCCCGEEEIIIWqZ/wfP/JVjuqQqKwAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "solution = ode.solve_determ(t[1::])\n", "\n", @@ -135,11 +114,17 @@ "axarr[0][0].plot(t/365, solution[:,0], color='C1')\n", "axarr[0][1].plot(t/365, solution[:,1], color='C0')\n", "axarr[1][0].plot(t/365, solution[:,2], color='C2')\n", - "axarr[1][1].plot(t/365, solution[:,3], color='C3')\n", + "axarr[1][1].plot(t/365, solution[:,3]/365, color='C3')\n", "axarr[0][0].set_title(\"S\")\n", + "axarr[0][0].set_xlabel(\"Time (years)\")\n", "axarr[0][1].set_title(\"I\")\n", + "axarr[0][1].set_xlabel(\"Time (years)\")\n", "axarr[1][0].set_title(\"R\")\n", - "axarr[1][1].set_title(\"tau\")" + "axarr[1][0].set_xlabel(\"Time (years)\")\n", + "axarr[1][1].set_title(\"tau (years)\")\n", + "axarr[1][1].set_xlabel(\"Time (years)\")\n", + "\n", + "plt.show()" ] }, { @@ -147,7 +132,12 @@ "id": "dc691a8f", "metadata": {}, "source": [ - "TODO: Figure out how to do this for a step function." + "```{warning}\n", + "PyGOM cannot be used to solve time dependent systems stochastically.\n", + "This is because our dummy variable, $\\tau$, representing time will be treated the same as the other state variables and thus also evolves stochastically.\n", + "Mathematically, the equation $\\frac{\\mathrm{d} \\tau}{\\mathrm{d} t} = 1$ implies stochastic evolution according to $\\mathrm{d} \\tau \\sim \\mathrm{Poisson}(\\mathrm{d} t)$.\n", + "Whilst $\\tau$ might vaguely follow a similar trajectory to time, we will likely lose too much precision for most applications.\n", + "```" ] } ], diff --git a/docs/notebooks/unroll/unrollSimple.ipynb b/docs/notebooks/unroll/unrollSimple.ipynb index dfba25ce..2004f948 100644 --- a/docs/notebooks/unroll/unrollSimple.ipynb +++ b/docs/notebooks/unroll/unrollSimple.ipynb @@ -22,7 +22,7 @@ "\\frac{\\mathrm{d} N}{\\mathrm{d} t} &= (B-\\mu)N\n", "\\end{aligned}$$\n", "\n", - "Given that the force of infection, $\\frac{\\beta SI}{N}$, depends on the total population, it is necessary to keep track of $N(t)$ in the final equation. \n", + "Given that the infection rate, $\\frac{\\beta SI}{N}$, depends on the total population, it is necessary to keep track of $N(t)$ in the final equation. \n", "Here we encounter an issue when thinking in terms of compartments:\n", "The total number of living individuals, $N$, is not a distinct category, rather, $S$, $I$ and $R$ are a subset of it.\n", "Thus, whilst valid to define a system of ODEs as we have done above, PyGOM will run into difficulties as it will interpret $N$ as a compartment.\n", @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "52daed16", "metadata": {}, "outputs": [], @@ -85,10 +85,47 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "768a4cd0", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Generate Transition Matrix\n", + "Matrix([[B*(I + R + S) - I*S*beta/(I + R + S) - S*mu], [I*S*beta/(I + R + S) - I*gamma - I*mu], [I*gamma - R*mu]])\n", + "Get unmatched\n", + "Matrix([[B*(I + R + S) - I*S*beta/(I + R + S) - S*mu], [I*S*beta/(I + R + S) - I*gamma - I*mu], [I*gamma - R*mu]])\n", + "Get unmatched\n", + "Matrix([[-I*S*beta/(I + R + S)], [I*S*beta/(I + R + S) - I*gamma], [I*gamma]])\n", + "get_bd_from_ode\n", + "Get unmatched\n", + "Matrix([[B*(I + R + S) - I*S*beta/(I + R + S) - S*mu], [I*S*beta/(I + R + S) - I*gamma - I*mu], [I*gamma - R*mu]])\n", + "[-S*mu, B*R, -R*mu, B*I, -I*mu, B*S]\n", + "Matrix([[B*(I + R + S) - I*S*beta/(I + R + S) - S*mu], [I*S*beta/(I + R + S) - I*gamma - I*mu], [I*gamma - R*mu]])\n", + "Generate Transition Matrix\n", + "None\n", + "Get unmatched\n", + "None\n" + ] + }, + { + "ename": "AssertionError", + "evalue": "Expecting a vector of expressions", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAssertionError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[2], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m model \u001b[38;5;241m=\u001b[39m \u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_unrolled_obj\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\users\\joseph.gibson\\pygom\\pygom\\model\\simulate.py:1101\u001b[0m, in \u001b[0;36mSimulateOde.get_unrolled_obj\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1095\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m'''\u001b[39;00m\n\u001b[0;32m 1096\u001b[0m \u001b[38;5;124;03mReturns a :class:`SimulateOde` with the same state and parameters\u001b[39;00m\n\u001b[0;32m 1097\u001b[0m \u001b[38;5;124;03mas the current object but with the equations defined by a set of\u001b[39;00m\n\u001b[0;32m 1098\u001b[0m \u001b[38;5;124;03mtransitions and birth death process instead of say, odes\u001b[39;00m\n\u001b[0;32m 1099\u001b[0m \u001b[38;5;124;03m'''\u001b[39;00m\n\u001b[0;32m 1100\u001b[0m transition \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_transitions_from_ode()\n\u001b[1;32m-> 1101\u001b[0m bdList \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_bd_from_ode\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1103\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m SimulateOde(\n\u001b[0;32m 1104\u001b[0m [\u001b[38;5;28mstr\u001b[39m(s) \u001b[38;5;28;01mfor\u001b[39;00m s \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_stateList],\n\u001b[0;32m 1105\u001b[0m [\u001b[38;5;28mstr\u001b[39m(p) \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_paramList],\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 1108\u001b[0m birth_death\u001b[38;5;241m=\u001b[39mbdList\n\u001b[0;32m 1109\u001b[0m )\n", + "File \u001b[1;32mc:\\users\\joseph.gibson\\pygom\\pygom\\model\\simulate.py:1151\u001b[0m, in \u001b[0;36mSimulateOde.get_bd_from_ode\u001b[1;34m(self, A)\u001b[0m\n\u001b[0;32m 1149\u001b[0m \u001b[38;5;28mprint\u001b[39m(A)\n\u001b[0;32m 1150\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(bdList) \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m-> 1151\u001b[0m M \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_generateTransitionMatrix\u001b[49m\u001b[43m(\u001b[49m\u001b[43mA\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1153\u001b[0m A1 \u001b[38;5;241m=\u001b[39m _ode_composition\u001b[38;5;241m.\u001b[39mpureTransitionToOde(M)\n\u001b[0;32m 1154\u001b[0m diffA \u001b[38;5;241m=\u001b[39m sympy\u001b[38;5;241m.\u001b[39msimplify(A \u001b[38;5;241m-\u001b[39m A1)\n", + "File \u001b[1;32mc:\\users\\joseph.gibson\\pygom\\pygom\\model\\simulate.py:1200\u001b[0m, in \u001b[0;36mSimulateOde._generateTransitionMatrix\u001b[1;34m(self, A)\u001b[0m\n\u001b[0;32m 1198\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGenerate Transition Matrix\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 1199\u001b[0m \u001b[38;5;28mprint\u001b[39m(A)\n\u001b[1;32m-> 1200\u001b[0m bdList, _term \u001b[38;5;241m=\u001b[39m \u001b[43m_ode_composition\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetUnmatchedExpressionVector\u001b[49m\u001b[43m(\u001b[49m\u001b[43mA\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[0;32m 1201\u001b[0m fx \u001b[38;5;241m=\u001b[39m _ode_composition\u001b[38;5;241m.\u001b[39mstripBDFromOde(A, bdList)\n\u001b[0;32m 1202\u001b[0m states \u001b[38;5;241m=\u001b[39m [s \u001b[38;5;28;01mfor\u001b[39;00m s \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_iterStateList()]\n", + "File \u001b[1;32mc:\\users\\joseph.gibson\\pygom\\pygom\\model\\_ode_composition.py:37\u001b[0m, in \u001b[0;36mgetUnmatchedExpressionVector\u001b[1;34m(expr_vec, full_output)\u001b[0m\n\u001b[0;32m 35\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGet unmatched\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 36\u001b[0m \u001b[38;5;28mprint\u001b[39m(expr_vec)\n\u001b[1;32m---> 37\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(expr_vec, MatrixBase), \\\n\u001b[0;32m 38\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mExpecting a vector of expressions\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 40\u001b[0m transition \u001b[38;5;241m=\u001b[39m reduce(\u001b[38;5;28;01mlambda\u001b[39;00m x, y: x \u001b[38;5;241m+\u001b[39m y, \u001b[38;5;28mmap\u001b[39m(getExpressions, expr_vec))\n\u001b[0;32m 41\u001b[0m matched_transition_list \u001b[38;5;241m=\u001b[39m _findMatchingExpression(transition)\n", + "\u001b[1;31mAssertionError\u001b[0m: Expecting a vector of expressions" + ] + } + ], "source": [ "model = model.get_unrolled_obj()" ] @@ -171,12 +208,12 @@ "from pygom import SimulateOde, Transition, TransitionType\n", "\n", "stateList = ['S', 'L', 'I', 'A', 'R']\n", - "paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'epsilon']\n", + "paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'eta']\n", "odeList = [Transition(origin='S', equation='- beta*S*(I + delta*A)', transition_type=TransitionType.ODE), \n", " Transition(origin='L', equation='beta*S*(I + delta*A) - kappa*L', transition_type=TransitionType.ODE),\n", " Transition(origin='I', equation='p*kappa*L - alpha*I', transition_type=TransitionType.ODE),\n", - " Transition(origin='A', equation='(1 - p)*kappa*L - epsilon*A', transition_type=TransitionType.ODE),\n", - " Transition(origin='R', equation='f*alpha*I + epsilon*A', transition_type=TransitionType.ODE)]\n", + " Transition(origin='A', equation='(1 - p)*kappa*L - eta*A', transition_type=TransitionType.ODE),\n", + " Transition(origin='R', equation='f*alpha*I + eta*A', transition_type=TransitionType.ODE)]\n", "model = SimulateOde(stateList, paramList, ode=odeList)" ] }, @@ -204,7 +241,7 @@ "id": "00742616", "metadata": {}, "source": [ - "we notice that the **L** outflow has been captured, but the outflow from **I** is assumed to be a full death process of which a fraction are born into the recovered state.\n", + "We notice that the **L** outflow has been captured, but the outflow from **I** is assumed to be a full death process of which a fraction are born into the recovered state.\n", "This appearance of an incorrect, but still consistent, configuration demonstrates the difficulty in performing such reverse engineering.\n", "One work-around is if we explicitly introduce a dead state, $D$:" ] @@ -217,12 +254,12 @@ "outputs": [], "source": [ "stateList = ['S', 'L', 'I', 'A', 'R', 'D']\n", - "paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'epsilon']\n", + "paramList = ['beta', 'p', 'kappa', 'alpha', 'f', 'delta', 'eta']\n", "odeList = [Transition(origin='S', equation='- beta*S*(I + delta*A)', transition_type=TransitionType.ODE), \n", " Transition(origin='L', equation='beta*S*(I + delta*A) - kappa*L', transition_type=TransitionType.ODE),\n", " Transition(origin='I', equation='p*kappa*L - alpha*I', transition_type=TransitionType.ODE),\n", - " Transition(origin='A', equation='(1 - p)*kappa*L - epsilon*A', transition_type=TransitionType.ODE),\n", - " Transition(origin='R', equation='f*alpha*I + epsilon*A', transition_type=TransitionType.ODE),\n", + " Transition(origin='A', equation='(1 - p)*kappa*L - eta*A', transition_type=TransitionType.ODE),\n", + " Transition(origin='R', equation='f*alpha*I + eta*A', transition_type=TransitionType.ODE),\n", " Transition(origin='D', equation='(1-f)*alpha*I', transition_type=TransitionType.ODE)]\n", "model = SimulateOde(stateList, paramList, ode=odeList)\n", "model = model.get_unrolled_obj()\n", From 41d4115cb4381e4948140e89f92be24b798cec1a Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:27:45 +0100 Subject: [PATCH 045/123] More docs stuff --- docs/_toc.yml | 20 ++++---- docs/bib/ref.bib | 20 ++++---- docs/md/building_doc.md | 8 ++- docs/md/common_models.md | 36 +------------ docs/md/faq.md | 98 +++++++++++++++--------------------- docs/md/installation.md | 5 +- docs/md/intro.md | 5 +- docs/md/parameter_fitting.md | 2 +- 8 files changed, 75 insertions(+), 119 deletions(-) diff --git a/docs/_toc.yml b/docs/_toc.yml index cca0ae10..2ab98058 100644 --- a/docs/_toc.yml +++ b/docs/_toc.yml @@ -20,6 +20,7 @@ parts: sections: - file: notebooks/model_params - file: notebooks/model_solver + - file: notebooks/time_dependent_params #- file: notebooks/transition # - file: md/unrollOde # sections: @@ -47,20 +48,21 @@ parts: - file: md/common_models sections: - file: notebooks/common_models/SIS + - file: notebooks/common_models/SIR + - file: notebooks/common_models/SEIR - file: notebooks/common_models/SIS_Periodic - - file: notebooks/common_models/SIR - file: notebooks/common_models/SIR_Birth_Death - - file: notebooks/common_models/SEIR - - file: notebooks/common_models/SEIR_Multiple - - file: notebooks/common_models/SEIR_Birth_Death - - file: notebooks/common_models/SEIR_Birth_Death_Periodic + - file: notebooks/common_models/SEIR_Multiple + - file: notebooks/common_models/SEIR_Birth_Death_Periodic_Waning_Intro + #- file: notebooks/common_models/SEIR_Birth_Death + #- file: notebooks/common_models/SEIR_Birth_Death_Periodic - file: notebooks/common_models/Legrand_Ebola_SEIHFR - file: notebooks/common_models/Lotka_Volterra - - file: notebooks/common_models/Lotka_Volterra_4State + #- file: notebooks/common_models/Lotka_Volterra_4State - file: notebooks/common_models/FitzHugh - - file: notebooks/common_models/Lorenz - - file: notebooks/common_models/vanDelPol - - file: notebooks/common_models/Robertson + #- file: notebooks/common_models/Lorenz + #- file: notebooks/common_models/vanDelPol + #- file: notebooks/common_models/Robertson - caption: Frequently asked questions chapters: - file: md/faq diff --git a/docs/bib/ref.bib b/docs/bib/ref.bib index cf02a3ca..023d4e5a 100644 --- a/docs/bib/ref.bib +++ b/docs/bib/ref.bib @@ -60,16 +60,15 @@ @article{FitzHugh1961 volume = {1}, year = {1961}, } -@inproceedings{Gillespie1977, - abstract = {There are two formalisms for mathematically describing the time behavior of a spatially homogeneous chemical system: The deterministic approach regards the time evolution as a continuous, wholly predictable process which is governed by a set of coupled, ordinary differential equations (the "reaction-rate equations"); the stochastic approach regards the time evolution as a kind of random-walk process which is governed by a single differential-difference equation (the "master equation"). Fairly simple kinetic theory arguments show that the stochastic formulation of chemical kinetics has a firmer physical basis than the deterministic formulation, but unfortunately the stochastic master equation is often mathematically intractable. There is, however, a way to make exact numerical calculations within the framework of the stochastic formulation without having to deal with the master equation directly. It is a relatively simple digital computer algorithm which uses a rigorously derived Monte Carlo procedure to numerically simulate the time evolution of the given chemical system. Like the master equation, this "stochastic simulation algorithm" correctly accounts for the inherent fluctuations and correlations that are necessarily ignored in the deterministic formulation. In addition, unlike most procedures for numerically solving the deterministic reaction-rate equations, this algorithm never approximates infinitesimal time increments dt by finite time steps Δt. The feasibility and utility of the simulation algorithm are demonstrated by applying it to several well-known model chemical systems, including the Lotka model, the Brusselator, and the Oregonator.}, - author = {Daniel T. Gillespie}, - doi = {10.1021/j100540a008}, - issn = {00223654}, - issue = {25}, - journal = {Journal of Physical Chemistry}, - title = {Exact stochastic simulation of coupled chemical reactions}, - volume = {81}, - year = {1977}, +@article{Gillespie1977, + title={Exact stochastic simulation of coupled chemical reactions}, + author={Gillespie, Daniel T}, + journal={The journal of physical chemistry}, + volume={81}, + number={25}, + pages={2340--2361}, + year={1977}, + publisher={ACS Publications} } @article{Girolami2011, abstract = {The paper proposes Metropolis adjusted Langevin and Hamiltonian Monte Carlo sampling methods defined on the Riemann manifold to resolve the shortcomings of existing Monte Carlo algorithms when sampling from target densities that may be high dimensional and exhibit strong correlations. The methods provide fully automated adaptation mechanisms that circumvent the costly pilot runs that are required to tune proposal densities for Metropolis-Hastings or indeed Hamiltonian Monte Carlo and Metropolis adjusted Langevin algorithms. This allows for highly efficient sampling even in very high dimensions where different scalings may be required for the transient and stationary phases of the Markov chain. The methodology proposed exploits the Riemann geometry of the parameter space of statistical models and thus automatically adapts to the local structure when simulating paths across this manifold, providing highly efficient convergence and exploration of the target density. The performance of these Riemann manifold Monte Carlo methods is rigorously assessed by performing inference on logistic regression models, log-Gaussian Cox point processes, stochastic volatility models and Bayesian estimation of dynamic systems described by non-linear differential equations. Substantial improvements in the time-normalized effective sample size are reported when compared with alternative sampling approaches. MATLAB code that is available from allows replication of all the results reported. © 2011 Royal Statistical Society.}, @@ -155,6 +154,7 @@ @book{Press2007 author = {William H Press and Saul a Teukolsky and William T Vetterling and Brian P Flannery}, issn = {00361445}, journal = {Sample page from NUMBERICAL RECIPES IN C}, + publisher = {Cambridge University Press}, title = {Numerical Recipes 3rd Edition: The Art of Scientific Computing}, volume = {1}, year = {2007}, diff --git a/docs/md/building_doc.md b/docs/md/building_doc.md index 4ea5e5eb..f37d5d96 100644 --- a/docs/md/building_doc.md +++ b/docs/md/building_doc.md @@ -13,6 +13,10 @@ Then, build the documentation from command line: jupyter-book build docs ``` -The html files will be saved in the local copy of your repository under: +The generated HTML files will be saved in the local copy of your repository under: - pygom/docs/_build/html \ No newline at end of file + pygom/docs/_build/html + +You can view the documentation by opening the index file in your browser of choice: + + pygom/docs/_build/html/index.html \ No newline at end of file diff --git a/docs/md/common_models.md b/docs/md/common_models.md index 68943565..f29a1c1e 100644 --- a/docs/md/common_models.md +++ b/docs/md/common_models.md @@ -1,39 +1,5 @@ # Pre-defined examples - common epi models -```{warning} -JG: I have not gone through every example here -``` - We have defined a set of models in the module {mod}`common_models`. Most of these draw from commonly used models in epidemiology and are included primarily to save time for users, but also to serve as examples. - -{doc}`../notebooks/common_models/SIS` - -{doc}`../notebooks/common_models/SIS_Periodic` - -{doc}`../notebooks/common_models/SIR` - -{doc}`../notebooks/common_models/SIR_Birth_Death` - -{doc}`../notebooks/common_models/SEIR` - -{doc}`../notebooks/common_models/SEIR_Multiple` - -{doc}`../notebooks/common_models/SEIR_Birth_Death` - -{doc}`../notebooks/common_models/SEIR_Birth_Death_Periodic` - -{doc}`../notebooks/common_models/Legrand_Ebola_SEIHFR` - -{doc}`../notebooks/common_models/Lotka_Volterra` - -{doc}`../notebooks/common_models/Lotka_Volterra_4State` - -{doc}`../notebooks/common_models/FitzHugh` - -{doc}`../notebooks/common_models/Lorenz` - -{doc}`../notebooks/common_models/vanDelPol` - -{doc}`../notebooks/common_models/Robertson` - +We also include a few models from outside of epidemiology which are commonly used for tasks such as testing numerical solvers. \ No newline at end of file diff --git a/docs/md/faq.md b/docs/md/faq.md index a22e19d8..f9bb00bd 100644 --- a/docs/md/faq.md +++ b/docs/md/faq.md @@ -1,76 +1,60 @@ -# Frequent asked questions {#faq} +# Frequently asked questions -## Code runs slowly +```{warning} +These FAQ's are not particularly up to date and so might not be as frequently asked. +``` -This is because the package is not optimized for speed. Although the -some of the main functions are lambdified using -`sympy`{.interpreted-text role="mod"} or compiled against -`cython`{.interpreted-text role="mod"} when available, there are many -more optimization that can be done. One example is the lines: +## Why does code run slowly? -in `.DeterministicOde.evalSensitivity`{.interpreted-text role="func"}. -The first two operations can be inlined into the third and the third -line itself can be rewritten as: +This is because the package is not optimized for speed. +Although some of the main functions are lambdified using {mod}`sympy` or compiled against {mod}`cython` when available, there are many more optimizations that can be done. -and save the explicit copy operation by `numpy`{.interpreted-text -role="mod"} when making A. If desired, we could have also made used of -the `numexpr`{.interpreted-text role="mod"} package that provides -further speed up on elementwise operations in place of numpy. + -## Why not compile the numeric computation form sympy against Theano +## Why not compile the numeric computation form sympy against Theano? -Setup of the package has been simplified as much as possible. If you -look closely enough, you will realize that the current code generation -only uses `cython`{.interpreted-text role="mod"} and not -`f2py`{.interpreted-text role="mod"}. This is because we are not -prepared to do all the system checks, i.e. does a fortran compiler -exist, is gcc installed, was python built as a shared library etc. We -are very much aware of the benefit, especially considering the -possibility of GPU computation in `theano`{.interpreted-text -role="mod"}. +Setup of the package has been simplified as much as possible. +If you look closely enough, you will realize that the current code generation only uses {mod}`cython` and not {mod}`f2py`. +This is because we are not prepared to do all the system checks, i.e. does a fortran compiler exist, is gcc installed, was python built as a shared library etc. +We are very much aware of the benefit, especially considering the possibility of GPU computation in {mod}`theano`. ## Why not use mpmath library throughout? -This is because we have a fair number of operations that depends on -`scipy`{.interpreted-text role="mod"}. Obviously, we can solve ode using -`mpmath`{.interpreted-text role="mod"} and do standard linear algebra. -Unfortunately, optimization and statistics packages and routine are -mostly based on `numpy`{.interpreted-text role="mod"}. +This is because we have a fair number of operations that depends on {mod}`scipy`. +Obviously, we can solve ode using {mod}`mpmath` and do standard linear algebra. +Unfortunately, optimization and statistics packages and routine are mostly based on {mod}`numpy`. -## Computing the gradient using `.SquareLoss`{.interpreted-text role="class"} is slow +## Why is computing the gradient using {class}`.SquareLoss` slow? -It will always be slow on the first operation. This is due to the design -where the initialization of the class is fast and only find derivative -information/compile function during runtime. After the first -calculation, things should be significantly faster. +It will always be slow on the first operation. +This is due to the design where the initialization of the class is fast and only finds derivative information/compile function during runtime. After the first calculation, things should be significantly faster. -**Why some of my code is not a fortran object?** +## Why is some of my code not a fortran object? -When we detec either a $\exp$ or a $\log$ in the equations, we -automatically force the compile to use mpmath to ensure that we obtain -the highest precision. To turn this on/off will be considered as a -feature in the future. +The following answer may be intended for a different question: -## Can you not convert a non-autonumous system to an autonomous system for me automatically +When we detect either a $\exp$ or a $\log$ in the equations, we automatically force the compile to use {mod}`mpmath` to ensure that we obtain +the highest precision. +To turn this on/off will be considered as a feature in the future. -Although we can do that, it is not, and will not be implemented. This is -to ensure that the end user such as yourself are fully aware of the -equations being defined. +## Can you not convert a non-autonumous system to an autonomous system for me automatically? -## Getting the sensitivities from `.SquareLoss`{.interpreted-text role="class"} did not get a speed up when I used a restricted set of parameters +Although we can do that, it is not, and will not be implemented. +This is to ensure that the end user is fully aware of the equations being defined. -This is because we currently evaluate the full set of sensitivities -before extracting them out. Speeding this up for a restrictive set is -being considered. A main reason that stopped us from implementing is -that we find the symbolic gradient of the ode before compiling it. Which -means that one function call to the compiled file will return the full -set of sensitivities and we would only be extracting the appropriate -elements from the matrix. This only amounts to a small speed up. The -best method would be to compile only the necessary elements of the -gradient matrix, but this would require much more work both within the -code, and later on when variables are being added/deleted as all these -compilation are perfromed in runtime. +## Getting the sensitivities from {class}`.SquareLoss` did not get a speed up when I used a restricted set of parameters -## Why do not have the option to obtain gradient via complex differencing +This is because we currently evaluate the full set of sensitivities before extracting them out. +Speeding this up for a restrictive set is being considered. +A main reason that stopped us from implementing is that we find the symbolic gradient of the ode before compiling it. +Which means that one function call to the compiled file will return the full set of sensitivities and we would only be extracting the appropriate elements from the matrix. +This only amounts to a small speed up. +The best method would be to compile only the necessary elements of the gradient matrix, but this would require much more work both within the +code, and later on when variables are being added/deleted as all these compilation are performed in runtime. -It is currently not implemented. Feature under consideration. +## Why do not have the option to obtain gradient via complex differencing? + +It is currently not implemented. Feature under consideration. \ No newline at end of file diff --git a/docs/md/installation.md b/docs/md/installation.md index 4543a6c0..a0708738 100644 --- a/docs/md/installation.md +++ b/docs/md/installation.md @@ -23,7 +23,7 @@ git activate relevant-branch-name ``` Package dependencies can be found in the file `requirements.txt`. -An easy way to install these to create a new [conda](https://conda.io/docs) environment via: +An easy way to install these is to create a new [conda](https://conda.io/docs) environment via: ```bash conda env create -f conda-env.yml @@ -43,8 +43,7 @@ pip install -r requirements.txt The final prerequisite, if you are working on a Windows machine, is that you will also need to install: - [Graphviz](https://graphviz.org/) -- [Visual C++](https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0) -- Visual C++ Build Tools +- Microsoft Visual C++ 14.0 or greater, which you can get with [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) You you should be able to install the PyGOM package via command line: diff --git a/docs/md/intro.md b/docs/md/intro.md index 8ef86486..ebbbb55c 100644 --- a/docs/md/intro.md +++ b/docs/md/intro.md @@ -8,7 +8,7 @@ The package source is freely available (hosted on [GitHub](https://github.com/uk ## What is new in this release? -The main objective of the current release (0.1.8?) is to provide more comprehensive documentation on how to use PyGOM. +The main objective of the current release (0.1.8) is to provide more comprehensive documentation on how to use PyGOM. The code underlying PyGOM's functionality is largely unchanged since the previous release, barring a few minor bug fixes. The only significant changes which previous users should be aware of are: @@ -19,7 +19,8 @@ Both these changes are outlined in more detail in the {doc}`Producing forecasts ## Using this documentation This documentation is built using [JupyterBook](https://jupyterbook.org/en/stable/intro.html). -To use the contents of a notebook as a starting point for trialing or developing your own models and analyses, you can download any of the examples within this documentation by using the download icon on the desired page (located at the top right). +Instructions on how to build the documentation locally and where to find it can be found {doc}`here `. +To use the contents of a notebook as a starting point for trialling or developing your own models and analyses, you can download any of the examples within this documentation by using the download icon on the desired page (located at the top right). ![download file](../images/download.png) diff --git a/docs/md/parameter_fitting.md b/docs/md/parameter_fitting.md index 64961c48..52b6d038 100644 --- a/docs/md/parameter_fitting.md +++ b/docs/md/parameter_fitting.md @@ -1,6 +1,6 @@ # Parameter fitting -As well as producing forecasts, another key activity in infectious disease modelling is inference of epidemic parameters from incidence data. +As well as producing forecasts, another key activity in infectious disease modelling is inference of epidemic parameters from case data. In this chapter we outline how PyGOM may be used to assist these endeavours. In {doc}`the first section <../notebooks/paramfit/params_via_abc>`, we present a more up to date method which uses Approximate Bayesian Computation (ABC) and {doc}`then <../notebooks/paramfit/params_via_optimization>` a more classical approach via Maximum Likelihood Estimation (MLE). We also demonstrate PyGOM's ability to solve the less epidemiologically related task of {doc}`boundary value problems <../notebooks/paramfit/bvpSimple>` \ No newline at end of file From 7c1b874a104a73ca2bc2e27da5090764c9c3fb62 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:28:29 +0100 Subject: [PATCH 046/123] Manually add Tom's simps fix --- pygom/loss/get_init.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pygom/loss/get_init.py b/pygom/loss/get_init.py index 78f81ed9..56cb5247 100644 --- a/pygom/loss/get_init.py +++ b/pygom/loss/get_init.py @@ -2,7 +2,11 @@ import numpy as np from scipy.interpolate import UnivariateSpline -from scipy.integrate import simps +# TODO: For newer <1.14.0 versions of scipy. Once established remove and leave only except part +try: + from scipy.integrate import simps +except ImportError: + from scipy.integrate import simpson as simps from scipy.optimize import leastsq, minimize_scalar def get_init(y, t, ode, theta=None, full_output=False): From 180e02ba26b384ae019b33b6730623b83314cbcf Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:30:50 +0100 Subject: [PATCH 047/123] Module affected by splitting of unrolling module --- pygom/model/deterministic.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pygom/model/deterministic.py b/pygom/model/deterministic.py index 5679921e..3fafc59c 100644 --- a/pygom/model/deterministic.py +++ b/pygom/model/deterministic.py @@ -25,7 +25,8 @@ from ._model_verification import simplifyEquation from . import ode_utils -from . import _ode_composition +# from . import _ode_composition +from . import _transition_graph class HasNewTransition(ode_utils.CompileCanary): states = ['ode', 'Jacobian', 'diffJacobian', 'grad', 'GradJacobian'] @@ -343,7 +344,8 @@ def get_transition_graph(self, file_name=None, show=True): ------- :class:`graphviz.Digraph` ''' - dot = _ode_composition.generateTransitionGraph(self, file_name) + # dot = _ode_composition.generateTransitionGraph(self, file_name) + dot = _transition_graph.generateTransitionGraph(self, file_name) if show: import matplotlib.image as mpimg import matplotlib.pyplot as plt From 20f6e5c55b673c38d3048cb9527401df878b84ee Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:32:13 +0100 Subject: [PATCH 048/123] fix docstring --- pygom/loss/loss_type.py | 4 ++-- pygom/utilR/distn.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pygom/loss/loss_type.py b/pygom/loss/loss_type.py index 0d6fb41e..00cdf59a 100644 --- a/pygom/loss/loss_type.py +++ b/pygom/loss/loss_type.py @@ -370,7 +370,7 @@ def diff_loss(self, yhat, apply_weighting=True): Returns ------- first_deriv_yhat: array like - :math:`\\mathcal\\frac{a \\left(\\hat{y} - y\\right)}{\\hat{y}^{2}}` + :math:`\\frac{a \\left(\\hat{y} - y\\right)}{\\hat{y}^{2}}` ''' shape = self._shape @@ -394,7 +394,7 @@ def diff2Loss(self, yhat, apply_weighting=True): Returns ------- scnd_deriv_yhat: array like - :math:`\\mathcal\\frac{a \\left(- \\hat{y} + 2 y\\right)}{\\hat{y}^{3}}` + :math:`\\frac{a \\left(- \\hat{y} + 2 y\\right)}{\\hat{y}^{3}}` ''' if len(yhat.shape) > 1: diff --git a/pygom/utilR/distn.py b/pygom/utilR/distn.py index 25cf2628..3dc13767 100644 --- a/pygom/utilR/distn.py +++ b/pygom/utilR/distn.py @@ -98,7 +98,7 @@ def gamma_mu_shape(x, mu,shape,log=False): Returns ------- - pdf, :math:`\\mathcal\\{p}(x; \\mu,a) = \\exp(- a \\ln{\\left(\\frac{\\mu}{a} \\right)} - \\frac{a x}{\\mu} + \\left(a - 1\\right) \\ln{\\left(x \\right)} - \\ln{\\left(\\Gamma\\left(a\\right) \\right)})` + pdf, :math:`\\mathcal{p}(x; \\mu,a) = \\exp(- a \\ln{\\left(\\frac{\\mu}{a} \\right)} - \\frac{a x}{\\mu} + \\left(a - 1\\right) \\ln{\\left(x \\right)} - \\ln{\\left(\\Gamma\\left(a\\right) \\right)})` ` ''' From 24770dabf7fd573bd634dde9265b68aff49197eb Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:33:00 +0100 Subject: [PATCH 049/123] Edit existing and add new common models --- pygom/model/common_models.py | 128 ++++++++++++++++++++++++++--------- 1 file changed, 95 insertions(+), 33 deletions(-) diff --git a/pygom/model/common_models.py b/pygom/model/common_models.py index 632d165c..91960683 100644 --- a/pygom/model/common_models.py +++ b/pygom/model/common_models.py @@ -107,6 +107,52 @@ def SIR(param=None): """ A standard SIR model as per [Brauer2008]_ + .. math:: + \\frac{dS}{dt} &= -\\ \\frac{beta SI}{N} \\\\ + \\frac{dI}{dt} &= \\ \\frac{beta SI}{N} - \\gamma I \\\\ + \\frac{dR}{dt} &= \\gamma I + + + Examples + -------- + The model that produced top two graph in Figure 1.3 of the reference above. + First, when everyone is susceptible and only one individual was infected. + + >>> import numpy as np + >>> from pygom import common_models + >>> N=1e5 + >>> ode = common_models.SIR({'beta':0.5, 'gamma':0.2, 'N':N}) + >>> t = np.linspace(0, 730, 1001) + >>> i0=1 + >>> x0 = [N-i0, i0, 0.0] + >>> ode.initial_values = (x0, t[0]) + >>> solution = ode.integrate(t[1::]) + >>> ode.plot() + + """ + state = ['S', 'I', 'R'] + param_list = ['beta', 'gamma', 'N'] + transition = [ + Transition(origin='S', destination='I', equation='beta*S*I/N', + transition_type=TransitionType.T), + Transition(origin='I', destination='R', equation='gamma*I', + transition_type=TransitionType.T) + ] + # initialize the model + ode_obj = SimulateOde(state, param_list, transition=transition) + + # set return, depending on whether we have input the parameters + if param is None: + return ode_obj + else: + ode_obj.parameters = param + return ode_obj + + +def SIR_norm(param=None): + """ + A normalized SIR model: + .. math:: \\frac{dS}{dt} &= -\\beta SI \\\\ \\frac{dI}{dt} &= \\beta SI - \\gamma I \\\\ @@ -142,9 +188,9 @@ def SIR(param=None): """ state = ['S', 'I', 'R'] - param_list = ['beta', 'gamma', 'N'] + param_list = ['beta', 'gamma'] transition = [ - Transition(origin='S', destination='I', equation='beta*S*I/N', + Transition(origin='S', destination='I', equation='beta*S*I', transition_type=TransitionType.T), Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T) @@ -159,34 +205,33 @@ def SIR(param=None): ode_obj.parameters = param return ode_obj +# def SIR_N(param=None, init=None): +# """ +# A standard SIR model [Brauer2008]_ with population N -def SIR_N(param=None, init=None): - """ - A standard SIR model [Brauer2008]_ with population N - - .. math:: - \\frac{dS}{dt} &= -\\beta SI/N \\\\ - \\frac{dI}{dt} &= \\beta SI/N- \\gamma I \\\\ - \\frac{dR}{dt} &= \\gamma I +# .. math:: +# \\frac{dS}{dt} &= -\\beta SI/N \\\\ +# \\frac{dI}{dt} &= \\beta SI/N- \\gamma I \\\\ +# \\frac{dR}{dt} &= \\gamma I - """ - stateList = ['S', 'I', 'R'] - paramList = ['beta', 'gamma', 'N'] - transitionList = [Transition(origin='S', destination='I', equation='beta*S*I/N', transition_type=TransitionType.T), - Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)] +# """ +# stateList = ['S', 'I', 'R'] +# paramList = ['beta', 'gamma', 'N'] +# transitionList = [Transition(origin='S', destination='I', equation='beta*S*I/N', transition_type=TransitionType.T), +# Transition(origin='I', destination='R', equation='gamma*I', transition_type=TransitionType.T)] - # initialize the model - ode_obj = SimulateOde(stateList, paramList, transition=transitionList) +# # initialize the model +# ode_obj = SimulateOde(stateList, paramList, transition=transitionList) - # set return, depending on whether we have input the parameters +# # set return, depending on whether we have input the parameters - if param is not None: - ode_obj.parameters = param +# if param is not None: +# ode_obj.parameters = param - if init is not None: - ode_obj.initial_values = init +# if init is not None: +# ode_obj.initial_values = init - return ode_obj +# return ode_obj def SEIR_N(param=None, init=None): @@ -830,19 +875,36 @@ def Lotka_Volterra(param=None): """ # our two state and four parameters - # no idea why they are not in capital state = ['x', 'y'] # while these 4 are - param_list = ['alpha', 'delta', 'c', 'gamma'] + param_list = ['alpha', 'beta', 'gamma', 'delta', 'A'] # then define the set of ode - ode = [ - Transition(origin='x', equation='alpha*x - c*x*y', - transition_type=TransitionType.ODE), - Transition(origin='y', equation='-delta*y + gamma*x*y', - transition_type=TransitionType.ODE) + # ode = [ + # Transition(origin='x', equation='alpha*x - c*x*y', + # transition_type=TransitionType.ODE), + # Transition(origin='y', equation='-delta*y + gamma*x*y', + # transition_type=TransitionType.ODE) + # ] + # ode_obj = SimulateOde(state, param_list, ode=ode) + + # Defining via transitions allows us to solve stochastically too + birth_death = [ + Transition(origin='x', equation='alpha*x', + transition_type=TransitionType.B), + Transition(origin='x', equation='beta*x*y/A', + transition_type=TransitionType.D), + Transition(origin='y', equation='gamma*x*y/A', + transition_type=TransitionType.B), + Transition(origin='y', equation='delta*y', + transition_type=TransitionType.D) ] - ode_obj = SimulateOde(state, param_list, ode=ode) + # initialize the model + ode_obj = SimulateOde(state, + param_list, + birth_death=birth_death) + + # set return, depending on whether we have input the parameters if param is None: return ode_obj @@ -993,7 +1055,7 @@ def Lorenz(param=None): return ode_obj -def vanDelPol(param=None): +def vanDerPol(param=None): """ The van der Pol equation [vanderpol1926]_, a second order ode @@ -1019,7 +1081,7 @@ def vanDelPol(param=None): >>> from pygom import common_models >>> import numpy >>> t = numpy.linspace(0, 20, 1000) - >>> ode = common_models.vanDelPol({'mu':1.0}) + >>> ode = common_models.vanDerPol({'mu':1.0}) >>> ode.initial_values = ([2.0,0.0], t[0]) >>> solution = ode.integrate(t[1::]) >>> ode.plot() From 1efd8a9be32dd982154cbf68c40875da086d5fae Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:33:53 +0100 Subject: [PATCH 050/123] numpy >2 was causing error, see if this remedies it --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 47c88f15..f01fdb8b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ dask[complete]>=0.13.0 graphviz>=0.4.9 matplotlib>=1.0.0 -numpy>=2.0.0 -pandas>=0.15.0 +numpy==1.26.4 +pandas>=2.2.2 python-dateutil>=2.0.0 scipy>=1.4.1 sympy>=1.0.0 From d061328fe977be2bc77cd641c976761baf7142b8 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 15:47:34 +0100 Subject: [PATCH 051/123] Set numpy back >=2.0.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f01fdb8b..bf57620d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ dask[complete]>=0.13.0 graphviz>=0.4.9 matplotlib>=1.0.0 -numpy==1.26.4 +numpy>=2.0.0 pandas>=2.2.2 python-dateutil>=2.0.0 scipy>=1.4.1 From 4d8a78e657e54d0ea9bd0bb451002d25da0cb07f Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 18:00:51 +0100 Subject: [PATCH 052/123] get_A should return A if it already exists --- pygom/model/simulate.py | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/pygom/model/simulate.py b/pygom/model/simulate.py index 453da856..571b960d 100644 --- a/pygom/model/simulate.py +++ b/pygom/model/simulate.py @@ -1127,24 +1127,29 @@ def get_transitions_from_ode(self): return transition - def get_bd_from_ode(self, A=None): - ''' - Returns a list of:class:`Transition` from this object by unrolling - the odes. All the elements are of TransitionType.B or - TransitionType.D - ''' + def _get_A(self, A=None): if A is None: if not ode_utils.none_or_empty_list(self._odeList): - eqn = [t.equation for t in self._odeList] - A = sympy.Matrix(checkEquation(eqn, + eqn_list = [t.equation for t in self._odeList] + A = sympy.Matrix(checkEquation(eqn_list, *self._getListOfVariablesDict(), subs_derived=False)) + return A else: raise Exception("Object was not initialized using a set of ode") - # A = super(SimulateOde, self).getOde() + else: + return A - bdList, _term = _ode_composition.getUnmatchedExpressionVector(A, True) + def get_bd_from_ode(self, A=None): + ''' + Returns a list of:class:`Transition` from this object by unrolling + the odes. All the elements are of TransitionType.B or + TransitionType.D + ''' + + A=self._get_A(A) + bdList, _term = _ode_composition.getUnmatchedExpressionVector(A, True) if len(bdList) > 0: M = self._generateTransitionMatrix(A) @@ -1172,17 +1177,6 @@ def get_bd_from_ode(self, A=None): else: return [] - def _get_A(self, A=None): - if A is None: - if not ode_utils.none_or_empty_list(self._odeList): - eqn_list = [t.equation for t in self._odeList] - A = sympy.Matrix(checkEquation(eqn_list, - *self._getListOfVariablesDict(), - subs_derived=False)) - return A - else: - raise Exception("Object was not initialized using a set of ode") - def _generateTransitionMatrix(self, A=None):#, transitionExpressionList=None): ''' Finds the transition matrix from the set of ode. It is From aeb32d283d22778eb8476dd0edd7c81ee66474cc Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Wed, 31 Jul 2024 18:24:42 +0100 Subject: [PATCH 053/123] unroll now working again --- docs/notebooks/unroll/unrollSimple.ipynb | 43 ++---------------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/docs/notebooks/unroll/unrollSimple.ipynb b/docs/notebooks/unroll/unrollSimple.ipynb index 2004f948..7d5894d4 100644 --- a/docs/notebooks/unroll/unrollSimple.ipynb +++ b/docs/notebooks/unroll/unrollSimple.ipynb @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "52daed16", "metadata": {}, "outputs": [], @@ -85,47 +85,10 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "768a4cd0", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Generate Transition Matrix\n", - "Matrix([[B*(I + R + S) - I*S*beta/(I + R + S) - S*mu], [I*S*beta/(I + R + S) - I*gamma - I*mu], [I*gamma - R*mu]])\n", - "Get unmatched\n", - "Matrix([[B*(I + R + S) - I*S*beta/(I + R + S) - S*mu], [I*S*beta/(I + R + S) - I*gamma - I*mu], [I*gamma - R*mu]])\n", - "Get unmatched\n", - "Matrix([[-I*S*beta/(I + R + S)], [I*S*beta/(I + R + S) - I*gamma], [I*gamma]])\n", - "get_bd_from_ode\n", - "Get unmatched\n", - "Matrix([[B*(I + R + S) - I*S*beta/(I + R + S) - S*mu], [I*S*beta/(I + R + S) - I*gamma - I*mu], [I*gamma - R*mu]])\n", - "[-S*mu, B*R, -R*mu, B*I, -I*mu, B*S]\n", - "Matrix([[B*(I + R + S) - I*S*beta/(I + R + S) - S*mu], [I*S*beta/(I + R + S) - I*gamma - I*mu], [I*gamma - R*mu]])\n", - "Generate Transition Matrix\n", - "None\n", - "Get unmatched\n", - "None\n" - ] - }, - { - "ename": "AssertionError", - "evalue": "Expecting a vector of expressions", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mAssertionError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[2], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m model \u001b[38;5;241m=\u001b[39m \u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_unrolled_obj\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[1;32mc:\\users\\joseph.gibson\\pygom\\pygom\\model\\simulate.py:1101\u001b[0m, in \u001b[0;36mSimulateOde.get_unrolled_obj\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1095\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m'''\u001b[39;00m\n\u001b[0;32m 1096\u001b[0m \u001b[38;5;124;03mReturns a :class:`SimulateOde` with the same state and parameters\u001b[39;00m\n\u001b[0;32m 1097\u001b[0m \u001b[38;5;124;03mas the current object but with the equations defined by a set of\u001b[39;00m\n\u001b[0;32m 1098\u001b[0m \u001b[38;5;124;03mtransitions and birth death process instead of say, odes\u001b[39;00m\n\u001b[0;32m 1099\u001b[0m \u001b[38;5;124;03m'''\u001b[39;00m\n\u001b[0;32m 1100\u001b[0m transition \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_transitions_from_ode()\n\u001b[1;32m-> 1101\u001b[0m bdList \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_bd_from_ode\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1103\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m SimulateOde(\n\u001b[0;32m 1104\u001b[0m [\u001b[38;5;28mstr\u001b[39m(s) \u001b[38;5;28;01mfor\u001b[39;00m s \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_stateList],\n\u001b[0;32m 1105\u001b[0m [\u001b[38;5;28mstr\u001b[39m(p) \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_paramList],\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 1108\u001b[0m birth_death\u001b[38;5;241m=\u001b[39mbdList\n\u001b[0;32m 1109\u001b[0m )\n", - "File \u001b[1;32mc:\\users\\joseph.gibson\\pygom\\pygom\\model\\simulate.py:1151\u001b[0m, in \u001b[0;36mSimulateOde.get_bd_from_ode\u001b[1;34m(self, A)\u001b[0m\n\u001b[0;32m 1149\u001b[0m \u001b[38;5;28mprint\u001b[39m(A)\n\u001b[0;32m 1150\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(bdList) \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m-> 1151\u001b[0m M \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_generateTransitionMatrix\u001b[49m\u001b[43m(\u001b[49m\u001b[43mA\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1153\u001b[0m A1 \u001b[38;5;241m=\u001b[39m _ode_composition\u001b[38;5;241m.\u001b[39mpureTransitionToOde(M)\n\u001b[0;32m 1154\u001b[0m diffA \u001b[38;5;241m=\u001b[39m sympy\u001b[38;5;241m.\u001b[39msimplify(A \u001b[38;5;241m-\u001b[39m A1)\n", - "File \u001b[1;32mc:\\users\\joseph.gibson\\pygom\\pygom\\model\\simulate.py:1200\u001b[0m, in \u001b[0;36mSimulateOde._generateTransitionMatrix\u001b[1;34m(self, A)\u001b[0m\n\u001b[0;32m 1198\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGenerate Transition Matrix\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 1199\u001b[0m \u001b[38;5;28mprint\u001b[39m(A)\n\u001b[1;32m-> 1200\u001b[0m bdList, _term \u001b[38;5;241m=\u001b[39m \u001b[43m_ode_composition\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetUnmatchedExpressionVector\u001b[49m\u001b[43m(\u001b[49m\u001b[43mA\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[0;32m 1201\u001b[0m fx \u001b[38;5;241m=\u001b[39m _ode_composition\u001b[38;5;241m.\u001b[39mstripBDFromOde(A, bdList)\n\u001b[0;32m 1202\u001b[0m states \u001b[38;5;241m=\u001b[39m [s \u001b[38;5;28;01mfor\u001b[39;00m s \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_iterStateList()]\n", - "File \u001b[1;32mc:\\users\\joseph.gibson\\pygom\\pygom\\model\\_ode_composition.py:37\u001b[0m, in \u001b[0;36mgetUnmatchedExpressionVector\u001b[1;34m(expr_vec, full_output)\u001b[0m\n\u001b[0;32m 35\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGet unmatched\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 36\u001b[0m \u001b[38;5;28mprint\u001b[39m(expr_vec)\n\u001b[1;32m---> 37\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(expr_vec, MatrixBase), \\\n\u001b[0;32m 38\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mExpecting a vector of expressions\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 40\u001b[0m transition \u001b[38;5;241m=\u001b[39m reduce(\u001b[38;5;28;01mlambda\u001b[39;00m x, y: x \u001b[38;5;241m+\u001b[39m y, \u001b[38;5;28mmap\u001b[39m(getExpressions, expr_vec))\n\u001b[0;32m 41\u001b[0m matched_transition_list \u001b[38;5;241m=\u001b[39m _findMatchingExpression(transition)\n", - "\u001b[1;31mAssertionError\u001b[0m: Expecting a vector of expressions" - ] - } - ], + "outputs": [], "source": [ "model = model.get_unrolled_obj()" ] From 7670e22566cdc2caf3e79c0b73e9f06ec1982c77 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 1 Aug 2024 09:21:17 +0100 Subject: [PATCH 054/123] update README --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bea3a03e..59a88422 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,7 @@ Alternatively, you may add dependencies to your own environment: The final prerequisite, if you are working on a Windows machine, is that you will also need to install: - [Graphviz](https://graphviz.org/) -- [Visual C++](https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0) -- [Visual C++ Build Tools](https://go.microsoft.com/fwlink/?LinkId=691126) +- Microsoft Visual C++ 14.0 or greater, which you can get with [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) You should now be able to install the PyGOM package via command line: @@ -68,7 +67,11 @@ Documentation is built from the command line: The html files will be saved in the local copy of your repository under: - docs/_build/html + pygom/docs/_build/html + +You can view the documentation by opening the index file in your browser of choice: + + pygom/docs/_build/html/index.html > [!NOTE] > Building the documentation involves running many examples in python which can take up to 30 minutes. Subsequent builds with these examples unchanged are much quicker due to caching of the code outputs. From 29fb0915a396f5f2767d9156cbccb2700e1d14b2 Mon Sep 17 00:00:00 2001 From: j-c-gibson <163280363+j-c-gibson@users.noreply.github.com> Date: Thu, 1 Aug 2024 11:15:17 +0100 Subject: [PATCH 055/123] setup.py might be deprecated for python 3.12 --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5f267a59..455fdb24 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] # macos-latest - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v2 From e70df4f9250e3fcbd880e0609a28446d896d7d00 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Thu, 1 Aug 2024 16:20:03 +0100 Subject: [PATCH 056/123] one term missing in equations --- .../common_models/SEIR_Birth_Death_Periodic_Waning_Intro.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/notebooks/common_models/SEIR_Birth_Death_Periodic_Waning_Intro.ipynb b/docs/notebooks/common_models/SEIR_Birth_Death_Periodic_Waning_Intro.ipynb index 976823ef..eaf90f5a 100644 --- a/docs/notebooks/common_models/SEIR_Birth_Death_Periodic_Waning_Intro.ipynb +++ b/docs/notebooks/common_models/SEIR_Birth_Death_Periodic_Waning_Intro.ipynb @@ -13,7 +13,7 @@ "In addition to the processes of births, deaths and seasonal driving, we have included (i) immune waning, which transitions recovered individuals back to susceptible at a rate $w$ and (ii) an external force of infection, which allows individuals to be infected from outside the population (analogous to case importation) at a rate $\\epsilon$.\n", "\n", "$$\\begin{aligned}\n", - "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= - \\frac{\\beta(t) SI}{N} + w R + \\mu N - \\mu S\\\\\n", + "\\frac{\\mathrm{d}S}{\\mathrm{d}t} &= - \\frac{\\beta(t) SI}{N} + w R + \\mu N - \\epsilon S - \\mu S\\\\\n", "\\frac{\\mathrm{d}E}{\\mathrm{d}t} &= \\frac{\\beta(t) SI}{N} + \\epsilon S - \\alpha E - \\mu E \\\\\n", "\\frac{\\mathrm{d}I}{\\mathrm{d}t} &= \\alpha E - \\gamma I - \\mu I \\\\\n", "\\frac{\\mathrm{d}R}{\\mathrm{d}t} &= \\gamma I - w R - \\mu R \\\\\n", From 53e7eb11b1d231dd1a038b3f73ab99ec00dc3beb Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 11:39:05 +0100 Subject: [PATCH 057/123] Remove requirements needed only for documentation from the main requirements file. --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index bf57620d..9e410a61 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,5 +10,3 @@ numpydoc>=0.6.0 sphinx>=1.4.1 sphinx_rtd_theme>=0.2.0 cython>=0.29 -nbsphinx -jupyter-book From 51112c67982b3dd9110563a22d3d9bbdb567f5c3 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 16:58:24 +0100 Subject: [PATCH 058/123] Update the bib file to remove duplicate publisher. --- docs/bib/ref.bib | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/bib/ref.bib b/docs/bib/ref.bib index c43f3d2a..86fd6ec2 100644 --- a/docs/bib/ref.bib +++ b/docs/bib/ref.bib @@ -156,7 +156,6 @@ @book{Press2007 journal = {Sample page from NUMBERICAL RECIPES IN C}, publisher = {Cambridge University Press}, title = {Numerical Recipes 3rd Edition: The Art of Scientific Computing}, - publisher = {Cambridge University Press}, volume = {1}, year = {2007}, } From d44b9d17fe44360371ae0f384e21f447760884a9 Mon Sep 17 00:00:00 2001 From: Joseph Gibson Date: Fri, 2 Aug 2024 17:12:09 +0100 Subject: [PATCH 059/123] and one last error in the ABC notebook --- docs/notebooks/paramfit/params_via_abc.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/notebooks/paramfit/params_via_abc.ipynb b/docs/notebooks/paramfit/params_via_abc.ipynb index 0777a0e0..0e54b10d 100644 --- a/docs/notebooks/paramfit/params_via_abc.ipynb +++ b/docs/notebooks/paramfit/params_via_abc.ipynb @@ -331,7 +331,7 @@ "x0=[n_pop-i0, i0, 0]\n", "\n", "# Set up pygom object\n", - "ode_SIR = common_models.SIR_N(param=paramEval)\n", + "ode_SIR = common_models.SIR(param=paramEval)\n", "\n", "objSIR = abc.create_loss(\"PoissonLoss\", parameters, ode_SIR, x0, t[0], t[1:], sol_i_r[1:,0], ['I'])\n", "abcSIR = abc.ABC(objSIR, parameters)\n", From 8eeb9b340d56374e33224bfe289888373e062b9c Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 17:17:04 +0100 Subject: [PATCH 060/123] Adjust the readme to show how to install the requirements via conda. --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 59a88422..34300123 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,11 @@ which you should ensure is active for the installation process using conda activate pygom -Alternatively, you may add dependencies to your own environment: +Alternatively, you may add dependencies to your own environment through conda: + + conda install --file requirements.txt + +**or** via pip: pip install -r requirements.txt @@ -61,17 +65,21 @@ This will run a few test cases and can take some minutes to complete. ## Documentation Documentation must be built locally and all necessary files can be found in the `docs` folder. -Documentation is built from the command line: +Documentation is built from the command line by first installing the additional documentation requirements: + + pip install -r docs/requirements.txt + +and then building the documentation: jupyter-book build docs The html files will be saved in the local copy of your repository under: - pygom/docs/_build/html + docs/_build/html You can view the documentation by opening the index file in your browser of choice: - pygom/docs/_build/html/index.html + docs/_build/html/index.html > [!NOTE] > Building the documentation involves running many examples in python which can take up to 30 minutes. Subsequent builds with these examples unchanged are much quicker due to caching of the code outputs. From 2bc23ca1f690746cc785b3d3d7ec7a934802481d Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 17:59:15 +0100 Subject: [PATCH 061/123] First test of actions building wheels. --- .github/workflows/main.yml | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 455fdb24..f5a106fc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,15 +17,15 @@ env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true jobs: - build: + test: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, windows-latest] # macos-latest + os: [ubuntu-latest, windows-latest, macos-13, macos-14] # macos-latest python-version: ["3.9", "3.10", "3.11"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/cache@v1 if: startsWith(runner.os, 'Linux') @@ -89,3 +89,30 @@ jobs: echo "backend: TkAgg" >> ~/.matplotlib/matplotlibrc - name: Test and coverage run: python setup.py test + + build_wheels: + name: Build wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-13, macos-14] + + steps: + - uses: actions/checkout@v4 + + # Used to host cibuildwheel + - uses: actions/setup-python@v5 + + - name: Install cibuildwheel + run: python -m pip install cibuildwheel==2.19.2 + + - name: Build wheels + run: python -m cibuildwheel --output-dir wheelhouse + # to supply options, put them in 'env', like: + # env: + # CIBW_SOME_OPTION: value + + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl From f5f8525b8e8ceff5396ef3d605de1adea7cf4859 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 19:40:56 +0100 Subject: [PATCH 062/123] Add the requirements to the build environment. --- .github/workflows/main.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f5a106fc..b08253d0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -100,6 +100,11 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + # Used to host cibuildwheel - uses: actions/setup-python@v5 From 909d9d3438ae8034a2c9a332d2c79146a09573bb Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 19:44:40 +0100 Subject: [PATCH 063/123] Without MacOS, can't test locally. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b08253d0..137f142a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-13, macos-14] # macos-latest + os: [ubuntu-latest, windows-latest] #, macos-13, macos-14] python-version: ["3.9", "3.10", "3.11"] steps: From 74658e4677cf8da65284dfe4f0326c8b3cad9591 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 20:02:02 +0100 Subject: [PATCH 064/123] Make the wheel building match the testing. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 137f142a..0360dff0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -95,7 +95,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-13, macos-14] + os: [ubuntu-latest, windows-latest] #, macos-13, macos-14] steps: - uses: actions/checkout@v4 From f6bd33ad75c7403fc7d4a9128bb927759044df6e Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 22:49:36 +0100 Subject: [PATCH 065/123] Restructure to use a pyproject.toml file. --- .../debug_tau_leap.ipynb | 0 pygom/model/_tau_leap.c | 30881 ---------------- pyproject.toml | 55 + setup.py | 121 +- {pygom => src/pygom}/__init__.py | 0 .../__init__.py | 0 .../approximate_bayesian_computation.py | 0 {pygom => src/pygom}/data/eg1.json | 0 {pygom => src/pygom}/loss/.gitignore | 0 {pygom => src/pygom}/loss/__init__.py | 0 {pygom => src/pygom}/loss/base_loss.py | 0 .../pygom}/loss/confidence_interval.py | 0 {pygom => src/pygom}/loss/epijson_loss.py | 0 {pygom => src/pygom}/loss/get_init.py | 0 {pygom => src/pygom}/loss/loss_type.py | 0 {pygom => src/pygom}/loss/ode_loss.py | 0 {pygom => src/pygom}/loss/read_epijson.py | 0 {pygom => src/pygom}/model/__init__.py | 0 {pygom => src/pygom}/model/_model_errors.py | 0 .../pygom}/model/_model_verification.py | 0 .../pygom}/model/_ode_composition.py | 0 {pygom => src/pygom}/model/_tau_leap.pyx | 0 .../pygom}/model/_transition_graph.py | 0 {pygom => src/pygom}/model/base_ode_model.py | 0 {pygom => src/pygom}/model/common_models.py | 0 {pygom => src/pygom}/model/deterministic.py | 0 {pygom => src/pygom}/model/epi_analysis.py | 0 .../pygom}/model/ode_utils/__init__.py | 0 .../model/ode_utils/checks_and_conversions.py | 0 .../pygom}/model/ode_utils/compile_canary.py | 0 .../pygom}/model/ode_utils/plot_det.py | 0 .../pygom}/model/ode_utils/plot_stoc.py | 0 {pygom => src/pygom}/model/ode_variable.py | 0 {pygom => src/pygom}/model/simulate.py | 0 .../pygom}/model/stochastic_simulation.py | 0 {pygom => src/pygom}/model/transition.py | 0 {pygom => src/pygom}/utilR/__init__.py | 0 {pygom => src/pygom}/utilR/distn.py | 0 38 files changed, 72 insertions(+), 30985 deletions(-) rename debug_tau_leap.ipynb => notebooks/debug_tau_leap.ipynb (100%) delete mode 100644 pygom/model/_tau_leap.c create mode 100644 pyproject.toml rename {pygom => src/pygom}/__init__.py (100%) rename {pygom => src/pygom}/approximate_bayesian_computation/__init__.py (100%) rename {pygom => src/pygom}/approximate_bayesian_computation/approximate_bayesian_computation.py (100%) rename {pygom => src/pygom}/data/eg1.json (100%) rename {pygom => src/pygom}/loss/.gitignore (100%) rename {pygom => src/pygom}/loss/__init__.py (100%) rename {pygom => src/pygom}/loss/base_loss.py (100%) rename {pygom => src/pygom}/loss/confidence_interval.py (100%) rename {pygom => src/pygom}/loss/epijson_loss.py (100%) rename {pygom => src/pygom}/loss/get_init.py (100%) rename {pygom => src/pygom}/loss/loss_type.py (100%) rename {pygom => src/pygom}/loss/ode_loss.py (100%) rename {pygom => src/pygom}/loss/read_epijson.py (100%) rename {pygom => src/pygom}/model/__init__.py (100%) rename {pygom => src/pygom}/model/_model_errors.py (100%) rename {pygom => src/pygom}/model/_model_verification.py (100%) rename {pygom => src/pygom}/model/_ode_composition.py (100%) rename {pygom => src/pygom}/model/_tau_leap.pyx (100%) rename {pygom => src/pygom}/model/_transition_graph.py (100%) rename {pygom => src/pygom}/model/base_ode_model.py (100%) rename {pygom => src/pygom}/model/common_models.py (100%) rename {pygom => src/pygom}/model/deterministic.py (100%) rename {pygom => src/pygom}/model/epi_analysis.py (100%) rename {pygom => src/pygom}/model/ode_utils/__init__.py (100%) rename {pygom => src/pygom}/model/ode_utils/checks_and_conversions.py (100%) rename {pygom => src/pygom}/model/ode_utils/compile_canary.py (100%) rename {pygom => src/pygom}/model/ode_utils/plot_det.py (100%) rename {pygom => src/pygom}/model/ode_utils/plot_stoc.py (100%) rename {pygom => src/pygom}/model/ode_variable.py (100%) rename {pygom => src/pygom}/model/simulate.py (100%) rename {pygom => src/pygom}/model/stochastic_simulation.py (100%) rename {pygom => src/pygom}/model/transition.py (100%) rename {pygom => src/pygom}/utilR/__init__.py (100%) rename {pygom => src/pygom}/utilR/distn.py (100%) diff --git a/debug_tau_leap.ipynb b/notebooks/debug_tau_leap.ipynb similarity index 100% rename from debug_tau_leap.ipynb rename to notebooks/debug_tau_leap.ipynb diff --git a/pygom/model/_tau_leap.c b/pygom/model/_tau_leap.c deleted file mode 100644 index 04607eb1..00000000 --- a/pygom/model/_tau_leap.c +++ /dev/null @@ -1,30881 +0,0 @@ -/* Generated by Cython 3.0.10 */ - -/* BEGIN: Cython Metadata -{ - "distutils": { - "depends": [ - "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\arrayobject.h", - "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\arrayscalars.h", - "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\ndarrayobject.h", - "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\ndarraytypes.h", - "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include\\numpy\\ufuncobject.h" - ], - "extra_compile_args": [ - "-std=c99" - ], - "include_dirs": [ - "C:\\Users\\joseph.gibson\\Anaconda3\\envs\\pygom_development\\lib\\site-packages\\numpy\\core\\include" - ], - "name": "pygom.model._tau_leap", - "sources": [ - "pygom/model/_tau_leap.pyx" - ] - }, - "module_name": "pygom.model._tau_leap" -} -END: Cython Metadata */ - -#ifndef PY_SSIZE_T_CLEAN -#define PY_SSIZE_T_CLEAN -#endif /* PY_SSIZE_T_CLEAN */ -#if defined(CYTHON_LIMITED_API) && 0 - #ifndef Py_LIMITED_API - #if CYTHON_LIMITED_API+0 > 0x03030000 - #define Py_LIMITED_API CYTHON_LIMITED_API - #else - #define Py_LIMITED_API 0x03030000 - #endif - #endif -#endif - -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02070000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.7+ or Python 3.3+. -#else -#if defined(CYTHON_LIMITED_API) && CYTHON_LIMITED_API -#define __PYX_EXTRA_ABI_MODULE_NAME "limited" -#else -#define __PYX_EXTRA_ABI_MODULE_NAME "" -#endif -#define CYTHON_ABI "3_0_10" __PYX_EXTRA_ABI_MODULE_NAME -#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI -#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." -#define CYTHON_HEX_VERSION 0x03000AF0 -#define CYTHON_FUTURE_DIVISION 1 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #define HAVE_LONG_LONG -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX -#if defined(GRAALVM_PYTHON) - /* For very preliminary testing purposes. Most variables are set the same as PyPy. - The existence of this section does not imply that anything works or is even tested */ - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #define CYTHON_COMPILING_IN_LIMITED_API 0 - #define CYTHON_COMPILING_IN_GRAAL 1 - #define CYTHON_COMPILING_IN_NOGIL 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_TYPE_SPECS - #define CYTHON_USE_TYPE_SPECS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_GIL - #define CYTHON_FAST_GIL 0 - #undef CYTHON_METH_FASTCALL - #define CYTHON_METH_FASTCALL 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #ifndef CYTHON_PEP487_INIT_SUBCLASS - #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) - #endif - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 1 - #undef CYTHON_USE_MODULE_STATE - #define CYTHON_USE_MODULE_STATE 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 - #endif - #undef CYTHON_USE_FREELISTS - #define CYTHON_USE_FREELISTS 0 -#elif defined(PYPY_VERSION) - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #define CYTHON_COMPILING_IN_LIMITED_API 0 - #define CYTHON_COMPILING_IN_GRAAL 0 - #define CYTHON_COMPILING_IN_NOGIL 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #ifndef CYTHON_USE_TYPE_SPECS - #define CYTHON_USE_TYPE_SPECS 0 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_GIL - #define CYTHON_FAST_GIL 0 - #undef CYTHON_METH_FASTCALL - #define CYTHON_METH_FASTCALL 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #ifndef CYTHON_PEP487_INIT_SUBCLASS - #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) - #endif - #if PY_VERSION_HEX < 0x03090000 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) - #define CYTHON_PEP489_MULTI_PHASE_INIT 1 - #endif - #undef CYTHON_USE_MODULE_STATE - #define CYTHON_USE_MODULE_STATE 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1 && PYPY_VERSION_NUM >= 0x07030C00) - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 - #endif - #undef CYTHON_USE_FREELISTS - #define CYTHON_USE_FREELISTS 0 -#elif defined(CYTHON_LIMITED_API) - #ifdef Py_LIMITED_API - #undef __PYX_LIMITED_VERSION_HEX - #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API - #endif - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #define CYTHON_COMPILING_IN_LIMITED_API 1 - #define CYTHON_COMPILING_IN_GRAAL 0 - #define CYTHON_COMPILING_IN_NOGIL 0 - #undef CYTHON_CLINE_IN_TRACEBACK - #define CYTHON_CLINE_IN_TRACEBACK 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_TYPE_SPECS - #define CYTHON_USE_TYPE_SPECS 1 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #endif - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_GIL - #define CYTHON_FAST_GIL 0 - #undef CYTHON_METH_FASTCALL - #define CYTHON_METH_FASTCALL 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #ifndef CYTHON_PEP487_INIT_SUBCLASS - #define CYTHON_PEP487_INIT_SUBCLASS 1 - #endif - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_MODULE_STATE - #define CYTHON_USE_MODULE_STATE 1 - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #endif - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 - #endif - #undef CYTHON_USE_FREELISTS - #define CYTHON_USE_FREELISTS 0 -#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #define CYTHON_COMPILING_IN_LIMITED_API 0 - #define CYTHON_COMPILING_IN_GRAAL 0 - #define CYTHON_COMPILING_IN_NOGIL 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #ifndef CYTHON_USE_TYPE_SPECS - #define CYTHON_USE_TYPE_SPECS 0 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #ifndef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #ifndef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_GIL - #define CYTHON_FAST_GIL 0 - #ifndef CYTHON_METH_FASTCALL - #define CYTHON_METH_FASTCALL 1 - #endif - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #ifndef CYTHON_PEP487_INIT_SUBCLASS - #define CYTHON_PEP487_INIT_SUBCLASS 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 1 - #endif - #ifndef CYTHON_USE_MODULE_STATE - #define CYTHON_USE_MODULE_STATE 0 - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 1 - #endif - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 - #endif - #ifndef CYTHON_USE_FREELISTS - #define CYTHON_USE_FREELISTS 0 - #endif -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #define CYTHON_COMPILING_IN_LIMITED_API 0 - #define CYTHON_COMPILING_IN_GRAAL 0 - #define CYTHON_COMPILING_IN_NOGIL 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #ifndef CYTHON_USE_TYPE_SPECS - #define CYTHON_USE_TYPE_SPECS 0 - #endif - #ifndef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #ifndef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_GIL - #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030C00A6) - #endif - #ifndef CYTHON_METH_FASTCALL - #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1) - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP487_INIT_SUBCLASS - #define CYTHON_PEP487_INIT_SUBCLASS 1 - #endif - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) - #define CYTHON_PEP489_MULTI_PHASE_INIT 1 - #endif - #ifndef CYTHON_USE_MODULE_STATE - #define CYTHON_USE_MODULE_STATE 0 - #endif - #if PY_VERSION_HEX < 0x030400a1 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #elif !defined(CYTHON_USE_TP_FINALIZE) - #define CYTHON_USE_TP_FINALIZE 1 - #endif - #if PY_VERSION_HEX < 0x030600B1 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #elif !defined(CYTHON_USE_DICT_VERSIONS) - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5) - #endif - #if PY_VERSION_HEX < 0x030700A3 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #elif !defined(CYTHON_USE_EXC_INFO_STACK) - #define CYTHON_USE_EXC_INFO_STACK 1 - #endif - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 - #endif - #ifndef CYTHON_USE_FREELISTS - #define CYTHON_USE_FREELISTS 1 - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if !defined(CYTHON_VECTORCALL) -#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1) -#endif -#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1) -#if CYTHON_USE_PYLONG_INTERNALS - #if PY_MAJOR_VERSION < 3 - #include "longintrepr.h" - #endif - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED - #if defined(__cplusplus) - /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 - * but leads to warnings with -pedantic, since it is a C++17 feature */ - #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) - #if __has_cpp_attribute(maybe_unused) - #define CYTHON_UNUSED [[maybe_unused]] - #endif - #endif - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR - #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_USE_CPP_STD_MOVE - #if defined(__cplusplus) && (\ - __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) - #define CYTHON_USE_CPP_STD_MOVE 1 - #else - #define CYTHON_USE_CPP_STD_MOVE 0 - #endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; - #endif - #endif - #if _MSC_VER < 1300 - #ifdef _WIN64 - typedef unsigned long long __pyx_uintptr_t; - #else - typedef unsigned int __pyx_uintptr_t; - #endif - #else - #ifdef _WIN64 - typedef unsigned __int64 __pyx_uintptr_t; - #else - typedef unsigned __int32 __pyx_uintptr_t; - #endif - #endif -#else - #include - typedef uintptr_t __pyx_uintptr_t; -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) - /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 - * but leads to warnings with -pedantic, since it is a C++17 feature */ - #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif -#ifdef __cplusplus - template - struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; - #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) -#else - #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) -#endif -#if CYTHON_COMPILING_IN_PYPY == 1 - #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x030A0000) -#else - #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000) -#endif -#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) - -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #elif defined(__GNUC__) - #define CYTHON_INLINE __inline__ - #elif defined(_MSC_VER) - #define CYTHON_INLINE __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_INLINE inline - #else - #define CYTHON_INLINE - #endif -#endif - -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_DefaultClassType PyClass_Type - #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" - #define __Pyx_DefaultClassType PyType_Type -#if CYTHON_COMPILING_IN_LIMITED_API - static CYTHON_INLINE PyObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, - PyObject *code, PyObject *c, PyObject* n, PyObject *v, - PyObject *fv, PyObject *cell, PyObject* fn, - PyObject *name, int fline, PyObject *lnos) { - PyObject *exception_table = NULL; - PyObject *types_module=NULL, *code_type=NULL, *result=NULL; - #if __PYX_LIMITED_VERSION_HEX < 0x030B0000 - PyObject *version_info; - PyObject *py_minor_version = NULL; - #endif - long minor_version = 0; - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - #if __PYX_LIMITED_VERSION_HEX >= 0x030B0000 - minor_version = 11; - #else - if (!(version_info = PySys_GetObject("version_info"))) goto end; - if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; - minor_version = PyLong_AsLong(py_minor_version); - Py_DECREF(py_minor_version); - if (minor_version == -1 && PyErr_Occurred()) goto end; - #endif - if (!(types_module = PyImport_ImportModule("types"))) goto end; - if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; - if (minor_version <= 7) { - (void)p; - result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOO", a, k, l, s, f, code, - c, n, v, fn, name, fline, lnos, fv, cell); - } else if (minor_version <= 10) { - result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOO", a,p, k, l, s, f, code, - c, n, v, fn, name, fline, lnos, fv, cell); - } else { - if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; - result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOO", a,p, k, l, s, f, code, - c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); - } - end: - Py_XDECREF(code_type); - Py_XDECREF(exception_table); - Py_XDECREF(types_module); - if (type) { - PyErr_Restore(type, value, traceback); - } - return result; - } - #ifndef CO_OPTIMIZED - #define CO_OPTIMIZED 0x0001 - #endif - #ifndef CO_NEWLOCALS - #define CO_NEWLOCALS 0x0002 - #endif - #ifndef CO_VARARGS - #define CO_VARARGS 0x0004 - #endif - #ifndef CO_VARKEYWORDS - #define CO_VARKEYWORDS 0x0008 - #endif - #ifndef CO_ASYNC_GENERATOR - #define CO_ASYNC_GENERATOR 0x0200 - #endif - #ifndef CO_GENERATOR - #define CO_GENERATOR 0x0020 - #endif - #ifndef CO_COROUTINE - #define CO_COROUTINE 0x0080 - #endif -#elif PY_VERSION_HEX >= 0x030B0000 - static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, - PyObject *code, PyObject *c, PyObject* n, PyObject *v, - PyObject *fv, PyObject *cell, PyObject* fn, - PyObject *name, int fline, PyObject *lnos) { - PyCodeObject *result; - PyObject *empty_bytes = PyBytes_FromStringAndSize("", 0); - if (!empty_bytes) return NULL; - result = - #if PY_VERSION_HEX >= 0x030C0000 - PyUnstable_Code_NewWithPosOnlyArgs - #else - PyCode_NewWithPosOnlyArgs - #endif - (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, empty_bytes); - Py_DECREF(empty_bytes); - return result; - } -#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif -#endif -#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) - #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) -#else - #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) -#endif -#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) - #define __Pyx_Py_Is(x, y) Py_Is(x, y) -#else - #define __Pyx_Py_Is(x, y) ((x) == (y)) -#endif -#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) - #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) -#else - #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) -#endif -#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) - #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) -#else - #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) -#endif -#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) - #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) -#else - #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) -#endif -#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) -#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) -#else - #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) -#endif -#ifndef CO_COROUTINE - #define CO_COROUTINE 0x80 -#endif -#ifndef CO_ASYNC_GENERATOR - #define CO_ASYNC_GENERATOR 0x200 -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef Py_TPFLAGS_SEQUENCE - #define Py_TPFLAGS_SEQUENCE 0 -#endif -#ifndef Py_TPFLAGS_MAPPING - #define Py_TPFLAGS_MAPPING 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #if PY_VERSION_HEX >= 0x030d00A4 - # define __Pyx_PyCFunctionFast PyCFunctionFast - # define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords - #else - # define __Pyx_PyCFunctionFast _PyCFunctionFast - # define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords - #endif -#endif -#if CYTHON_METH_FASTCALL - #define __Pyx_METH_FASTCALL METH_FASTCALL - #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast - #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords -#else - #define __Pyx_METH_FASTCALL METH_VARARGS - #define __Pyx_PyCFunction_FastCall PyCFunction - #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords -#endif -#if CYTHON_VECTORCALL - #define __pyx_vectorcallfunc vectorcallfunc - #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET - #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) -#elif CYTHON_BACKPORT_VECTORCALL - typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames); - #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) - #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(((size_t)(n)) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)) -#else - #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 - #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) -#endif -#if PY_MAJOR_VERSION >= 0x030900B1 -#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) -#else -#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) -#endif -#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) -#elif !CYTHON_COMPILING_IN_LIMITED_API -#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) -#endif -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) -static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { - return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; -} -#endif -static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void *cfunc) { -#if CYTHON_COMPILING_IN_LIMITED_API - return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; -#else - return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; -#endif -} -#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) -#if __PYX_LIMITED_VERSION_HEX < 0x030900B1 - #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) - typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); -#else - #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) - #define __Pyx_PyCMethod PyCMethod -#endif -#ifndef METH_METHOD - #define METH_METHOD 0x200 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_LIMITED_API - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if CYTHON_COMPILING_IN_LIMITED_API - #define __Pyx_PyThreadState_Current PyThreadState_Get() -#elif !CYTHON_FAST_THREAD_STATE - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x030d00A1 - #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if CYTHON_COMPILING_IN_LIMITED_API -static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op) -{ - void *result; - result = PyModule_GetState(op); - if (!result) - Py_FatalError("Couldn't find the module state"); - return result; -} -#endif -#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE(obj), name, func_ctype) -#if CYTHON_COMPILING_IN_LIMITED_API - #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) -#else - #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if PY_MAJOR_VERSION < 3 - #if CYTHON_COMPILING_IN_PYPY - #if PYPY_VERSION_NUM < 0x07030600 - #if defined(__cplusplus) && __cplusplus >= 201402L - [[deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")]] - #elif defined(__GNUC__) || defined(__clang__) - __attribute__ ((__deprecated__("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6"))) - #elif defined(_MSC_VER) - __declspec(deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")) - #endif - static CYTHON_INLINE int PyGILState_Check(void) { - return 0; - } - #else // PYPY_VERSION_NUM < 0x07030600 - #endif // PYPY_VERSION_NUM < 0x07030600 - #else - static CYTHON_INLINE int PyGILState_Check(void) { - PyThreadState * tstate = _PyThreadState_Current; - return tstate && (tstate == PyGILState_GetThisThreadState()); - } - #endif -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX > 0x030600B4 && PY_VERSION_HEX < 0x030d0000 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { - PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); - if (res == NULL) PyErr_Clear(); - return res; -} -#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000) -#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError -#define __Pyx_PyDict_GetItemStr PyDict_GetItem -#else -static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { -#if CYTHON_COMPILING_IN_PYPY - return PyDict_GetItem(dict, name); -#else - PyDictEntry *ep; - PyDictObject *mp = (PyDictObject*) dict; - long hash = ((PyStringObject *) name)->ob_shash; - assert(hash != -1); - ep = (mp->ma_lookup)(mp, name, hash); - if (ep == NULL) { - return NULL; - } - return ep->me_value; -#endif -} -#define __Pyx_PyDict_GetItemStr PyDict_GetItem -#endif -#if CYTHON_USE_TYPE_SLOTS - #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) - #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) - #define __Pyx_PyObject_GetIterNextFunc(obj) (Py_TYPE(obj)->tp_iternext) -#else - #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) - #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) - #define __Pyx_PyObject_GetIterNextFunc(obj) PyIter_Next -#endif -#if CYTHON_COMPILING_IN_LIMITED_API - #define __Pyx_SetItemOnTypeDict(tp, k, v) PyObject_GenericSetAttr((PyObject*)tp, k, v) -#else - #define __Pyx_SetItemOnTypeDict(tp, k, v) PyDict_SetItem(tp->tp_dict, k, v) -#endif -#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000 -#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ - PyTypeObject *type = Py_TYPE((PyObject*)obj);\ - assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ - PyObject_GC_Del(obj);\ - Py_DECREF(type);\ -} -#else -#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) -#endif -#if CYTHON_COMPILING_IN_LIMITED_API - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GetLength(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) - #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) - #define __Pyx_PyUnicode_DATA(u) ((void*)u) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) -#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #if PY_VERSION_HEX >= 0x030C0000 - #define __Pyx_PyUnicode_READY(op) (0) - #else - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #endif - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) - #if PY_VERSION_HEX >= 0x030C0000 - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) - #else - #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) - #endif - #endif -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535U : 1114111U) - #define __Pyx_PyUnicode_KIND(u) ((int)sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = (Py_UNICODE) ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #if !defined(PyUnicode_DecodeUnicodeEscape) - #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) - #endif - #if !defined(PyUnicode_Contains) || (PY_MAJOR_VERSION == 2 && PYPY_VERSION_NUM < 0x07030500) - #undef PyUnicode_Contains - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) - #endif - #if !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) - #endif - #if !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) - #endif -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#ifndef PyObject_Unicode - #define PyObject_Unicode PyObject_Str -#endif -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#if CYTHON_COMPILING_IN_CPYTHON - #define __Pyx_PySequence_ListKeepNew(obj)\ - (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) -#else - #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) -#endif -#if PY_VERSION_HEX >= 0x030900A4 - #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) -#else - #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) - #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) - #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) - #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) - #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) - #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) - #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) - #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) -#else - #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) - #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) - #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) - #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) - #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) - #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) - #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) - #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) -#endif -#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 - #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) -#else - static CYTHON_INLINE PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { - PyObject *module = PyImport_AddModule(name); - Py_XINCREF(module); - return module; - } -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define __Pyx_Py3Int_Check(op) PyLong_Check(op) - #define __Pyx_Py3Int_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#else - #define __Pyx_Py3Int_Check(op) (PyLong_Check(op) || PyInt_Check(op)) - #define __Pyx_Py3Int_CheckExact(op) (PyLong_CheckExact(op) || PyInt_CheckExact(op)) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) - #if !defined(_USE_MATH_DEFINES) - #define _USE_MATH_DEFINES - #endif -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - -#define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } -#define __PYX_ERR(f_index, lineno, Ln_error) \ - { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } - -#ifdef CYTHON_EXTERN_C - #undef __PYX_EXTERN_C - #define __PYX_EXTERN_C CYTHON_EXTERN_C -#elif defined(__PYX_EXTERN_C) - #ifdef _MSC_VER - #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") - #else - #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. - #endif -#else - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__pygom__model___tau_leap -#define __PYX_HAVE_API__pygom__model___tau_leap -/* Early includes */ -#include -#include - - /* Using NumPy API declarations from "numpy/__init__.cython-30.pxd" */ - -#include "numpy/arrayobject.h" -#include "numpy/ndarrayobject.h" -#include "numpy/ndarraytypes.h" -#include "numpy/arrayscalars.h" -#include "numpy/ufuncobject.h" -#include -#include "pythread.h" -#include -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #if PY_VERSION_HEX >= 0x030C00A7 - #ifndef _PyLong_SIGN_MASK - #define _PyLong_SIGN_MASK 3 - #endif - #ifndef _PyLong_NON_SIZE_BITS - #define _PyLong_NON_SIZE_BITS 3 - #endif - #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) - #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) - #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) - #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) - #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) - #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) - #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) - #define __Pyx_PyLong_SignedDigitCount(x)\ - ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) - #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) - #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) - #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) - #else - #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) - #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) - #endif - typedef Py_ssize_t __Pyx_compact_pylong; - typedef size_t __Pyx_compact_upylong; - #else - #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) - #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) - #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) - #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) - #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) - #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) - #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) - #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) - #define __Pyx_PyLong_CompactValue(x)\ - ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) - typedef sdigit __Pyx_compact_pylong; - typedef digit __Pyx_compact_upylong; - #endif - #if PY_VERSION_HEX >= 0x030C00A5 - #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) - #else - #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) - #endif -#endif -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -#include -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = (char) c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#include -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -#if !CYTHON_USE_MODULE_STATE -static PyObject *__pyx_m = NULL; -#endif -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm = __FILE__; -static const char *__pyx_filename; - -/* Header.proto */ -#if !defined(CYTHON_CCOMPLEX) - #if defined(__cplusplus) - #define CYTHON_CCOMPLEX 1 - #elif (defined(_Complex_I) && !defined(_MSC_VER)) || ((defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_COMPLEX__) && !defined(_MSC_VER)) - #define CYTHON_CCOMPLEX 1 - #else - #define CYTHON_CCOMPLEX 0 - #endif -#endif -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - #include - #else - #include - #endif -#endif -#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) - #undef _Complex_I - #define _Complex_I 1.0fj -#endif - -/* #### Code section: filename_table ### */ - -static const char *__pyx_f[] = { - "pygom\\\\model\\\\_tau_leap.pyx", - "", - "__init__.cython-30.pxd", - "type.pxd", -}; -/* #### Code section: utility_code_proto_before_types ### */ -/* ForceInitThreads.proto */ -#ifndef __PYX_FORCE_INIT_THREADS - #define __PYX_FORCE_INIT_THREADS 0 -#endif - -/* NoFastGil.proto */ -#define __Pyx_PyGILState_Ensure PyGILState_Ensure -#define __Pyx_PyGILState_Release PyGILState_Release -#define __Pyx_FastGIL_Remember() -#define __Pyx_FastGIL_Forget() -#define __Pyx_FastGilFuncInit() - -/* BufferFormatStructs.proto */ -struct __Pyx_StructField_; -#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) -typedef struct { - const char* name; - struct __Pyx_StructField_* fields; - size_t size; - size_t arraysize[8]; - int ndim; - char typegroup; - char is_unsigned; - int flags; -} __Pyx_TypeInfo; -typedef struct __Pyx_StructField_ { - __Pyx_TypeInfo* type; - const char* name; - size_t offset; -} __Pyx_StructField; -typedef struct { - __Pyx_StructField* field; - size_t parent_offset; -} __Pyx_BufFmt_StackElem; -typedef struct { - __Pyx_StructField root; - __Pyx_BufFmt_StackElem* head; - size_t fmt_offset; - size_t new_count, enc_count; - size_t struct_alignment; - int is_complex; - char enc_type; - char new_packmode; - char enc_packmode; - char is_valid_array; -} __Pyx_BufFmt_Context; - -/* Atomics.proto */ -#include -#ifndef CYTHON_ATOMICS - #define CYTHON_ATOMICS 1 -#endif -#define __PYX_CYTHON_ATOMICS_ENABLED() CYTHON_ATOMICS -#define __pyx_atomic_int_type int -#define __pyx_nonatomic_int_type int -#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ - (__STDC_VERSION__ >= 201112L) &&\ - !defined(__STDC_NO_ATOMICS__)) - #include -#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ - (__cplusplus >= 201103L) ||\ - (defined(_MSC_VER) && _MSC_VER >= 1700))) - #include -#endif -#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ - (__STDC_VERSION__ >= 201112L) &&\ - !defined(__STDC_NO_ATOMICS__) &&\ - ATOMIC_INT_LOCK_FREE == 2) - #undef __pyx_atomic_int_type - #define __pyx_atomic_int_type atomic_int - #define __pyx_atomic_incr_aligned(value) atomic_fetch_add_explicit(value, 1, memory_order_relaxed) - #define __pyx_atomic_decr_aligned(value) atomic_fetch_sub_explicit(value, 1, memory_order_acq_rel) - #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) - #pragma message ("Using standard C atomics") - #elif defined(__PYX_DEBUG_ATOMICS) - #warning "Using standard C atomics" - #endif -#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ - (__cplusplus >= 201103L) ||\ -\ - (defined(_MSC_VER) && _MSC_VER >= 1700)) &&\ - ATOMIC_INT_LOCK_FREE == 2) - #undef __pyx_atomic_int_type - #define __pyx_atomic_int_type std::atomic_int - #define __pyx_atomic_incr_aligned(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_relaxed) - #define __pyx_atomic_decr_aligned(value) std::atomic_fetch_sub_explicit(value, 1, std::memory_order_acq_rel) - #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) - #pragma message ("Using standard C++ atomics") - #elif defined(__PYX_DEBUG_ATOMICS) - #warning "Using standard C++ atomics" - #endif -#elif CYTHON_ATOMICS && (__GNUC__ >= 5 || (__GNUC__ == 4 &&\ - (__GNUC_MINOR__ > 1 ||\ - (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 2)))) - #define __pyx_atomic_incr_aligned(value) __sync_fetch_and_add(value, 1) - #define __pyx_atomic_decr_aligned(value) __sync_fetch_and_sub(value, 1) - #ifdef __PYX_DEBUG_ATOMICS - #warning "Using GNU atomics" - #endif -#elif CYTHON_ATOMICS && defined(_MSC_VER) - #include - #undef __pyx_atomic_int_type - #define __pyx_atomic_int_type long - #undef __pyx_nonatomic_int_type - #define __pyx_nonatomic_int_type long - #pragma intrinsic (_InterlockedExchangeAdd) - #define __pyx_atomic_incr_aligned(value) _InterlockedExchangeAdd(value, 1) - #define __pyx_atomic_decr_aligned(value) _InterlockedExchangeAdd(value, -1) - #ifdef __PYX_DEBUG_ATOMICS - #pragma message ("Using MSVC atomics") - #endif -#else - #undef CYTHON_ATOMICS - #define CYTHON_ATOMICS 0 - #ifdef __PYX_DEBUG_ATOMICS - #warning "Not using atomics" - #endif -#endif -#if CYTHON_ATOMICS - #define __pyx_add_acquisition_count(memview)\ - __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview)) - #define __pyx_sub_acquisition_count(memview)\ - __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview)) -#else - #define __pyx_add_acquisition_count(memview)\ - __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock) - #define __pyx_sub_acquisition_count(memview)\ - __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock) -#endif - -/* MemviewSliceStruct.proto */ -struct __pyx_memoryview_obj; -typedef struct { - struct __pyx_memoryview_obj *memview; - char *data; - Py_ssize_t shape[8]; - Py_ssize_t strides[8]; - Py_ssize_t suboffsets[8]; -} __Pyx_memviewslice; -#define __Pyx_MemoryView_Len(m) (m.shape[0]) - -/* #### Code section: numeric_typedefs ### */ - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":770 - * # in Cython to enable them only on the right systems. - * - * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t - */ -typedef npy_int8 __pyx_t_5numpy_int8_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":771 - * - * ctypedef npy_int8 int8_t - * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< - * ctypedef npy_int32 int32_t - * ctypedef npy_int64 int64_t - */ -typedef npy_int16 __pyx_t_5numpy_int16_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":772 - * ctypedef npy_int8 int8_t - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< - * ctypedef npy_int64 int64_t - * #ctypedef npy_int96 int96_t - */ -typedef npy_int32 __pyx_t_5numpy_int32_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":773 - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t - * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< - * #ctypedef npy_int96 int96_t - * #ctypedef npy_int128 int128_t - */ -typedef npy_int64 __pyx_t_5numpy_int64_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":777 - * #ctypedef npy_int128 int128_t - * - * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t - */ -typedef npy_uint8 __pyx_t_5numpy_uint8_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":778 - * - * ctypedef npy_uint8 uint8_t - * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< - * ctypedef npy_uint32 uint32_t - * ctypedef npy_uint64 uint64_t - */ -typedef npy_uint16 __pyx_t_5numpy_uint16_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":779 - * ctypedef npy_uint8 uint8_t - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< - * ctypedef npy_uint64 uint64_t - * #ctypedef npy_uint96 uint96_t - */ -typedef npy_uint32 __pyx_t_5numpy_uint32_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":780 - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t - * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< - * #ctypedef npy_uint96 uint96_t - * #ctypedef npy_uint128 uint128_t - */ -typedef npy_uint64 __pyx_t_5numpy_uint64_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":784 - * #ctypedef npy_uint128 uint128_t - * - * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< - * ctypedef npy_float64 float64_t - * #ctypedef npy_float80 float80_t - */ -typedef npy_float32 __pyx_t_5numpy_float32_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":785 - * - * ctypedef npy_float32 float32_t - * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< - * #ctypedef npy_float80 float80_t - * #ctypedef npy_float128 float128_t - */ -typedef npy_float64 __pyx_t_5numpy_float64_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":792 - * ctypedef double complex complex128_t - * - * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< - * ctypedef npy_ulonglong ulonglong_t - * - */ -typedef npy_longlong __pyx_t_5numpy_longlong_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":793 - * - * ctypedef npy_longlong longlong_t - * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< - * - * ctypedef npy_intp intp_t - */ -typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":795 - * ctypedef npy_ulonglong ulonglong_t - * - * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< - * ctypedef npy_uintp uintp_t - * - */ -typedef npy_intp __pyx_t_5numpy_intp_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":796 - * - * ctypedef npy_intp intp_t - * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< - * - * ctypedef npy_double float_t - */ -typedef npy_uintp __pyx_t_5numpy_uintp_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":798 - * ctypedef npy_uintp uintp_t - * - * ctypedef npy_double float_t # <<<<<<<<<<<<<< - * ctypedef npy_double double_t - * ctypedef npy_longdouble longdouble_t - */ -typedef npy_double __pyx_t_5numpy_float_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":799 - * - * ctypedef npy_double float_t - * ctypedef npy_double double_t # <<<<<<<<<<<<<< - * ctypedef npy_longdouble longdouble_t - * - */ -typedef npy_double __pyx_t_5numpy_double_t; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":800 - * ctypedef npy_double float_t - * ctypedef npy_double double_t - * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< - * - * ctypedef float complex cfloat_t - */ -typedef npy_longdouble __pyx_t_5numpy_longdouble_t; -/* #### Code section: complex_type_declarations ### */ -/* Declarations.proto */ -#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) - #ifdef __cplusplus - typedef ::std::complex< float > __pyx_t_float_complex; - #else - typedef float _Complex __pyx_t_float_complex; - #endif -#else - typedef struct { float real, imag; } __pyx_t_float_complex; -#endif -static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); - -/* Declarations.proto */ -#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) - #ifdef __cplusplus - typedef ::std::complex< double > __pyx_t_double_complex; - #else - typedef double _Complex __pyx_t_double_complex; - #endif -#else - typedef struct { double real, imag; } __pyx_t_double_complex; -#endif -static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); - -/* Declarations.proto */ -#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) - #ifdef __cplusplus - typedef ::std::complex< long double > __pyx_t_long_double_complex; - #else - typedef long double _Complex __pyx_t_long_double_complex; - #endif -#else - typedef struct { long double real, imag; } __pyx_t_long_double_complex; -#endif -static CYTHON_INLINE __pyx_t_long_double_complex __pyx_t_long_double_complex_from_parts(long double, long double); - -/* #### Code section: type_declarations ### */ - -/*--- Type declarations ---*/ -struct __pyx_array_obj; -struct __pyx_MemviewEnum_obj; -struct __pyx_memoryview_obj; -struct __pyx_memoryviewslice_obj; - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1096 - * - * # Iterator API added in v1.6 - * ctypedef int (*NpyIter_IterNextFunc)(NpyIter* it) noexcept nogil # <<<<<<<<<<<<<< - * ctypedef void (*NpyIter_GetMultiIndexFunc)(NpyIter* it, npy_intp* outcoords) noexcept nogil - * - */ -typedef int (*__pyx_t_5numpy_NpyIter_IterNextFunc)(NpyIter *); - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1097 - * # Iterator API added in v1.6 - * ctypedef int (*NpyIter_IterNextFunc)(NpyIter* it) noexcept nogil - * ctypedef void (*NpyIter_GetMultiIndexFunc)(NpyIter* it, npy_intp* outcoords) noexcept nogil # <<<<<<<<<<<<<< - * - * cdef extern from "numpy/arrayobject.h": - */ -typedef void (*__pyx_t_5numpy_NpyIter_GetMultiIndexFunc)(NpyIter *, npy_intp *); -struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_jn; -struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_jn; -struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_yn; -struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_yn; -struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_in; -struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_in; -struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_kn; -struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_kn; - -/* "scipy/special/cython_special.pxd":8 - * double - * - * cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) noexcept nogil # <<<<<<<<<<<<<< - * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) noexcept nogil - * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) noexcept nogil - */ -struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_jn { - int __pyx_n; - int derivative; -}; -struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_jn { - int __pyx_n; - int derivative; -}; - -/* "scipy/special/cython_special.pxd":9 - * - * cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) noexcept nogil - * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) noexcept nogil # <<<<<<<<<<<<<< - * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) noexcept nogil - * cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) noexcept nogil - */ -struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_yn { - int __pyx_n; - int derivative; -}; -struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_yn { - int __pyx_n; - int derivative; -}; - -/* "scipy/special/cython_special.pxd":10 - * cpdef number_t spherical_jn(long n, number_t z, bint derivative=*) noexcept nogil - * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) noexcept nogil - * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) noexcept nogil # <<<<<<<<<<<<<< - * cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) noexcept nogil - * - */ -struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_in { - int __pyx_n; - int derivative; -}; -struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_in { - int __pyx_n; - int derivative; -}; - -/* "scipy/special/cython_special.pxd":11 - * cpdef number_t spherical_yn(long n, number_t z, bint derivative=*) noexcept nogil - * cpdef number_t spherical_in(long n, number_t z, bint derivative=*) noexcept nogil - * cpdef number_t spherical_kn(long n, number_t z, bint derivative=*) noexcept nogil # <<<<<<<<<<<<<< - * - * ctypedef fused Dd_number_t: - */ -struct __pyx_fuse_0__pyx_opt_args_5scipy_7special_14cython_special_spherical_kn { - int __pyx_n; - int derivative; -}; -struct __pyx_fuse_1__pyx_opt_args_5scipy_7special_14cython_special_spherical_kn { - int __pyx_n; - int derivative; -}; - -/* "View.MemoryView":114 - * @cython.collection_type("sequence") - * @cname("__pyx_array") - * cdef class array: # <<<<<<<<<<<<<< - * - * cdef: - */ -struct __pyx_array_obj { - PyObject_HEAD - struct __pyx_vtabstruct_array *__pyx_vtab; - char *data; - Py_ssize_t len; - char *format; - int ndim; - Py_ssize_t *_shape; - Py_ssize_t *_strides; - Py_ssize_t itemsize; - PyObject *mode; - PyObject *_format; - void (*callback_free_data)(void *); - int free_data; - int dtype_is_object; -}; - - -/* "View.MemoryView":302 - * - * @cname('__pyx_MemviewEnum') - * cdef class Enum(object): # <<<<<<<<<<<<<< - * cdef object name - * def __init__(self, name): - */ -struct __pyx_MemviewEnum_obj { - PyObject_HEAD - PyObject *name; -}; - - -/* "View.MemoryView":337 - * - * @cname('__pyx_memoryview') - * cdef class memoryview: # <<<<<<<<<<<<<< - * - * cdef object obj - */ -struct __pyx_memoryview_obj { - PyObject_HEAD - struct __pyx_vtabstruct_memoryview *__pyx_vtab; - PyObject *obj; - PyObject *_size; - PyObject *_array_interface; - PyThread_type_lock lock; - __pyx_atomic_int_type acquisition_count; - Py_buffer view; - int flags; - int dtype_is_object; - __Pyx_TypeInfo *typeinfo; -}; - - -/* "View.MemoryView":952 - * @cython.collection_type("sequence") - * @cname('__pyx_memoryviewslice') - * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<< - * "Internal class for passing memoryview slices to Python" - * - */ -struct __pyx_memoryviewslice_obj { - struct __pyx_memoryview_obj __pyx_base; - __Pyx_memviewslice from_slice; - PyObject *from_object; - PyObject *(*to_object_func)(char *); - int (*to_dtype_func)(char *, PyObject *); -}; - - - -/* "View.MemoryView":114 - * @cython.collection_type("sequence") - * @cname("__pyx_array") - * cdef class array: # <<<<<<<<<<<<<< - * - * cdef: - */ - -struct __pyx_vtabstruct_array { - PyObject *(*get_memview)(struct __pyx_array_obj *); -}; -static struct __pyx_vtabstruct_array *__pyx_vtabptr_array; - - -/* "View.MemoryView":337 - * - * @cname('__pyx_memoryview') - * cdef class memoryview: # <<<<<<<<<<<<<< - * - * cdef object obj - */ - -struct __pyx_vtabstruct_memoryview { - char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *); - PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *); - PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *); - PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *); - PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *); - PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *); - PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *); - PyObject *(*_get_base)(struct __pyx_memoryview_obj *); -}; -static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview; - - -/* "View.MemoryView":952 - * @cython.collection_type("sequence") - * @cname('__pyx_memoryviewslice') - * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<< - * "Internal class for passing memoryview slices to Python" - * - */ - -struct __pyx_vtabstruct__memoryviewslice { - struct __pyx_vtabstruct_memoryview __pyx_base; -}; -static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice; -/* #### Code section: utility_code_proto ### */ - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, Py_ssize_t); - void (*DECREF)(void*, PyObject*, Py_ssize_t); - void (*GOTREF)(void*, PyObject*, Py_ssize_t); - void (*GIVEREF)(void*, PyObject*, Py_ssize_t); - void* (*SetupContext)(const char*, Py_ssize_t, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ - } - #define __Pyx_RefNannyFinishContextNogil() {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __Pyx_RefNannyFinishContext();\ - PyGILState_Release(__pyx_gilstate_save);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__)) - #define __Pyx_RefNannyFinishContextNogil() __Pyx_RefNannyFinishContext() -#endif - #define __Pyx_RefNannyFinishContextNogil() {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __Pyx_RefNannyFinishContext();\ - PyGILState_Release(__pyx_gilstate_save);\ - } - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) - #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContextNogil() - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_Py_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; Py_XDECREF(tmp);\ - } while (0) -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyErrExceptionMatches.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); -#else -#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) -#endif - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#if PY_VERSION_HEX >= 0x030C00A6 -#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) -#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) -#else -#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) -#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) -#endif -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) -#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* PyObjectGetAttrStrNoError.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* TupleAndListFromArray.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); -static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); -#endif - -/* IncludeStringH.proto */ -#include - -/* BytesEquals.proto */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); - -/* UnicodeEquals.proto */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); - -/* fastcall.proto */ -#if CYTHON_AVOID_BORROWED_REFS - #define __Pyx_Arg_VARARGS(args, i) PySequence_GetItem(args, i) -#elif CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i) -#else - #define __Pyx_Arg_VARARGS(args, i) PyTuple_GetItem(args, i) -#endif -#if CYTHON_AVOID_BORROWED_REFS - #define __Pyx_Arg_NewRef_VARARGS(arg) __Pyx_NewRef(arg) - #define __Pyx_Arg_XDECREF_VARARGS(arg) Py_XDECREF(arg) -#else - #define __Pyx_Arg_NewRef_VARARGS(arg) arg - #define __Pyx_Arg_XDECREF_VARARGS(arg) -#endif -#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) -#define __Pyx_KwValues_VARARGS(args, nargs) NULL -#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) -#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) -#if CYTHON_METH_FASTCALL - #define __Pyx_Arg_FASTCALL(args, i) args[i] - #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds) - #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) - static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 - CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); - #else - #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) - #endif - #define __Pyx_Arg_NewRef_FASTCALL(arg) arg /* no-op, __Pyx_Arg_FASTCALL is direct and this needs - to have the same reference counting */ - #define __Pyx_Arg_XDECREF_FASTCALL(arg) -#else - #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS - #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS - #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS - #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS - #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS - #define __Pyx_Arg_NewRef_FASTCALL(arg) __Pyx_Arg_NewRef_VARARGS(arg) - #define __Pyx_Arg_XDECREF_FASTCALL(arg) __Pyx_Arg_XDECREF_VARARGS(arg) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS -#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start) -#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start) -#else -#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) -#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) -#endif - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues, - PyObject **argnames[], - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, - const char* function_name); - -/* ArgTypeTest.proto */ -#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ - ((likely(__Pyx_IS_TYPE(obj, type) | (none_allowed && (obj == Py_None)))) ? 1 :\ - __Pyx__ArgTypeTest(obj, type, name, exact)) -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); - -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); - -/* PyFunctionFastCall.proto */ -#if CYTHON_FAST_PYCALL -#if !CYTHON_VECTORCALL -#define __Pyx_PyFunction_FastCall(func, args, nargs)\ - __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#endif -#define __Pyx_BUILD_ASSERT_EXPR(cond)\ - (sizeof(char [1 - 2*!(cond)]) - 1) -#ifndef Py_MEMBER_SIZE -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#endif -#if !CYTHON_VECTORCALL -#if PY_VERSION_HEX >= 0x03080000 - #include "frameobject.h" -#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API - #ifndef Py_BUILD_CORE - #define Py_BUILD_CORE 1 - #endif - #include "internal/pycore_frame.h" -#endif - #define __Pxy_PyFrame_Initialize_Offsets() - #define __Pyx_PyFrame_GetLocalsplus(frame) ((frame)->f_localsplus) -#else - static size_t __pyx_pyframe_localsplus_offset = 0; - #include "frameobject.h" - #define __Pxy_PyFrame_Initialize_Offsets()\ - ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ - (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) - #define __Pyx_PyFrame_GetLocalsplus(frame)\ - (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif -#endif -#endif - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* PyObjectCallMethO.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); -#endif - -/* PyObjectFastCall.proto */ -#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) -static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs); - -/* RaiseUnexpectedTypeError.proto */ -static int __Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj); - -/* GCCDiagnostics.proto */ -#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -#define __Pyx_HAS_GCC_DIAGNOSTIC -#endif - -/* BuildPyUnicode.proto */ -static PyObject* __Pyx_PyUnicode_BuildFromAscii(Py_ssize_t ulength, char* chars, int clength, - int prepend_sign, char padding_char); - -/* CIntToPyUnicode.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_int(int value, Py_ssize_t width, char padding_char, char format_char); - -/* CIntToPyUnicode.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_Py_ssize_t(Py_ssize_t value, Py_ssize_t width, char padding_char, char format_char); - -/* JoinPyUnicode.proto */ -static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength, - Py_UCS4 max_char); - -/* StrEquals.proto */ -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals -#else -#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals -#endif - -/* PyObjectFormatSimple.proto */ -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - PyObject_Format(s, f)) -#elif PY_MAJOR_VERSION < 3 - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - likely(PyString_CheckExact(s)) ? PyUnicode_FromEncodedObject(s, NULL, "strict") :\ - PyObject_Format(s, f)) -#elif CYTHON_USE_TYPE_SLOTS - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - likely(PyLong_CheckExact(s)) ? PyLong_Type.tp_repr(s) :\ - likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_repr(s) :\ - PyObject_Format(s, f)) -#else - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - PyObject_Format(s, f)) -#endif - -CYTHON_UNUSED static int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *); /*proto*/ -/* GetAttr.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); - -/* GetItemInt.proto */ -#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ - __Pyx_GetItemInt_Generic(o, to_py_func(i)))) -#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, - int is_list, int wraparound, int boundscheck); - -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - -/* ObjectGetItem.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key); -#else -#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) -#endif - -/* KeywordStringCheck.proto */ -static int __Pyx_CheckKeywordStrings(PyObject *kw, const char* function_name, int kw_allowed); - -/* DivInt[Py_ssize_t].proto */ -static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); - -/* UnaryNegOverflows.proto */ -#define __Pyx_UNARY_NEG_WOULD_OVERFLOW(x)\ - (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x))) - -/* GetAttr3.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* GetModuleGlobalName.proto */ -#if CYTHON_USE_DICT_VERSIONS -#define __Pyx_GetModuleGlobalName(var, name) do {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ - (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ - __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} while(0) -#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ - PY_UINT64_T __pyx_dict_version;\ - PyObject *__pyx_dict_cached_value;\ - (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} while(0) -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); -#else -#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) -#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); -#endif - -/* AssertionsEnabled.proto */ -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define __Pyx_init_assertions_enabled() (0) - #define __pyx_assertions_enabled() (1) -#elif CYTHON_COMPILING_IN_LIMITED_API || (CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030C0000) - static int __pyx_assertions_enabled_flag; - #define __pyx_assertions_enabled() (__pyx_assertions_enabled_flag) - static int __Pyx_init_assertions_enabled(void) { - PyObject *builtins, *debug, *debug_str; - int flag; - builtins = PyEval_GetBuiltins(); - if (!builtins) goto bad; - debug_str = PyUnicode_FromStringAndSize("__debug__", 9); - if (!debug_str) goto bad; - debug = PyObject_GetItem(builtins, debug_str); - Py_DECREF(debug_str); - if (!debug) goto bad; - flag = PyObject_IsTrue(debug); - Py_DECREF(debug); - if (flag == -1) goto bad; - __pyx_assertions_enabled_flag = flag; - return 0; - bad: - __pyx_assertions_enabled_flag = 1; - return -1; - } -#else - #define __Pyx_init_assertions_enabled() (0) - #define __pyx_assertions_enabled() (!Py_OptimizeFlag) -#endif - -/* RaiseTooManyValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); - -/* RaiseNeedMoreValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); - -/* RaiseNoneIterError.proto */ -static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); - -/* ExtTypeTest.proto */ -static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); - -/* GetTopmostException.proto */ -#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE -static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); -#endif - -/* SaveResetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -#else -#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) -#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) -#endif - -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* SwapException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* ImportDottedModule.proto */ -static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple); -#if PY_MAJOR_VERSION >= 3 -static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple); -#endif - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -CYTHON_UNUSED static int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -/* ListCompAppend.proto */ -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { - PyListObject* L = (PyListObject*) list; - Py_ssize_t len = Py_SIZE(list); - if (likely(L->allocated > len)) { - Py_INCREF(x); - #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 - L->ob_item[len] = x; - #else - PyList_SET_ITEM(list, len, x); - #endif - __Pyx_SET_SIZE(list, len + 1); - return 0; - } - return PyList_Append(list, x); -} -#else -#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) -#endif - -/* PySequenceMultiply.proto */ -#define __Pyx_PySequence_Multiply_Left(mul, seq) __Pyx_PySequence_Multiply(seq, mul) -static CYTHON_INLINE PyObject* __Pyx_PySequence_Multiply(PyObject *seq, Py_ssize_t mul); - -/* SetItemInt.proto */ -#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) :\ - __Pyx_SetItemInt_Generic(o, to_py_func(i), v))) -static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v); -static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, - int is_list, int wraparound, int boundscheck); - -/* RaiseUnboundLocalError.proto */ -static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname); - -/* DivInt[long].proto */ -static CYTHON_INLINE long __Pyx_div_long(long, long); - -/* PySequenceContains.proto */ -static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { - int result = PySequence_Contains(seq, item); - return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); -} - -/* ImportFrom.proto */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); - -/* HasAttr.proto */ -#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 -#define __Pyx_HasAttr(o, n) PyObject_HasAttrWithError(o, n) -#else -static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); -#endif - -/* IsLittleEndian.proto */ -static CYTHON_INLINE int __Pyx_Is_Little_Endian(void); - -/* BufferFormatCheck.proto */ -static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); -static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, - __Pyx_BufFmt_StackElem* stack, - __Pyx_TypeInfo* type); - -/* BufferGetAndValidate.proto */ -#define __Pyx_GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)\ - ((obj == Py_None || obj == NULL) ?\ - (__Pyx_ZeroBuffer(buf), 0) :\ - __Pyx__GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)) -static int __Pyx__GetBufferAndValidate(Py_buffer* buf, PyObject* obj, - __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); -static void __Pyx_ZeroBuffer(Py_buffer* buf); -static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); -static Py_ssize_t __Pyx_minusones[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static Py_ssize_t __Pyx_zeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -/* PyObject_GenericGetAttrNoDict.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr -#endif - -/* PyObject_GenericGetAttr.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr -#endif - -/* IncludeStructmemberH.proto */ -#include - -/* FixUpExtensionType.proto */ -#if CYTHON_USE_TYPE_SPECS -static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); -#endif - -/* PyObjectCallNoArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); - -/* PyObjectGetMethod.proto */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); - -/* PyObjectCallMethod0.proto */ -static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); - -/* ValidateBasesTuple.proto */ -#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS -static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases); -#endif - -/* PyType_Ready.proto */ -CYTHON_UNUSED static int __Pyx_PyType_Ready(PyTypeObject *t); - -/* SetVTable.proto */ -static int __Pyx_SetVtable(PyTypeObject* typeptr , void* vtable); - -/* GetVTable.proto */ -static void* __Pyx_GetVtable(PyTypeObject *type); - -/* MergeVTables.proto */ -#if !CYTHON_COMPILING_IN_LIMITED_API -static int __Pyx_MergeVtables(PyTypeObject *type); -#endif - -/* SetupReduce.proto */ -#if !CYTHON_COMPILING_IN_LIMITED_API -static int __Pyx_setup_reduce(PyObject* type_obj); -#endif - -/* TypeImport.proto */ -#ifndef __PYX_HAVE_RT_ImportType_proto_3_0_10 -#define __PYX_HAVE_RT_ImportType_proto_3_0_10 -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -#include -#endif -#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || __cplusplus >= 201103L -#define __PYX_GET_STRUCT_ALIGNMENT_3_0_10(s) alignof(s) -#else -#define __PYX_GET_STRUCT_ALIGNMENT_3_0_10(s) sizeof(void*) -#endif -enum __Pyx_ImportType_CheckSize_3_0_10 { - __Pyx_ImportType_CheckSize_Error_3_0_10 = 0, - __Pyx_ImportType_CheckSize_Warn_3_0_10 = 1, - __Pyx_ImportType_CheckSize_Ignore_3_0_10 = 2 -}; -static PyTypeObject *__Pyx_ImportType_3_0_10(PyObject* module, const char *module_name, const char *class_name, size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_3_0_10 check_size); -#endif - -/* FetchSharedCythonModule.proto */ -static PyObject *__Pyx_FetchSharedCythonABIModule(void); - -/* FetchCommonType.proto */ -#if !CYTHON_USE_TYPE_SPECS -static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); -#else -static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases); -#endif - -/* PyMethodNew.proto */ -#if CYTHON_COMPILING_IN_LIMITED_API -static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { - PyObject *typesModule=NULL, *methodType=NULL, *result=NULL; - CYTHON_UNUSED_VAR(typ); - if (!self) - return __Pyx_NewRef(func); - typesModule = PyImport_ImportModule("types"); - if (!typesModule) return NULL; - methodType = PyObject_GetAttrString(typesModule, "MethodType"); - Py_DECREF(typesModule); - if (!methodType) return NULL; - result = PyObject_CallFunctionObjArgs(methodType, func, self, NULL); - Py_DECREF(methodType); - return result; -} -#elif PY_MAJOR_VERSION >= 3 -static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { - CYTHON_UNUSED_VAR(typ); - if (!self) - return __Pyx_NewRef(func); - return PyMethod_New(func, self); -} -#else - #define __Pyx_PyMethod_New PyMethod_New -#endif - -/* PyVectorcallFastCallDict.proto */ -#if CYTHON_METH_FASTCALL -static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); -#endif - -/* CythonFunctionShared.proto */ -#define __Pyx_CyFunction_USED -#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 -#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 -#define __Pyx_CYFUNCTION_CCLASS 0x04 -#define __Pyx_CYFUNCTION_COROUTINE 0x08 -#define __Pyx_CyFunction_GetClosure(f)\ - (((__pyx_CyFunctionObject *) (f))->func_closure) -#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API - #define __Pyx_CyFunction_GetClassObj(f)\ - (((__pyx_CyFunctionObject *) (f))->func_classobj) -#else - #define __Pyx_CyFunction_GetClassObj(f)\ - ((PyObject*) ((PyCMethodObject *) (f))->mm_class) -#endif -#define __Pyx_CyFunction_SetClassObj(f, classobj)\ - __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) -#define __Pyx_CyFunction_Defaults(type, f)\ - ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) -#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ - ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) -typedef struct { -#if CYTHON_COMPILING_IN_LIMITED_API - PyObject_HEAD - PyObject *func; -#elif PY_VERSION_HEX < 0x030900B1 - PyCFunctionObject func; -#else - PyCMethodObject func; -#endif -#if CYTHON_BACKPORT_VECTORCALL - __pyx_vectorcallfunc func_vectorcall; -#endif -#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API - PyObject *func_weakreflist; -#endif - PyObject *func_dict; - PyObject *func_name; - PyObject *func_qualname; - PyObject *func_doc; - PyObject *func_globals; - PyObject *func_code; - PyObject *func_closure; -#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API - PyObject *func_classobj; -#endif - void *defaults; - int defaults_pyobjects; - size_t defaults_size; - int flags; - PyObject *defaults_tuple; - PyObject *defaults_kwdict; - PyObject *(*defaults_getter)(PyObject *); - PyObject *func_annotations; - PyObject *func_is_coroutine; -} __pyx_CyFunctionObject; -#undef __Pyx_CyOrPyCFunction_Check -#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_CyFunctionType) -#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_CyFunctionType, &PyCFunction_Type) -#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CyFunctionType) -static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc); -#undef __Pyx_IsSameCFunction -#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) -static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, - int flags, PyObject* qualname, - PyObject *closure, - PyObject *module, PyObject *globals, - PyObject* code); -static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); -static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, - size_t size, - int pyobjects); -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, - PyObject *tuple); -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, - PyObject *dict); -static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, - PyObject *dict); -static int __pyx_CyFunction_init(PyObject *module); -#if CYTHON_METH_FASTCALL -static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); -static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); -static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); -static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); -#if CYTHON_BACKPORT_VECTORCALL -#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) -#else -#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) -#endif -#endif - -/* CythonFunction.proto */ -static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, - int flags, PyObject* qualname, - PyObject *closure, - PyObject *module, PyObject *globals, - PyObject* code); - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -#if !CYTHON_COMPILING_IN_LIMITED_API -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); -#endif - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -#if PY_MAJOR_VERSION < 3 - static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); - static void __Pyx_ReleaseBuffer(Py_buffer *view); -#else - #define __Pyx_GetBuffer PyObject_GetBuffer - #define __Pyx_ReleaseBuffer PyBuffer_Release -#endif - - -/* BufferStructDeclare.proto */ -typedef struct { - Py_ssize_t shape, strides, suboffsets; -} __Pyx_Buf_DimInfo; -typedef struct { - size_t refcount; - Py_buffer pybuffer; -} __Pyx_Buffer; -typedef struct { - __Pyx_Buffer *rcbuffer; - char *data; - __Pyx_Buf_DimInfo diminfo[8]; -} __Pyx_LocalBuf_ND; - -/* MemviewSliceIsContig.proto */ -static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice mvs, char order, int ndim); - -/* OverlappingSlices.proto */ -static int __pyx_slices_overlap(__Pyx_memviewslice *slice1, - __Pyx_memviewslice *slice2, - int ndim, size_t itemsize); - -/* TypeInfoCompare.proto */ -static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b); - -/* MemviewSliceValidateAndInit.proto */ -static int __Pyx_ValidateAndInit_memviewslice( - int *axes_specs, - int c_or_f_flag, - int buf_flags, - int ndim, - __Pyx_TypeInfo *dtype, - __Pyx_BufFmt_StackElem stack[], - __Pyx_memviewslice *memviewslice, - PyObject *original_obj); - -/* ObjectToMemviewSlice.proto */ -static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_double(PyObject *, int writable_flag); - -/* ObjectToMemviewSlice.proto */ -static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int64_t(PyObject *, int writable_flag); - -/* RealImag.proto */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - #define __Pyx_CREAL(z) ((z).real()) - #define __Pyx_CIMAG(z) ((z).imag()) - #else - #define __Pyx_CREAL(z) (__real__(z)) - #define __Pyx_CIMAG(z) (__imag__(z)) - #endif -#else - #define __Pyx_CREAL(z) ((z).real) - #define __Pyx_CIMAG(z) ((z).imag) -#endif -#if defined(__cplusplus) && CYTHON_CCOMPLEX\ - && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) - #define __Pyx_SET_CREAL(z,x) ((z).real(x)) - #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) -#else - #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) - #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) -#endif - -/* Arithmetic.proto */ -#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) - #define __Pyx_c_eq_float(a, b) ((a)==(b)) - #define __Pyx_c_sum_float(a, b) ((a)+(b)) - #define __Pyx_c_diff_float(a, b) ((a)-(b)) - #define __Pyx_c_prod_float(a, b) ((a)*(b)) - #define __Pyx_c_quot_float(a, b) ((a)/(b)) - #define __Pyx_c_neg_float(a) (-(a)) - #ifdef __cplusplus - #define __Pyx_c_is_zero_float(z) ((z)==(float)0) - #define __Pyx_c_conj_float(z) (::std::conj(z)) - #if 1 - #define __Pyx_c_abs_float(z) (::std::abs(z)) - #define __Pyx_c_pow_float(a, b) (::std::pow(a, b)) - #endif - #else - #define __Pyx_c_is_zero_float(z) ((z)==0) - #define __Pyx_c_conj_float(z) (conjf(z)) - #if 1 - #define __Pyx_c_abs_float(z) (cabsf(z)) - #define __Pyx_c_pow_float(a, b) (cpowf(a, b)) - #endif - #endif -#else - static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex); - static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex); - #if 1 - static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex, __pyx_t_float_complex); - #endif -#endif - -/* Arithmetic.proto */ -#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) - #define __Pyx_c_eq_double(a, b) ((a)==(b)) - #define __Pyx_c_sum_double(a, b) ((a)+(b)) - #define __Pyx_c_diff_double(a, b) ((a)-(b)) - #define __Pyx_c_prod_double(a, b) ((a)*(b)) - #define __Pyx_c_quot_double(a, b) ((a)/(b)) - #define __Pyx_c_neg_double(a) (-(a)) - #ifdef __cplusplus - #define __Pyx_c_is_zero_double(z) ((z)==(double)0) - #define __Pyx_c_conj_double(z) (::std::conj(z)) - #if 1 - #define __Pyx_c_abs_double(z) (::std::abs(z)) - #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) - #endif - #else - #define __Pyx_c_is_zero_double(z) ((z)==0) - #define __Pyx_c_conj_double(z) (conj(z)) - #if 1 - #define __Pyx_c_abs_double(z) (cabs(z)) - #define __Pyx_c_pow_double(a, b) (cpow(a, b)) - #endif - #endif -#else - static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); - static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); - #if 1 - static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); - #endif -#endif - -/* Arithmetic.proto */ -#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) - #define __Pyx_c_eq_long__double(a, b) ((a)==(b)) - #define __Pyx_c_sum_long__double(a, b) ((a)+(b)) - #define __Pyx_c_diff_long__double(a, b) ((a)-(b)) - #define __Pyx_c_prod_long__double(a, b) ((a)*(b)) - #define __Pyx_c_quot_long__double(a, b) ((a)/(b)) - #define __Pyx_c_neg_long__double(a) (-(a)) - #ifdef __cplusplus - #define __Pyx_c_is_zero_long__double(z) ((z)==(long double)0) - #define __Pyx_c_conj_long__double(z) (::std::conj(z)) - #if 1 - #define __Pyx_c_abs_long__double(z) (::std::abs(z)) - #define __Pyx_c_pow_long__double(a, b) (::std::pow(a, b)) - #endif - #else - #define __Pyx_c_is_zero_long__double(z) ((z)==0) - #define __Pyx_c_conj_long__double(z) (conjl(z)) - #if 1 - #define __Pyx_c_abs_long__double(z) (cabsl(z)) - #define __Pyx_c_pow_long__double(a, b) (cpowl(a, b)) - #endif - #endif -#else - static CYTHON_INLINE int __Pyx_c_eq_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_sum_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_diff_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_prod_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_quot_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_neg_long__double(__pyx_t_long_double_complex); - static CYTHON_INLINE int __Pyx_c_is_zero_long__double(__pyx_t_long_double_complex); - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_conj_long__double(__pyx_t_long_double_complex); - #if 1 - static CYTHON_INLINE long double __Pyx_c_abs_long__double(__pyx_t_long_double_complex); - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_pow_long__double(__pyx_t_long_double_complex, __pyx_t_long_double_complex); - #endif -#endif - -/* MemviewSliceCopyTemplate.proto */ -static __Pyx_memviewslice -__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, - const char *mode, int ndim, - size_t sizeof_dtype, int contig_flag, - int dtype_is_object); - -/* MemviewSliceInit.proto */ -#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d -#define __Pyx_MEMVIEW_DIRECT 1 -#define __Pyx_MEMVIEW_PTR 2 -#define __Pyx_MEMVIEW_FULL 4 -#define __Pyx_MEMVIEW_CONTIG 8 -#define __Pyx_MEMVIEW_STRIDED 16 -#define __Pyx_MEMVIEW_FOLLOW 32 -#define __Pyx_IS_C_CONTIG 1 -#define __Pyx_IS_F_CONTIG 2 -static int __Pyx_init_memviewslice( - struct __pyx_memoryview_obj *memview, - int ndim, - __Pyx_memviewslice *memviewslice, - int memview_is_new_reference); -static CYTHON_INLINE int __pyx_add_acquisition_count_locked( - __pyx_atomic_int_type *acquisition_count, PyThread_type_lock lock); -static CYTHON_INLINE int __pyx_sub_acquisition_count_locked( - __pyx_atomic_int_type *acquisition_count, PyThread_type_lock lock); -#define __pyx_get_slice_count_pointer(memview) (&memview->acquisition_count) -#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__) -#define __PYX_XCLEAR_MEMVIEW(slice, have_gil) __Pyx_XCLEAR_MEMVIEW(slice, have_gil, __LINE__) -static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int); -static CYTHON_INLINE void __Pyx_XCLEAR_MEMVIEW(__Pyx_memviewslice *, int, int); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_npy_int64(npy_int64 value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE npy_int64 __Pyx_PyInt_As_npy_int64(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *); - -/* FormatTypeName.proto */ -#if CYTHON_COMPILING_IN_LIMITED_API -typedef PyObject *__Pyx_TypeName; -#define __Pyx_FMT_TYPENAME "%U" -static __Pyx_TypeName __Pyx_PyType_GetName(PyTypeObject* tp); -#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) -#else -typedef const char *__Pyx_TypeName; -#define __Pyx_FMT_TYPENAME "%.200s" -#define __Pyx_PyType_GetName(tp) ((tp)->tp_name) -#define __Pyx_DECREF_TypeName(obj) -#endif - -/* CheckBinaryVersion.proto */ -static unsigned long __Pyx_get_runtime_version(void); -static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); - -/* FunctionImport.proto */ -static int __Pyx_ImportFunction_3_0_10(PyObject *module, const char *funcname, void (**f)(void), const char *sig); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - -/* #### Code section: module_declarations ### */ -static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *__pyx_v_self); /* proto*/ -static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/ -static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/ -static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/ -static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/ -static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/ -static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/ -static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/ -static PyObject *__pyx_memoryview__get_base(struct __pyx_memoryview_obj *__pyx_v_self); /* proto*/ -static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/ -static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/ -static PyObject *__pyx_memoryviewslice__get_base(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto*/ -static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_8itemsize_itemsize(PyArray_Descr *__pyx_v_self); /* proto*/ -static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_9alignment_alignment(PyArray_Descr *__pyx_v_self); /* proto*/ -static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_6fields_fields(PyArray_Descr *__pyx_v_self); /* proto*/ -static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_5names_names(PyArray_Descr *__pyx_v_self); /* proto*/ -static CYTHON_INLINE PyArray_ArrayDescr *__pyx_f_5numpy_5dtype_8subarray_subarray(PyArray_Descr *__pyx_v_self); /* proto*/ -static CYTHON_INLINE npy_uint64 __pyx_f_5numpy_5dtype_5flags_flags(PyArray_Descr *__pyx_v_self); /* proto*/ -static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_7numiter_numiter(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_4size_size(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_5index_index(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_2nd_nd(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE npy_intp *__pyx_f_5numpy_9broadcast_10dimensions_dimensions(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE void **__pyx_f_5numpy_9broadcast_5iters_iters(PyArrayMultiIterObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArrayObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject *__pyx_v_self); /* proto*/ -static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__pyx_v_self); /* proto*/ - -/* Module declarations from "libc.string" */ - -/* Module declarations from "libc.stdio" */ - -/* Module declarations from "__builtin__" */ - -/* Module declarations from "cpython.type" */ - -/* Module declarations from "cpython" */ - -/* Module declarations from "cpython.object" */ - -/* Module declarations from "cpython.ref" */ - -/* Module declarations from "numpy" */ - -/* Module declarations from "numpy" */ - -/* Module declarations from "scipy.special.cython_special" */ -static double (*__pyx_f_5scipy_7special_14cython_special_pdtr)(double, double, int __pyx_skip_dispatch); /*proto*/ - -/* Module declarations from "libc.math" */ - -/* Module declarations from "cython.view" */ - -/* Module declarations from "cython.dataclasses" */ - -/* Module declarations from "cython" */ - -/* Module declarations from "pygom.model._tau_leap" */ -static PyObject *__pyx_collections_abc_Sequence = 0; -static PyObject *generic = 0; -static PyObject *strided = 0; -static PyObject *indirect = 0; -static PyObject *contiguous = 0; -static PyObject *indirect_contiguous = 0; -static int __pyx_memoryview_thread_locks_used; -static PyThread_type_lock __pyx_memoryview_thread_locks[8]; -static int __pyx_array_allocate_buffer(struct __pyx_array_obj *); /*proto*/ -static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/ -static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/ -static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/ -static PyObject *_unellipsify(PyObject *, int); /*proto*/ -static int assert_direct_dimensions(Py_ssize_t *, int); /*proto*/ -static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/ -static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/ -static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/ -static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/ -static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/ -static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/ -static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/ -static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/ -static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/ -static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/ -static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/ -static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/ -static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/ -static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/ -static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/ -static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/ -static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/ -static int __pyx_memoryview_err_dim(PyObject *, PyObject *, int); /*proto*/ -static int __pyx_memoryview_err(PyObject *, PyObject *); /*proto*/ -static int __pyx_memoryview_err_no_memory(void); /*proto*/ -static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/ -static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/ -static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/ -static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/ -static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/ -static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/ -static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/ -static PyObject *__pyx_unpickle_Enum__set_state(struct __pyx_MemviewEnum_obj *, PyObject *); /*proto*/ -/* #### Code section: typeinfo ### */ -static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t = { "float64_t", NULL, sizeof(__pyx_t_5numpy_float64_t), { 0 }, 0, 'R', 0, 0 }; -static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t = { "int64_t", NULL, sizeof(__pyx_t_5numpy_int64_t), { 0 }, 0, __PYX_IS_UNSIGNED(__pyx_t_5numpy_int64_t) ? 'U' : 'I', __PYX_IS_UNSIGNED(__pyx_t_5numpy_int64_t), 0 }; -static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 }; -/* #### Code section: before_global_var ### */ -#define __Pyx_MODULE_NAME "pygom.model._tau_leap" -extern int __pyx_module_is_main_pygom__model___tau_leap; -int __pyx_module_is_main_pygom__model___tau_leap = 0; - -/* Implementation of "pygom.model._tau_leap" */ -/* #### Code section: global_var ### */ -static PyObject *__pyx_builtin_range; -static PyObject *__pyx_builtin_print; -static PyObject *__pyx_builtin___import__; -static PyObject *__pyx_builtin_ValueError; -static PyObject *__pyx_builtin_MemoryError; -static PyObject *__pyx_builtin_enumerate; -static PyObject *__pyx_builtin_TypeError; -static PyObject *__pyx_builtin_AssertionError; -static PyObject *__pyx_builtin_Ellipsis; -static PyObject *__pyx_builtin_id; -static PyObject *__pyx_builtin_IndexError; -static PyObject *__pyx_builtin_ImportError; -/* #### Code section: string_decls ### */ -static const char __pyx_k_[] = ": "; -static const char __pyx_k_O[] = "O"; -static const char __pyx_k_c[] = "c"; -static const char __pyx_k_i[] = "i"; -static const char __pyx_k_j[] = "j"; -static const char __pyx_k_x[] = "x"; -static const char __pyx_k__2[] = "."; -static const char __pyx_k__3[] = "*"; -static const char __pyx_k__6[] = "'"; -static const char __pyx_k__7[] = ")"; -static const char __pyx_k_gc[] = "gc"; -static const char __pyx_k_id[] = "id"; -static const char __pyx_k_mu[] = "mu"; -static const char __pyx_k_np[] = "np"; -static const char __pyx_k__25[] = "?"; -static const char __pyx_k_abc[] = "abc"; -static const char __pyx_k_and[] = " and "; -static const char __pyx_k_got[] = " (got "; -static const char __pyx_k_new[] = "__new__"; -static const char __pyx_k_obj[] = "obj"; -static const char __pyx_k_sum[] = "sum"; -static const char __pyx_k_sys[] = "sys"; -static const char __pyx_k_base[] = "base"; -static const char __pyx_k_dict[] = "__dict__"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_mode[] = "mode"; -static const char __pyx_k_name[] = "name"; -static const char __pyx_k_ndim[] = "ndim"; -static const char __pyx_k_pack[] = "pack"; -static const char __pyx_k_safe[] = "safe"; -static const char __pyx_k_size[] = "size"; -static const char __pyx_k_spec[] = "__spec__"; -static const char __pyx_k_step[] = "step"; -static const char __pyx_k_stop[] = "stop"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_ASCII[] = "ASCII"; -static const char __pyx_k_class[] = "__class__"; -static const char __pyx_k_count[] = "count"; -static const char __pyx_k_error[] = "error"; -static const char __pyx_k_flags[] = "flags"; -static const char __pyx_k_index[] = "index"; -static const char __pyx_k_numpy[] = "numpy"; -static const char __pyx_k_print[] = "print"; -static const char __pyx_k_range[] = "range"; -static const char __pyx_k_rates[] = "rates"; -static const char __pyx_k_shape[] = "shape"; -static const char __pyx_k_start[] = "start"; -static const char __pyx_k_enable[] = "enable"; -static const char __pyx_k_encode[] = "encode"; -static const char __pyx_k_format[] = "format"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_name_2[] = "__name__"; -static const char __pyx_k_pickle[] = "pickle"; -static const char __pyx_k_reduce[] = "__reduce__"; -static const char __pyx_k_struct[] = "struct"; -static const char __pyx_k_unpack[] = "unpack"; -static const char __pyx_k_update[] = "update"; -static const char __pyx_k_x_view[] = "x_view"; -static const char __pyx_k_cdf_val[] = "cdf_val"; -static const char __pyx_k_disable[] = "disable"; -static const char __pyx_k_epsilon[] = "epsilon"; -static const char __pyx_k_fortran[] = "fortran"; -static const char __pyx_k_max_cdf[] = "max_cdf"; -static const char __pyx_k_memview[] = "memview"; -static const char __pyx_k_n_rates[] = "n_rates"; -static const char __pyx_k_new_cdf[] = "new_cdf"; -static const char __pyx_k_Ellipsis[] = "Ellipsis"; -static const char __pyx_k_Sequence[] = "Sequence"; -static const char __pyx_k_getstate[] = "__getstate__"; -static const char __pyx_k_itemsize[] = "itemsize"; -static const char __pyx_k_pyx_type[] = "__pyx_type"; -static const char __pyx_k_register[] = "register"; -static const char __pyx_k_setstate[] = "__setstate__"; -static const char __pyx_k_TypeError[] = "TypeError"; -static const char __pyx_k_enumerate[] = "enumerate"; -static const char __pyx_k_isenabled[] = "isenabled"; -static const char __pyx_k_pyx_state[] = "__pyx_state"; -static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; -static const char __pyx_k_tau_scale[] = "tau_scale"; -static const char __pyx_k_IndexError[] = "IndexError"; -static const char __pyx_k_ValueError[] = "ValueError"; -static const char __pyx_k_pyx_result[] = "__pyx_result"; -static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; -static const char __pyx_k_rates_view[] = "rates_view"; -static const char __pyx_k_total_rate[] = "total_rate"; -static const char __pyx_k_ImportError[] = "ImportError"; -static const char __pyx_k_MemoryError[] = "MemoryError"; -static const char __pyx_k_PickleError[] = "PickleError"; -static const char __pyx_k_collections[] = "collections"; -static const char __pyx_k_count_error[] = "count error"; -static const char __pyx_k_n_reactants[] = "n_reactants"; -static const char __pyx_k_initializing[] = "_initializing"; -static const char __pyx_k_is_coroutine[] = "_is_coroutine"; -static const char __pyx_k_pyx_checksum[] = "__pyx_checksum"; -static const char __pyx_k_reactant_mat[] = "reactant_mat"; -static const char __pyx_k_stringsource[] = ""; -static const char __pyx_k_version_info[] = "version_info"; -static const char __pyx_k_class_getitem[] = "__class_getitem__"; -static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; -static const char __pyx_k_AssertionError[] = "AssertionError"; -static const char __pyx_k_View_MemoryView[] = "View.MemoryView"; -static const char __pyx_k_allocate_buffer[] = "allocate_buffer"; -static const char __pyx_k_collections_abc[] = "collections.abc"; -static const char __pyx_k_dtype_is_object[] = "dtype_is_object"; -static const char __pyx_k_pyx_PickleError[] = "__pyx_PickleError"; -static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; -static const char __pyx_k_pyx_unpickle_Enum[] = "__pyx_unpickle_Enum"; -static const char __pyx_k_reactant_mat_view[] = "reactant_mat_view"; -static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines"; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_strided_and_direct[] = ""; -static const char __pyx_k_strided_and_indirect[] = ""; -static const char __pyx_k_Invalid_shape_in_axis[] = "Invalid shape in axis "; -static const char __pyx_k_contiguous_and_direct[] = ""; -static const char __pyx_k_pygom_model__tau_leap[] = "pygom.model._tau_leap"; -static const char __pyx_k_Cannot_index_with_type[] = "Cannot index with type '"; -static const char __pyx_k_MemoryView_of_r_object[] = ""; -static const char __pyx_k_MemoryView_of_r_at_0x_x[] = ""; -static const char __pyx_k_contiguous_and_indirect[] = ""; -static const char __pyx_k_cy_test_tau_leap_safety[] = "_cy_test_tau_leap_safety"; -static const char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct"; -static const char __pyx_k_pygom_model__tau_leap_pyx[] = "pygom\\model\\_tau_leap.pyx"; -static const char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)"; -static const char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)"; -static const char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array"; -static const char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data."; -static const char __pyx_k_strided_and_direct_or_indirect[] = ""; -static const char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced"; -static const char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides"; -static const char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory."; -static const char __pyx_k_Cannot_assign_to_read_only_memor[] = "Cannot assign to read-only memoryview"; -static const char __pyx_k_Cannot_create_writable_memory_vi[] = "Cannot create writable memory view from read-only memoryview"; -static const char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions"; -static const char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array"; -static const char __pyx_k_Incompatible_checksums_0x_x_vs_0[] = "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))"; -static const char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported"; -static const char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got "; -static const char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis "; -static const char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object"; -static const char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension "; -static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; -static const char __pyx_k_numpy__core_multiarray_failed_to[] = "numpy._core.multiarray failed to import"; -static const char __pyx_k_numpy__core_umath_failed_to_impo[] = "numpy._core.umath failed to import"; -static const char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides."; -/* #### Code section: decls ### */ -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */ -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ -static void __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */ -static Py_ssize_t __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__len__(struct __pyx_array_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */ -static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_12__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */ -static PyObject *__pyx_pf___pyx_array___reduce_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_array_2__setstate_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static int __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */ -static PyObject *__pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_MemviewEnum___reduce_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_MemviewEnum_2__setstate_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v___pyx_state); /* proto */ -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */ -static void __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */ -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */ -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static Py_ssize_t __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_memoryview___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_memoryview_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static void __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_memoryviewslice___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_memoryviewslice_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView___pyx_unpickle_Enum(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state); /* proto */ -static PyObject *__pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_x, PyArrayObject *__pyx_v_reactant_mat, PyArrayObject *__pyx_v_rates, double __pyx_v_tau_scale, double __pyx_v_epsilon); /* proto */ -static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -/* #### Code section: late_includes ### */ -/* #### Code section: module_state ### */ -typedef struct { - PyObject *__pyx_d; - PyObject *__pyx_b; - PyObject *__pyx_cython_runtime; - PyObject *__pyx_empty_tuple; - PyObject *__pyx_empty_bytes; - PyObject *__pyx_empty_unicode; - #ifdef __Pyx_CyFunction_USED - PyTypeObject *__pyx_CyFunctionType; - #endif - #ifdef __Pyx_FusedFunction_USED - PyTypeObject *__pyx_FusedFunctionType; - #endif - #ifdef __Pyx_Generator_USED - PyTypeObject *__pyx_GeneratorType; - #endif - #ifdef __Pyx_IterableCoroutine_USED - PyTypeObject *__pyx_IterableCoroutineType; - #endif - #ifdef __Pyx_Coroutine_USED - PyTypeObject *__pyx_CoroutineAwaitType; - #endif - #ifdef __Pyx_Coroutine_USED - PyTypeObject *__pyx_CoroutineType; - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - PyTypeObject *__pyx_ptype_7cpython_4type_type; - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - PyTypeObject *__pyx_ptype_5numpy_dtype; - PyTypeObject *__pyx_ptype_5numpy_flatiter; - PyTypeObject *__pyx_ptype_5numpy_broadcast; - PyTypeObject *__pyx_ptype_5numpy_ndarray; - PyTypeObject *__pyx_ptype_5numpy_generic; - PyTypeObject *__pyx_ptype_5numpy_number; - PyTypeObject *__pyx_ptype_5numpy_integer; - PyTypeObject *__pyx_ptype_5numpy_signedinteger; - PyTypeObject *__pyx_ptype_5numpy_unsignedinteger; - PyTypeObject *__pyx_ptype_5numpy_inexact; - PyTypeObject *__pyx_ptype_5numpy_floating; - PyTypeObject *__pyx_ptype_5numpy_complexfloating; - PyTypeObject *__pyx_ptype_5numpy_flexible; - PyTypeObject *__pyx_ptype_5numpy_character; - PyTypeObject *__pyx_ptype_5numpy_ufunc; - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - PyObject *__pyx_type___pyx_array; - PyObject *__pyx_type___pyx_MemviewEnum; - PyObject *__pyx_type___pyx_memoryview; - PyObject *__pyx_type___pyx_memoryviewslice; - #endif - PyTypeObject *__pyx_array_type; - PyTypeObject *__pyx_MemviewEnum_type; - PyTypeObject *__pyx_memoryview_type; - PyTypeObject *__pyx_memoryviewslice_type; - PyObject *__pyx_kp_u_; - PyObject *__pyx_n_s_ASCII; - PyObject *__pyx_kp_s_All_dimensions_preceding_dimensi; - PyObject *__pyx_n_s_AssertionError; - PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri; - PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is; - PyObject *__pyx_kp_s_Cannot_assign_to_read_only_memor; - PyObject *__pyx_kp_s_Cannot_create_writable_memory_vi; - PyObject *__pyx_kp_u_Cannot_index_with_type; - PyObject *__pyx_kp_s_Cannot_transpose_memoryview_with; - PyObject *__pyx_kp_s_Dimension_d_is_not_direct; - PyObject *__pyx_n_s_Ellipsis; - PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr; - PyObject *__pyx_n_s_ImportError; - PyObject *__pyx_kp_s_Incompatible_checksums_0x_x_vs_0; - PyObject *__pyx_n_s_IndexError; - PyObject *__pyx_kp_s_Index_out_of_bounds_axis_d; - PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte; - PyObject *__pyx_kp_u_Invalid_mode_expected_c_or_fortr; - PyObject *__pyx_kp_u_Invalid_shape_in_axis; - PyObject *__pyx_n_s_MemoryError; - PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x; - PyObject *__pyx_kp_s_MemoryView_of_r_object; - PyObject *__pyx_n_b_O; - PyObject *__pyx_kp_u_Out_of_bounds_on_buffer_access_a; - PyObject *__pyx_n_s_PickleError; - PyObject *__pyx_n_s_Sequence; - PyObject *__pyx_kp_s_Step_may_not_be_zero_axis_d; - PyObject *__pyx_n_s_TypeError; - PyObject *__pyx_kp_s_Unable_to_convert_item_to_object; - PyObject *__pyx_n_s_ValueError; - PyObject *__pyx_n_s_View_MemoryView; - PyObject *__pyx_kp_u__2; - PyObject *__pyx_n_s__25; - PyObject *__pyx_n_s__3; - PyObject *__pyx_kp_u__6; - PyObject *__pyx_kp_u__7; - PyObject *__pyx_n_s_abc; - PyObject *__pyx_n_s_allocate_buffer; - PyObject *__pyx_kp_u_and; - PyObject *__pyx_n_s_asyncio_coroutines; - PyObject *__pyx_n_s_base; - PyObject *__pyx_n_s_c; - PyObject *__pyx_n_u_c; - PyObject *__pyx_n_s_cdf_val; - PyObject *__pyx_n_s_class; - PyObject *__pyx_n_s_class_getitem; - PyObject *__pyx_n_s_cline_in_traceback; - PyObject *__pyx_n_s_collections; - PyObject *__pyx_kp_s_collections_abc; - PyObject *__pyx_kp_s_contiguous_and_direct; - PyObject *__pyx_kp_s_contiguous_and_indirect; - PyObject *__pyx_n_s_count; - PyObject *__pyx_kp_s_count_error; - PyObject *__pyx_n_s_cy_test_tau_leap_safety; - PyObject *__pyx_n_s_dict; - PyObject *__pyx_kp_u_disable; - PyObject *__pyx_n_s_dtype_is_object; - PyObject *__pyx_kp_u_enable; - PyObject *__pyx_n_s_encode; - PyObject *__pyx_n_s_enumerate; - PyObject *__pyx_n_s_epsilon; - PyObject *__pyx_n_s_error; - PyObject *__pyx_n_s_flags; - PyObject *__pyx_n_s_format; - PyObject *__pyx_n_s_fortran; - PyObject *__pyx_n_u_fortran; - PyObject *__pyx_kp_u_gc; - PyObject *__pyx_n_s_getstate; - PyObject *__pyx_kp_u_got; - PyObject *__pyx_kp_u_got_differing_extents_in_dimensi; - PyObject *__pyx_n_s_i; - PyObject *__pyx_n_s_id; - PyObject *__pyx_n_s_import; - PyObject *__pyx_n_s_index; - PyObject *__pyx_n_s_initializing; - PyObject *__pyx_n_s_is_coroutine; - PyObject *__pyx_kp_u_isenabled; - PyObject *__pyx_n_s_itemsize; - PyObject *__pyx_kp_s_itemsize_0_for_cython_array; - PyObject *__pyx_n_s_j; - PyObject *__pyx_n_s_main; - PyObject *__pyx_n_s_max_cdf; - PyObject *__pyx_n_s_memview; - PyObject *__pyx_n_s_mode; - PyObject *__pyx_n_s_mu; - PyObject *__pyx_n_s_n_rates; - PyObject *__pyx_n_s_n_reactants; - PyObject *__pyx_n_s_name; - PyObject *__pyx_n_s_name_2; - PyObject *__pyx_n_s_ndim; - PyObject *__pyx_n_s_new; - PyObject *__pyx_n_s_new_cdf; - PyObject *__pyx_kp_s_no_default___reduce___due_to_non; - PyObject *__pyx_n_s_np; - PyObject *__pyx_n_s_numpy; - PyObject *__pyx_kp_s_numpy__core_multiarray_failed_to; - PyObject *__pyx_kp_s_numpy__core_umath_failed_to_impo; - PyObject *__pyx_n_s_obj; - PyObject *__pyx_n_s_pack; - PyObject *__pyx_n_s_pickle; - PyObject *__pyx_n_s_print; - PyObject *__pyx_n_s_pygom_model__tau_leap; - PyObject *__pyx_kp_s_pygom_model__tau_leap_pyx; - PyObject *__pyx_n_s_pyx_PickleError; - PyObject *__pyx_n_s_pyx_checksum; - PyObject *__pyx_n_s_pyx_result; - PyObject *__pyx_n_s_pyx_state; - PyObject *__pyx_n_s_pyx_type; - PyObject *__pyx_n_s_pyx_unpickle_Enum; - PyObject *__pyx_n_s_pyx_vtable; - PyObject *__pyx_n_s_range; - PyObject *__pyx_n_s_rates; - PyObject *__pyx_n_s_rates_view; - PyObject *__pyx_n_s_reactant_mat; - PyObject *__pyx_n_s_reactant_mat_view; - PyObject *__pyx_n_s_reduce; - PyObject *__pyx_n_s_reduce_cython; - PyObject *__pyx_n_s_reduce_ex; - PyObject *__pyx_n_s_register; - PyObject *__pyx_n_s_safe; - PyObject *__pyx_n_s_setstate; - PyObject *__pyx_n_s_setstate_cython; - PyObject *__pyx_n_s_shape; - PyObject *__pyx_n_s_size; - PyObject *__pyx_n_s_spec; - PyObject *__pyx_n_s_start; - PyObject *__pyx_n_s_step; - PyObject *__pyx_n_s_stop; - PyObject *__pyx_kp_s_strided_and_direct; - PyObject *__pyx_kp_s_strided_and_direct_or_indirect; - PyObject *__pyx_kp_s_strided_and_indirect; - PyObject *__pyx_kp_s_stringsource; - PyObject *__pyx_n_s_struct; - PyObject *__pyx_n_s_sum; - PyObject *__pyx_n_s_sys; - PyObject *__pyx_n_s_tau_scale; - PyObject *__pyx_n_s_test; - PyObject *__pyx_n_s_total_rate; - PyObject *__pyx_kp_s_unable_to_allocate_array_data; - PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str; - PyObject *__pyx_n_s_unpack; - PyObject *__pyx_n_s_update; - PyObject *__pyx_n_s_version_info; - PyObject *__pyx_n_s_x; - PyObject *__pyx_n_s_x_view; - PyObject *__pyx_int_0; - PyObject *__pyx_int_1; - PyObject *__pyx_int_3; - PyObject *__pyx_int_112105877; - PyObject *__pyx_int_136983863; - PyObject *__pyx_int_184977713; - PyObject *__pyx_int_neg_1; - PyObject *__pyx_slice__5; - PyObject *__pyx_tuple__4; - PyObject *__pyx_tuple__8; - PyObject *__pyx_tuple__9; - PyObject *__pyx_tuple__10; - PyObject *__pyx_tuple__11; - PyObject *__pyx_tuple__12; - PyObject *__pyx_tuple__13; - PyObject *__pyx_tuple__14; - PyObject *__pyx_tuple__15; - PyObject *__pyx_tuple__16; - PyObject *__pyx_tuple__17; - PyObject *__pyx_tuple__18; - PyObject *__pyx_tuple__19; - PyObject *__pyx_tuple__20; - PyObject *__pyx_tuple__21; - PyObject *__pyx_tuple__23; - PyObject *__pyx_codeobj__22; - PyObject *__pyx_codeobj__24; -} __pyx_mstate; - -#if CYTHON_USE_MODULE_STATE -#ifdef __cplusplus -namespace { - extern struct PyModuleDef __pyx_moduledef; -} /* anonymous namespace */ -#else -static struct PyModuleDef __pyx_moduledef; -#endif - -#define __pyx_mstate(o) ((__pyx_mstate *)__Pyx_PyModule_GetState(o)) - -#define __pyx_mstate_global (__pyx_mstate(PyState_FindModule(&__pyx_moduledef))) - -#define __pyx_m (PyState_FindModule(&__pyx_moduledef)) -#else -static __pyx_mstate __pyx_mstate_global_static = -#ifdef __cplusplus - {}; -#else - {0}; -#endif -static __pyx_mstate *__pyx_mstate_global = &__pyx_mstate_global_static; -#endif -/* #### Code section: module_state_clear ### */ -#if CYTHON_USE_MODULE_STATE -static int __pyx_m_clear(PyObject *m) { - __pyx_mstate *clear_module_state = __pyx_mstate(m); - if (!clear_module_state) return 0; - Py_CLEAR(clear_module_state->__pyx_d); - Py_CLEAR(clear_module_state->__pyx_b); - Py_CLEAR(clear_module_state->__pyx_cython_runtime); - Py_CLEAR(clear_module_state->__pyx_empty_tuple); - Py_CLEAR(clear_module_state->__pyx_empty_bytes); - Py_CLEAR(clear_module_state->__pyx_empty_unicode); - #ifdef __Pyx_CyFunction_USED - Py_CLEAR(clear_module_state->__pyx_CyFunctionType); - #endif - #ifdef __Pyx_FusedFunction_USED - Py_CLEAR(clear_module_state->__pyx_FusedFunctionType); - #endif - Py_CLEAR(clear_module_state->__pyx_ptype_7cpython_4type_type); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_dtype); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_flatiter); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_broadcast); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_ndarray); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_generic); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_number); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_integer); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_signedinteger); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_unsignedinteger); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_inexact); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_floating); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_complexfloating); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_flexible); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_character); - Py_CLEAR(clear_module_state->__pyx_ptype_5numpy_ufunc); - Py_CLEAR(clear_module_state->__pyx_array_type); - Py_CLEAR(clear_module_state->__pyx_type___pyx_array); - Py_CLEAR(clear_module_state->__pyx_MemviewEnum_type); - Py_CLEAR(clear_module_state->__pyx_type___pyx_MemviewEnum); - Py_CLEAR(clear_module_state->__pyx_memoryview_type); - Py_CLEAR(clear_module_state->__pyx_type___pyx_memoryview); - Py_CLEAR(clear_module_state->__pyx_memoryviewslice_type); - Py_CLEAR(clear_module_state->__pyx_type___pyx_memoryviewslice); - Py_CLEAR(clear_module_state->__pyx_kp_u_); - Py_CLEAR(clear_module_state->__pyx_n_s_ASCII); - Py_CLEAR(clear_module_state->__pyx_kp_s_All_dimensions_preceding_dimensi); - Py_CLEAR(clear_module_state->__pyx_n_s_AssertionError); - Py_CLEAR(clear_module_state->__pyx_kp_s_Buffer_view_does_not_expose_stri); - Py_CLEAR(clear_module_state->__pyx_kp_s_Can_only_create_a_buffer_that_is); - Py_CLEAR(clear_module_state->__pyx_kp_s_Cannot_assign_to_read_only_memor); - Py_CLEAR(clear_module_state->__pyx_kp_s_Cannot_create_writable_memory_vi); - Py_CLEAR(clear_module_state->__pyx_kp_u_Cannot_index_with_type); - Py_CLEAR(clear_module_state->__pyx_kp_s_Cannot_transpose_memoryview_with); - Py_CLEAR(clear_module_state->__pyx_kp_s_Dimension_d_is_not_direct); - Py_CLEAR(clear_module_state->__pyx_n_s_Ellipsis); - Py_CLEAR(clear_module_state->__pyx_kp_s_Empty_shape_tuple_for_cython_arr); - Py_CLEAR(clear_module_state->__pyx_n_s_ImportError); - Py_CLEAR(clear_module_state->__pyx_kp_s_Incompatible_checksums_0x_x_vs_0); - Py_CLEAR(clear_module_state->__pyx_n_s_IndexError); - Py_CLEAR(clear_module_state->__pyx_kp_s_Index_out_of_bounds_axis_d); - Py_CLEAR(clear_module_state->__pyx_kp_s_Indirect_dimensions_not_supporte); - Py_CLEAR(clear_module_state->__pyx_kp_u_Invalid_mode_expected_c_or_fortr); - Py_CLEAR(clear_module_state->__pyx_kp_u_Invalid_shape_in_axis); - Py_CLEAR(clear_module_state->__pyx_n_s_MemoryError); - Py_CLEAR(clear_module_state->__pyx_kp_s_MemoryView_of_r_at_0x_x); - Py_CLEAR(clear_module_state->__pyx_kp_s_MemoryView_of_r_object); - Py_CLEAR(clear_module_state->__pyx_n_b_O); - Py_CLEAR(clear_module_state->__pyx_kp_u_Out_of_bounds_on_buffer_access_a); - Py_CLEAR(clear_module_state->__pyx_n_s_PickleError); - Py_CLEAR(clear_module_state->__pyx_n_s_Sequence); - Py_CLEAR(clear_module_state->__pyx_kp_s_Step_may_not_be_zero_axis_d); - Py_CLEAR(clear_module_state->__pyx_n_s_TypeError); - Py_CLEAR(clear_module_state->__pyx_kp_s_Unable_to_convert_item_to_object); - Py_CLEAR(clear_module_state->__pyx_n_s_ValueError); - Py_CLEAR(clear_module_state->__pyx_n_s_View_MemoryView); - Py_CLEAR(clear_module_state->__pyx_kp_u__2); - Py_CLEAR(clear_module_state->__pyx_n_s__25); - Py_CLEAR(clear_module_state->__pyx_n_s__3); - Py_CLEAR(clear_module_state->__pyx_kp_u__6); - Py_CLEAR(clear_module_state->__pyx_kp_u__7); - Py_CLEAR(clear_module_state->__pyx_n_s_abc); - Py_CLEAR(clear_module_state->__pyx_n_s_allocate_buffer); - Py_CLEAR(clear_module_state->__pyx_kp_u_and); - Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines); - Py_CLEAR(clear_module_state->__pyx_n_s_base); - Py_CLEAR(clear_module_state->__pyx_n_s_c); - Py_CLEAR(clear_module_state->__pyx_n_u_c); - Py_CLEAR(clear_module_state->__pyx_n_s_cdf_val); - Py_CLEAR(clear_module_state->__pyx_n_s_class); - Py_CLEAR(clear_module_state->__pyx_n_s_class_getitem); - Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback); - Py_CLEAR(clear_module_state->__pyx_n_s_collections); - Py_CLEAR(clear_module_state->__pyx_kp_s_collections_abc); - Py_CLEAR(clear_module_state->__pyx_kp_s_contiguous_and_direct); - Py_CLEAR(clear_module_state->__pyx_kp_s_contiguous_and_indirect); - Py_CLEAR(clear_module_state->__pyx_n_s_count); - Py_CLEAR(clear_module_state->__pyx_kp_s_count_error); - Py_CLEAR(clear_module_state->__pyx_n_s_cy_test_tau_leap_safety); - Py_CLEAR(clear_module_state->__pyx_n_s_dict); - Py_CLEAR(clear_module_state->__pyx_kp_u_disable); - Py_CLEAR(clear_module_state->__pyx_n_s_dtype_is_object); - Py_CLEAR(clear_module_state->__pyx_kp_u_enable); - Py_CLEAR(clear_module_state->__pyx_n_s_encode); - Py_CLEAR(clear_module_state->__pyx_n_s_enumerate); - Py_CLEAR(clear_module_state->__pyx_n_s_epsilon); - Py_CLEAR(clear_module_state->__pyx_n_s_error); - Py_CLEAR(clear_module_state->__pyx_n_s_flags); - Py_CLEAR(clear_module_state->__pyx_n_s_format); - Py_CLEAR(clear_module_state->__pyx_n_s_fortran); - Py_CLEAR(clear_module_state->__pyx_n_u_fortran); - Py_CLEAR(clear_module_state->__pyx_kp_u_gc); - Py_CLEAR(clear_module_state->__pyx_n_s_getstate); - Py_CLEAR(clear_module_state->__pyx_kp_u_got); - Py_CLEAR(clear_module_state->__pyx_kp_u_got_differing_extents_in_dimensi); - Py_CLEAR(clear_module_state->__pyx_n_s_i); - Py_CLEAR(clear_module_state->__pyx_n_s_id); - Py_CLEAR(clear_module_state->__pyx_n_s_import); - Py_CLEAR(clear_module_state->__pyx_n_s_index); - Py_CLEAR(clear_module_state->__pyx_n_s_initializing); - Py_CLEAR(clear_module_state->__pyx_n_s_is_coroutine); - Py_CLEAR(clear_module_state->__pyx_kp_u_isenabled); - Py_CLEAR(clear_module_state->__pyx_n_s_itemsize); - Py_CLEAR(clear_module_state->__pyx_kp_s_itemsize_0_for_cython_array); - Py_CLEAR(clear_module_state->__pyx_n_s_j); - Py_CLEAR(clear_module_state->__pyx_n_s_main); - Py_CLEAR(clear_module_state->__pyx_n_s_max_cdf); - Py_CLEAR(clear_module_state->__pyx_n_s_memview); - Py_CLEAR(clear_module_state->__pyx_n_s_mode); - Py_CLEAR(clear_module_state->__pyx_n_s_mu); - Py_CLEAR(clear_module_state->__pyx_n_s_n_rates); - Py_CLEAR(clear_module_state->__pyx_n_s_n_reactants); - Py_CLEAR(clear_module_state->__pyx_n_s_name); - Py_CLEAR(clear_module_state->__pyx_n_s_name_2); - Py_CLEAR(clear_module_state->__pyx_n_s_ndim); - Py_CLEAR(clear_module_state->__pyx_n_s_new); - Py_CLEAR(clear_module_state->__pyx_n_s_new_cdf); - Py_CLEAR(clear_module_state->__pyx_kp_s_no_default___reduce___due_to_non); - Py_CLEAR(clear_module_state->__pyx_n_s_np); - Py_CLEAR(clear_module_state->__pyx_n_s_numpy); - Py_CLEAR(clear_module_state->__pyx_kp_s_numpy__core_multiarray_failed_to); - Py_CLEAR(clear_module_state->__pyx_kp_s_numpy__core_umath_failed_to_impo); - Py_CLEAR(clear_module_state->__pyx_n_s_obj); - Py_CLEAR(clear_module_state->__pyx_n_s_pack); - Py_CLEAR(clear_module_state->__pyx_n_s_pickle); - Py_CLEAR(clear_module_state->__pyx_n_s_print); - Py_CLEAR(clear_module_state->__pyx_n_s_pygom_model__tau_leap); - Py_CLEAR(clear_module_state->__pyx_kp_s_pygom_model__tau_leap_pyx); - Py_CLEAR(clear_module_state->__pyx_n_s_pyx_PickleError); - Py_CLEAR(clear_module_state->__pyx_n_s_pyx_checksum); - Py_CLEAR(clear_module_state->__pyx_n_s_pyx_result); - Py_CLEAR(clear_module_state->__pyx_n_s_pyx_state); - Py_CLEAR(clear_module_state->__pyx_n_s_pyx_type); - Py_CLEAR(clear_module_state->__pyx_n_s_pyx_unpickle_Enum); - Py_CLEAR(clear_module_state->__pyx_n_s_pyx_vtable); - Py_CLEAR(clear_module_state->__pyx_n_s_range); - Py_CLEAR(clear_module_state->__pyx_n_s_rates); - Py_CLEAR(clear_module_state->__pyx_n_s_rates_view); - Py_CLEAR(clear_module_state->__pyx_n_s_reactant_mat); - Py_CLEAR(clear_module_state->__pyx_n_s_reactant_mat_view); - Py_CLEAR(clear_module_state->__pyx_n_s_reduce); - Py_CLEAR(clear_module_state->__pyx_n_s_reduce_cython); - Py_CLEAR(clear_module_state->__pyx_n_s_reduce_ex); - Py_CLEAR(clear_module_state->__pyx_n_s_register); - Py_CLEAR(clear_module_state->__pyx_n_s_safe); - Py_CLEAR(clear_module_state->__pyx_n_s_setstate); - Py_CLEAR(clear_module_state->__pyx_n_s_setstate_cython); - Py_CLEAR(clear_module_state->__pyx_n_s_shape); - Py_CLEAR(clear_module_state->__pyx_n_s_size); - Py_CLEAR(clear_module_state->__pyx_n_s_spec); - Py_CLEAR(clear_module_state->__pyx_n_s_start); - Py_CLEAR(clear_module_state->__pyx_n_s_step); - Py_CLEAR(clear_module_state->__pyx_n_s_stop); - Py_CLEAR(clear_module_state->__pyx_kp_s_strided_and_direct); - Py_CLEAR(clear_module_state->__pyx_kp_s_strided_and_direct_or_indirect); - Py_CLEAR(clear_module_state->__pyx_kp_s_strided_and_indirect); - Py_CLEAR(clear_module_state->__pyx_kp_s_stringsource); - Py_CLEAR(clear_module_state->__pyx_n_s_struct); - Py_CLEAR(clear_module_state->__pyx_n_s_sum); - Py_CLEAR(clear_module_state->__pyx_n_s_sys); - Py_CLEAR(clear_module_state->__pyx_n_s_tau_scale); - Py_CLEAR(clear_module_state->__pyx_n_s_test); - Py_CLEAR(clear_module_state->__pyx_n_s_total_rate); - Py_CLEAR(clear_module_state->__pyx_kp_s_unable_to_allocate_array_data); - Py_CLEAR(clear_module_state->__pyx_kp_s_unable_to_allocate_shape_and_str); - Py_CLEAR(clear_module_state->__pyx_n_s_unpack); - Py_CLEAR(clear_module_state->__pyx_n_s_update); - Py_CLEAR(clear_module_state->__pyx_n_s_version_info); - Py_CLEAR(clear_module_state->__pyx_n_s_x); - Py_CLEAR(clear_module_state->__pyx_n_s_x_view); - Py_CLEAR(clear_module_state->__pyx_int_0); - Py_CLEAR(clear_module_state->__pyx_int_1); - Py_CLEAR(clear_module_state->__pyx_int_3); - Py_CLEAR(clear_module_state->__pyx_int_112105877); - Py_CLEAR(clear_module_state->__pyx_int_136983863); - Py_CLEAR(clear_module_state->__pyx_int_184977713); - Py_CLEAR(clear_module_state->__pyx_int_neg_1); - Py_CLEAR(clear_module_state->__pyx_slice__5); - Py_CLEAR(clear_module_state->__pyx_tuple__4); - Py_CLEAR(clear_module_state->__pyx_tuple__8); - Py_CLEAR(clear_module_state->__pyx_tuple__9); - Py_CLEAR(clear_module_state->__pyx_tuple__10); - Py_CLEAR(clear_module_state->__pyx_tuple__11); - Py_CLEAR(clear_module_state->__pyx_tuple__12); - Py_CLEAR(clear_module_state->__pyx_tuple__13); - Py_CLEAR(clear_module_state->__pyx_tuple__14); - Py_CLEAR(clear_module_state->__pyx_tuple__15); - Py_CLEAR(clear_module_state->__pyx_tuple__16); - Py_CLEAR(clear_module_state->__pyx_tuple__17); - Py_CLEAR(clear_module_state->__pyx_tuple__18); - Py_CLEAR(clear_module_state->__pyx_tuple__19); - Py_CLEAR(clear_module_state->__pyx_tuple__20); - Py_CLEAR(clear_module_state->__pyx_tuple__21); - Py_CLEAR(clear_module_state->__pyx_tuple__23); - Py_CLEAR(clear_module_state->__pyx_codeobj__22); - Py_CLEAR(clear_module_state->__pyx_codeobj__24); - return 0; -} -#endif -/* #### Code section: module_state_traverse ### */ -#if CYTHON_USE_MODULE_STATE -static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { - __pyx_mstate *traverse_module_state = __pyx_mstate(m); - if (!traverse_module_state) return 0; - Py_VISIT(traverse_module_state->__pyx_d); - Py_VISIT(traverse_module_state->__pyx_b); - Py_VISIT(traverse_module_state->__pyx_cython_runtime); - Py_VISIT(traverse_module_state->__pyx_empty_tuple); - Py_VISIT(traverse_module_state->__pyx_empty_bytes); - Py_VISIT(traverse_module_state->__pyx_empty_unicode); - #ifdef __Pyx_CyFunction_USED - Py_VISIT(traverse_module_state->__pyx_CyFunctionType); - #endif - #ifdef __Pyx_FusedFunction_USED - Py_VISIT(traverse_module_state->__pyx_FusedFunctionType); - #endif - Py_VISIT(traverse_module_state->__pyx_ptype_7cpython_4type_type); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_dtype); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_flatiter); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_broadcast); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_ndarray); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_generic); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_number); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_integer); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_signedinteger); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_unsignedinteger); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_inexact); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_floating); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_complexfloating); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_flexible); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_character); - Py_VISIT(traverse_module_state->__pyx_ptype_5numpy_ufunc); - Py_VISIT(traverse_module_state->__pyx_array_type); - Py_VISIT(traverse_module_state->__pyx_type___pyx_array); - Py_VISIT(traverse_module_state->__pyx_MemviewEnum_type); - Py_VISIT(traverse_module_state->__pyx_type___pyx_MemviewEnum); - Py_VISIT(traverse_module_state->__pyx_memoryview_type); - Py_VISIT(traverse_module_state->__pyx_type___pyx_memoryview); - Py_VISIT(traverse_module_state->__pyx_memoryviewslice_type); - Py_VISIT(traverse_module_state->__pyx_type___pyx_memoryviewslice); - Py_VISIT(traverse_module_state->__pyx_kp_u_); - Py_VISIT(traverse_module_state->__pyx_n_s_ASCII); - Py_VISIT(traverse_module_state->__pyx_kp_s_All_dimensions_preceding_dimensi); - Py_VISIT(traverse_module_state->__pyx_n_s_AssertionError); - Py_VISIT(traverse_module_state->__pyx_kp_s_Buffer_view_does_not_expose_stri); - Py_VISIT(traverse_module_state->__pyx_kp_s_Can_only_create_a_buffer_that_is); - Py_VISIT(traverse_module_state->__pyx_kp_s_Cannot_assign_to_read_only_memor); - Py_VISIT(traverse_module_state->__pyx_kp_s_Cannot_create_writable_memory_vi); - Py_VISIT(traverse_module_state->__pyx_kp_u_Cannot_index_with_type); - Py_VISIT(traverse_module_state->__pyx_kp_s_Cannot_transpose_memoryview_with); - Py_VISIT(traverse_module_state->__pyx_kp_s_Dimension_d_is_not_direct); - Py_VISIT(traverse_module_state->__pyx_n_s_Ellipsis); - Py_VISIT(traverse_module_state->__pyx_kp_s_Empty_shape_tuple_for_cython_arr); - Py_VISIT(traverse_module_state->__pyx_n_s_ImportError); - Py_VISIT(traverse_module_state->__pyx_kp_s_Incompatible_checksums_0x_x_vs_0); - Py_VISIT(traverse_module_state->__pyx_n_s_IndexError); - Py_VISIT(traverse_module_state->__pyx_kp_s_Index_out_of_bounds_axis_d); - Py_VISIT(traverse_module_state->__pyx_kp_s_Indirect_dimensions_not_supporte); - Py_VISIT(traverse_module_state->__pyx_kp_u_Invalid_mode_expected_c_or_fortr); - Py_VISIT(traverse_module_state->__pyx_kp_u_Invalid_shape_in_axis); - Py_VISIT(traverse_module_state->__pyx_n_s_MemoryError); - Py_VISIT(traverse_module_state->__pyx_kp_s_MemoryView_of_r_at_0x_x); - Py_VISIT(traverse_module_state->__pyx_kp_s_MemoryView_of_r_object); - Py_VISIT(traverse_module_state->__pyx_n_b_O); - Py_VISIT(traverse_module_state->__pyx_kp_u_Out_of_bounds_on_buffer_access_a); - Py_VISIT(traverse_module_state->__pyx_n_s_PickleError); - Py_VISIT(traverse_module_state->__pyx_n_s_Sequence); - Py_VISIT(traverse_module_state->__pyx_kp_s_Step_may_not_be_zero_axis_d); - Py_VISIT(traverse_module_state->__pyx_n_s_TypeError); - Py_VISIT(traverse_module_state->__pyx_kp_s_Unable_to_convert_item_to_object); - Py_VISIT(traverse_module_state->__pyx_n_s_ValueError); - Py_VISIT(traverse_module_state->__pyx_n_s_View_MemoryView); - Py_VISIT(traverse_module_state->__pyx_kp_u__2); - Py_VISIT(traverse_module_state->__pyx_n_s__25); - Py_VISIT(traverse_module_state->__pyx_n_s__3); - Py_VISIT(traverse_module_state->__pyx_kp_u__6); - Py_VISIT(traverse_module_state->__pyx_kp_u__7); - Py_VISIT(traverse_module_state->__pyx_n_s_abc); - Py_VISIT(traverse_module_state->__pyx_n_s_allocate_buffer); - Py_VISIT(traverse_module_state->__pyx_kp_u_and); - Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines); - Py_VISIT(traverse_module_state->__pyx_n_s_base); - Py_VISIT(traverse_module_state->__pyx_n_s_c); - Py_VISIT(traverse_module_state->__pyx_n_u_c); - Py_VISIT(traverse_module_state->__pyx_n_s_cdf_val); - Py_VISIT(traverse_module_state->__pyx_n_s_class); - Py_VISIT(traverse_module_state->__pyx_n_s_class_getitem); - Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback); - Py_VISIT(traverse_module_state->__pyx_n_s_collections); - Py_VISIT(traverse_module_state->__pyx_kp_s_collections_abc); - Py_VISIT(traverse_module_state->__pyx_kp_s_contiguous_and_direct); - Py_VISIT(traverse_module_state->__pyx_kp_s_contiguous_and_indirect); - Py_VISIT(traverse_module_state->__pyx_n_s_count); - Py_VISIT(traverse_module_state->__pyx_kp_s_count_error); - Py_VISIT(traverse_module_state->__pyx_n_s_cy_test_tau_leap_safety); - Py_VISIT(traverse_module_state->__pyx_n_s_dict); - Py_VISIT(traverse_module_state->__pyx_kp_u_disable); - Py_VISIT(traverse_module_state->__pyx_n_s_dtype_is_object); - Py_VISIT(traverse_module_state->__pyx_kp_u_enable); - Py_VISIT(traverse_module_state->__pyx_n_s_encode); - Py_VISIT(traverse_module_state->__pyx_n_s_enumerate); - Py_VISIT(traverse_module_state->__pyx_n_s_epsilon); - Py_VISIT(traverse_module_state->__pyx_n_s_error); - Py_VISIT(traverse_module_state->__pyx_n_s_flags); - Py_VISIT(traverse_module_state->__pyx_n_s_format); - Py_VISIT(traverse_module_state->__pyx_n_s_fortran); - Py_VISIT(traverse_module_state->__pyx_n_u_fortran); - Py_VISIT(traverse_module_state->__pyx_kp_u_gc); - Py_VISIT(traverse_module_state->__pyx_n_s_getstate); - Py_VISIT(traverse_module_state->__pyx_kp_u_got); - Py_VISIT(traverse_module_state->__pyx_kp_u_got_differing_extents_in_dimensi); - Py_VISIT(traverse_module_state->__pyx_n_s_i); - Py_VISIT(traverse_module_state->__pyx_n_s_id); - Py_VISIT(traverse_module_state->__pyx_n_s_import); - Py_VISIT(traverse_module_state->__pyx_n_s_index); - Py_VISIT(traverse_module_state->__pyx_n_s_initializing); - Py_VISIT(traverse_module_state->__pyx_n_s_is_coroutine); - Py_VISIT(traverse_module_state->__pyx_kp_u_isenabled); - Py_VISIT(traverse_module_state->__pyx_n_s_itemsize); - Py_VISIT(traverse_module_state->__pyx_kp_s_itemsize_0_for_cython_array); - Py_VISIT(traverse_module_state->__pyx_n_s_j); - Py_VISIT(traverse_module_state->__pyx_n_s_main); - Py_VISIT(traverse_module_state->__pyx_n_s_max_cdf); - Py_VISIT(traverse_module_state->__pyx_n_s_memview); - Py_VISIT(traverse_module_state->__pyx_n_s_mode); - Py_VISIT(traverse_module_state->__pyx_n_s_mu); - Py_VISIT(traverse_module_state->__pyx_n_s_n_rates); - Py_VISIT(traverse_module_state->__pyx_n_s_n_reactants); - Py_VISIT(traverse_module_state->__pyx_n_s_name); - Py_VISIT(traverse_module_state->__pyx_n_s_name_2); - Py_VISIT(traverse_module_state->__pyx_n_s_ndim); - Py_VISIT(traverse_module_state->__pyx_n_s_new); - Py_VISIT(traverse_module_state->__pyx_n_s_new_cdf); - Py_VISIT(traverse_module_state->__pyx_kp_s_no_default___reduce___due_to_non); - Py_VISIT(traverse_module_state->__pyx_n_s_np); - Py_VISIT(traverse_module_state->__pyx_n_s_numpy); - Py_VISIT(traverse_module_state->__pyx_kp_s_numpy__core_multiarray_failed_to); - Py_VISIT(traverse_module_state->__pyx_kp_s_numpy__core_umath_failed_to_impo); - Py_VISIT(traverse_module_state->__pyx_n_s_obj); - Py_VISIT(traverse_module_state->__pyx_n_s_pack); - Py_VISIT(traverse_module_state->__pyx_n_s_pickle); - Py_VISIT(traverse_module_state->__pyx_n_s_print); - Py_VISIT(traverse_module_state->__pyx_n_s_pygom_model__tau_leap); - Py_VISIT(traverse_module_state->__pyx_kp_s_pygom_model__tau_leap_pyx); - Py_VISIT(traverse_module_state->__pyx_n_s_pyx_PickleError); - Py_VISIT(traverse_module_state->__pyx_n_s_pyx_checksum); - Py_VISIT(traverse_module_state->__pyx_n_s_pyx_result); - Py_VISIT(traverse_module_state->__pyx_n_s_pyx_state); - Py_VISIT(traverse_module_state->__pyx_n_s_pyx_type); - Py_VISIT(traverse_module_state->__pyx_n_s_pyx_unpickle_Enum); - Py_VISIT(traverse_module_state->__pyx_n_s_pyx_vtable); - Py_VISIT(traverse_module_state->__pyx_n_s_range); - Py_VISIT(traverse_module_state->__pyx_n_s_rates); - Py_VISIT(traverse_module_state->__pyx_n_s_rates_view); - Py_VISIT(traverse_module_state->__pyx_n_s_reactant_mat); - Py_VISIT(traverse_module_state->__pyx_n_s_reactant_mat_view); - Py_VISIT(traverse_module_state->__pyx_n_s_reduce); - Py_VISIT(traverse_module_state->__pyx_n_s_reduce_cython); - Py_VISIT(traverse_module_state->__pyx_n_s_reduce_ex); - Py_VISIT(traverse_module_state->__pyx_n_s_register); - Py_VISIT(traverse_module_state->__pyx_n_s_safe); - Py_VISIT(traverse_module_state->__pyx_n_s_setstate); - Py_VISIT(traverse_module_state->__pyx_n_s_setstate_cython); - Py_VISIT(traverse_module_state->__pyx_n_s_shape); - Py_VISIT(traverse_module_state->__pyx_n_s_size); - Py_VISIT(traverse_module_state->__pyx_n_s_spec); - Py_VISIT(traverse_module_state->__pyx_n_s_start); - Py_VISIT(traverse_module_state->__pyx_n_s_step); - Py_VISIT(traverse_module_state->__pyx_n_s_stop); - Py_VISIT(traverse_module_state->__pyx_kp_s_strided_and_direct); - Py_VISIT(traverse_module_state->__pyx_kp_s_strided_and_direct_or_indirect); - Py_VISIT(traverse_module_state->__pyx_kp_s_strided_and_indirect); - Py_VISIT(traverse_module_state->__pyx_kp_s_stringsource); - Py_VISIT(traverse_module_state->__pyx_n_s_struct); - Py_VISIT(traverse_module_state->__pyx_n_s_sum); - Py_VISIT(traverse_module_state->__pyx_n_s_sys); - Py_VISIT(traverse_module_state->__pyx_n_s_tau_scale); - Py_VISIT(traverse_module_state->__pyx_n_s_test); - Py_VISIT(traverse_module_state->__pyx_n_s_total_rate); - Py_VISIT(traverse_module_state->__pyx_kp_s_unable_to_allocate_array_data); - Py_VISIT(traverse_module_state->__pyx_kp_s_unable_to_allocate_shape_and_str); - Py_VISIT(traverse_module_state->__pyx_n_s_unpack); - Py_VISIT(traverse_module_state->__pyx_n_s_update); - Py_VISIT(traverse_module_state->__pyx_n_s_version_info); - Py_VISIT(traverse_module_state->__pyx_n_s_x); - Py_VISIT(traverse_module_state->__pyx_n_s_x_view); - Py_VISIT(traverse_module_state->__pyx_int_0); - Py_VISIT(traverse_module_state->__pyx_int_1); - Py_VISIT(traverse_module_state->__pyx_int_3); - Py_VISIT(traverse_module_state->__pyx_int_112105877); - Py_VISIT(traverse_module_state->__pyx_int_136983863); - Py_VISIT(traverse_module_state->__pyx_int_184977713); - Py_VISIT(traverse_module_state->__pyx_int_neg_1); - Py_VISIT(traverse_module_state->__pyx_slice__5); - Py_VISIT(traverse_module_state->__pyx_tuple__4); - Py_VISIT(traverse_module_state->__pyx_tuple__8); - Py_VISIT(traverse_module_state->__pyx_tuple__9); - Py_VISIT(traverse_module_state->__pyx_tuple__10); - Py_VISIT(traverse_module_state->__pyx_tuple__11); - Py_VISIT(traverse_module_state->__pyx_tuple__12); - Py_VISIT(traverse_module_state->__pyx_tuple__13); - Py_VISIT(traverse_module_state->__pyx_tuple__14); - Py_VISIT(traverse_module_state->__pyx_tuple__15); - Py_VISIT(traverse_module_state->__pyx_tuple__16); - Py_VISIT(traverse_module_state->__pyx_tuple__17); - Py_VISIT(traverse_module_state->__pyx_tuple__18); - Py_VISIT(traverse_module_state->__pyx_tuple__19); - Py_VISIT(traverse_module_state->__pyx_tuple__20); - Py_VISIT(traverse_module_state->__pyx_tuple__21); - Py_VISIT(traverse_module_state->__pyx_tuple__23); - Py_VISIT(traverse_module_state->__pyx_codeobj__22); - Py_VISIT(traverse_module_state->__pyx_codeobj__24); - return 0; -} -#endif -/* #### Code section: module_state_defines ### */ -#define __pyx_d __pyx_mstate_global->__pyx_d -#define __pyx_b __pyx_mstate_global->__pyx_b -#define __pyx_cython_runtime __pyx_mstate_global->__pyx_cython_runtime -#define __pyx_empty_tuple __pyx_mstate_global->__pyx_empty_tuple -#define __pyx_empty_bytes __pyx_mstate_global->__pyx_empty_bytes -#define __pyx_empty_unicode __pyx_mstate_global->__pyx_empty_unicode -#ifdef __Pyx_CyFunction_USED -#define __pyx_CyFunctionType __pyx_mstate_global->__pyx_CyFunctionType -#endif -#ifdef __Pyx_FusedFunction_USED -#define __pyx_FusedFunctionType __pyx_mstate_global->__pyx_FusedFunctionType -#endif -#ifdef __Pyx_Generator_USED -#define __pyx_GeneratorType __pyx_mstate_global->__pyx_GeneratorType -#endif -#ifdef __Pyx_IterableCoroutine_USED -#define __pyx_IterableCoroutineType __pyx_mstate_global->__pyx_IterableCoroutineType -#endif -#ifdef __Pyx_Coroutine_USED -#define __pyx_CoroutineAwaitType __pyx_mstate_global->__pyx_CoroutineAwaitType -#endif -#ifdef __Pyx_Coroutine_USED -#define __pyx_CoroutineType __pyx_mstate_global->__pyx_CoroutineType -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#define __pyx_ptype_7cpython_4type_type __pyx_mstate_global->__pyx_ptype_7cpython_4type_type -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#define __pyx_ptype_5numpy_dtype __pyx_mstate_global->__pyx_ptype_5numpy_dtype -#define __pyx_ptype_5numpy_flatiter __pyx_mstate_global->__pyx_ptype_5numpy_flatiter -#define __pyx_ptype_5numpy_broadcast __pyx_mstate_global->__pyx_ptype_5numpy_broadcast -#define __pyx_ptype_5numpy_ndarray __pyx_mstate_global->__pyx_ptype_5numpy_ndarray -#define __pyx_ptype_5numpy_generic __pyx_mstate_global->__pyx_ptype_5numpy_generic -#define __pyx_ptype_5numpy_number __pyx_mstate_global->__pyx_ptype_5numpy_number -#define __pyx_ptype_5numpy_integer __pyx_mstate_global->__pyx_ptype_5numpy_integer -#define __pyx_ptype_5numpy_signedinteger __pyx_mstate_global->__pyx_ptype_5numpy_signedinteger -#define __pyx_ptype_5numpy_unsignedinteger __pyx_mstate_global->__pyx_ptype_5numpy_unsignedinteger -#define __pyx_ptype_5numpy_inexact __pyx_mstate_global->__pyx_ptype_5numpy_inexact -#define __pyx_ptype_5numpy_floating __pyx_mstate_global->__pyx_ptype_5numpy_floating -#define __pyx_ptype_5numpy_complexfloating __pyx_mstate_global->__pyx_ptype_5numpy_complexfloating -#define __pyx_ptype_5numpy_flexible __pyx_mstate_global->__pyx_ptype_5numpy_flexible -#define __pyx_ptype_5numpy_character __pyx_mstate_global->__pyx_ptype_5numpy_character -#define __pyx_ptype_5numpy_ufunc __pyx_mstate_global->__pyx_ptype_5numpy_ufunc -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#define __pyx_type___pyx_array __pyx_mstate_global->__pyx_type___pyx_array -#define __pyx_type___pyx_MemviewEnum __pyx_mstate_global->__pyx_type___pyx_MemviewEnum -#define __pyx_type___pyx_memoryview __pyx_mstate_global->__pyx_type___pyx_memoryview -#define __pyx_type___pyx_memoryviewslice __pyx_mstate_global->__pyx_type___pyx_memoryviewslice -#endif -#define __pyx_array_type __pyx_mstate_global->__pyx_array_type -#define __pyx_MemviewEnum_type __pyx_mstate_global->__pyx_MemviewEnum_type -#define __pyx_memoryview_type __pyx_mstate_global->__pyx_memoryview_type -#define __pyx_memoryviewslice_type __pyx_mstate_global->__pyx_memoryviewslice_type -#define __pyx_kp_u_ __pyx_mstate_global->__pyx_kp_u_ -#define __pyx_n_s_ASCII __pyx_mstate_global->__pyx_n_s_ASCII -#define __pyx_kp_s_All_dimensions_preceding_dimensi __pyx_mstate_global->__pyx_kp_s_All_dimensions_preceding_dimensi -#define __pyx_n_s_AssertionError __pyx_mstate_global->__pyx_n_s_AssertionError -#define __pyx_kp_s_Buffer_view_does_not_expose_stri __pyx_mstate_global->__pyx_kp_s_Buffer_view_does_not_expose_stri -#define __pyx_kp_s_Can_only_create_a_buffer_that_is __pyx_mstate_global->__pyx_kp_s_Can_only_create_a_buffer_that_is -#define __pyx_kp_s_Cannot_assign_to_read_only_memor __pyx_mstate_global->__pyx_kp_s_Cannot_assign_to_read_only_memor -#define __pyx_kp_s_Cannot_create_writable_memory_vi __pyx_mstate_global->__pyx_kp_s_Cannot_create_writable_memory_vi -#define __pyx_kp_u_Cannot_index_with_type __pyx_mstate_global->__pyx_kp_u_Cannot_index_with_type -#define __pyx_kp_s_Cannot_transpose_memoryview_with __pyx_mstate_global->__pyx_kp_s_Cannot_transpose_memoryview_with -#define __pyx_kp_s_Dimension_d_is_not_direct __pyx_mstate_global->__pyx_kp_s_Dimension_d_is_not_direct -#define __pyx_n_s_Ellipsis __pyx_mstate_global->__pyx_n_s_Ellipsis -#define __pyx_kp_s_Empty_shape_tuple_for_cython_arr __pyx_mstate_global->__pyx_kp_s_Empty_shape_tuple_for_cython_arr -#define __pyx_n_s_ImportError __pyx_mstate_global->__pyx_n_s_ImportError -#define __pyx_kp_s_Incompatible_checksums_0x_x_vs_0 __pyx_mstate_global->__pyx_kp_s_Incompatible_checksums_0x_x_vs_0 -#define __pyx_n_s_IndexError __pyx_mstate_global->__pyx_n_s_IndexError -#define __pyx_kp_s_Index_out_of_bounds_axis_d __pyx_mstate_global->__pyx_kp_s_Index_out_of_bounds_axis_d -#define __pyx_kp_s_Indirect_dimensions_not_supporte __pyx_mstate_global->__pyx_kp_s_Indirect_dimensions_not_supporte -#define __pyx_kp_u_Invalid_mode_expected_c_or_fortr __pyx_mstate_global->__pyx_kp_u_Invalid_mode_expected_c_or_fortr -#define __pyx_kp_u_Invalid_shape_in_axis __pyx_mstate_global->__pyx_kp_u_Invalid_shape_in_axis -#define __pyx_n_s_MemoryError __pyx_mstate_global->__pyx_n_s_MemoryError -#define __pyx_kp_s_MemoryView_of_r_at_0x_x __pyx_mstate_global->__pyx_kp_s_MemoryView_of_r_at_0x_x -#define __pyx_kp_s_MemoryView_of_r_object __pyx_mstate_global->__pyx_kp_s_MemoryView_of_r_object -#define __pyx_n_b_O __pyx_mstate_global->__pyx_n_b_O -#define __pyx_kp_u_Out_of_bounds_on_buffer_access_a __pyx_mstate_global->__pyx_kp_u_Out_of_bounds_on_buffer_access_a -#define __pyx_n_s_PickleError __pyx_mstate_global->__pyx_n_s_PickleError -#define __pyx_n_s_Sequence __pyx_mstate_global->__pyx_n_s_Sequence -#define __pyx_kp_s_Step_may_not_be_zero_axis_d __pyx_mstate_global->__pyx_kp_s_Step_may_not_be_zero_axis_d -#define __pyx_n_s_TypeError __pyx_mstate_global->__pyx_n_s_TypeError -#define __pyx_kp_s_Unable_to_convert_item_to_object __pyx_mstate_global->__pyx_kp_s_Unable_to_convert_item_to_object -#define __pyx_n_s_ValueError __pyx_mstate_global->__pyx_n_s_ValueError -#define __pyx_n_s_View_MemoryView __pyx_mstate_global->__pyx_n_s_View_MemoryView -#define __pyx_kp_u__2 __pyx_mstate_global->__pyx_kp_u__2 -#define __pyx_n_s__25 __pyx_mstate_global->__pyx_n_s__25 -#define __pyx_n_s__3 __pyx_mstate_global->__pyx_n_s__3 -#define __pyx_kp_u__6 __pyx_mstate_global->__pyx_kp_u__6 -#define __pyx_kp_u__7 __pyx_mstate_global->__pyx_kp_u__7 -#define __pyx_n_s_abc __pyx_mstate_global->__pyx_n_s_abc -#define __pyx_n_s_allocate_buffer __pyx_mstate_global->__pyx_n_s_allocate_buffer -#define __pyx_kp_u_and __pyx_mstate_global->__pyx_kp_u_and -#define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines -#define __pyx_n_s_base __pyx_mstate_global->__pyx_n_s_base -#define __pyx_n_s_c __pyx_mstate_global->__pyx_n_s_c -#define __pyx_n_u_c __pyx_mstate_global->__pyx_n_u_c -#define __pyx_n_s_cdf_val __pyx_mstate_global->__pyx_n_s_cdf_val -#define __pyx_n_s_class __pyx_mstate_global->__pyx_n_s_class -#define __pyx_n_s_class_getitem __pyx_mstate_global->__pyx_n_s_class_getitem -#define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback -#define __pyx_n_s_collections __pyx_mstate_global->__pyx_n_s_collections -#define __pyx_kp_s_collections_abc __pyx_mstate_global->__pyx_kp_s_collections_abc -#define __pyx_kp_s_contiguous_and_direct __pyx_mstate_global->__pyx_kp_s_contiguous_and_direct -#define __pyx_kp_s_contiguous_and_indirect __pyx_mstate_global->__pyx_kp_s_contiguous_and_indirect -#define __pyx_n_s_count __pyx_mstate_global->__pyx_n_s_count -#define __pyx_kp_s_count_error __pyx_mstate_global->__pyx_kp_s_count_error -#define __pyx_n_s_cy_test_tau_leap_safety __pyx_mstate_global->__pyx_n_s_cy_test_tau_leap_safety -#define __pyx_n_s_dict __pyx_mstate_global->__pyx_n_s_dict -#define __pyx_kp_u_disable __pyx_mstate_global->__pyx_kp_u_disable -#define __pyx_n_s_dtype_is_object __pyx_mstate_global->__pyx_n_s_dtype_is_object -#define __pyx_kp_u_enable __pyx_mstate_global->__pyx_kp_u_enable -#define __pyx_n_s_encode __pyx_mstate_global->__pyx_n_s_encode -#define __pyx_n_s_enumerate __pyx_mstate_global->__pyx_n_s_enumerate -#define __pyx_n_s_epsilon __pyx_mstate_global->__pyx_n_s_epsilon -#define __pyx_n_s_error __pyx_mstate_global->__pyx_n_s_error -#define __pyx_n_s_flags __pyx_mstate_global->__pyx_n_s_flags -#define __pyx_n_s_format __pyx_mstate_global->__pyx_n_s_format -#define __pyx_n_s_fortran __pyx_mstate_global->__pyx_n_s_fortran -#define __pyx_n_u_fortran __pyx_mstate_global->__pyx_n_u_fortran -#define __pyx_kp_u_gc __pyx_mstate_global->__pyx_kp_u_gc -#define __pyx_n_s_getstate __pyx_mstate_global->__pyx_n_s_getstate -#define __pyx_kp_u_got __pyx_mstate_global->__pyx_kp_u_got -#define __pyx_kp_u_got_differing_extents_in_dimensi __pyx_mstate_global->__pyx_kp_u_got_differing_extents_in_dimensi -#define __pyx_n_s_i __pyx_mstate_global->__pyx_n_s_i -#define __pyx_n_s_id __pyx_mstate_global->__pyx_n_s_id -#define __pyx_n_s_import __pyx_mstate_global->__pyx_n_s_import -#define __pyx_n_s_index __pyx_mstate_global->__pyx_n_s_index -#define __pyx_n_s_initializing __pyx_mstate_global->__pyx_n_s_initializing -#define __pyx_n_s_is_coroutine __pyx_mstate_global->__pyx_n_s_is_coroutine -#define __pyx_kp_u_isenabled __pyx_mstate_global->__pyx_kp_u_isenabled -#define __pyx_n_s_itemsize __pyx_mstate_global->__pyx_n_s_itemsize -#define __pyx_kp_s_itemsize_0_for_cython_array __pyx_mstate_global->__pyx_kp_s_itemsize_0_for_cython_array -#define __pyx_n_s_j __pyx_mstate_global->__pyx_n_s_j -#define __pyx_n_s_main __pyx_mstate_global->__pyx_n_s_main -#define __pyx_n_s_max_cdf __pyx_mstate_global->__pyx_n_s_max_cdf -#define __pyx_n_s_memview __pyx_mstate_global->__pyx_n_s_memview -#define __pyx_n_s_mode __pyx_mstate_global->__pyx_n_s_mode -#define __pyx_n_s_mu __pyx_mstate_global->__pyx_n_s_mu -#define __pyx_n_s_n_rates __pyx_mstate_global->__pyx_n_s_n_rates -#define __pyx_n_s_n_reactants __pyx_mstate_global->__pyx_n_s_n_reactants -#define __pyx_n_s_name __pyx_mstate_global->__pyx_n_s_name -#define __pyx_n_s_name_2 __pyx_mstate_global->__pyx_n_s_name_2 -#define __pyx_n_s_ndim __pyx_mstate_global->__pyx_n_s_ndim -#define __pyx_n_s_new __pyx_mstate_global->__pyx_n_s_new -#define __pyx_n_s_new_cdf __pyx_mstate_global->__pyx_n_s_new_cdf -#define __pyx_kp_s_no_default___reduce___due_to_non __pyx_mstate_global->__pyx_kp_s_no_default___reduce___due_to_non -#define __pyx_n_s_np __pyx_mstate_global->__pyx_n_s_np -#define __pyx_n_s_numpy __pyx_mstate_global->__pyx_n_s_numpy -#define __pyx_kp_s_numpy__core_multiarray_failed_to __pyx_mstate_global->__pyx_kp_s_numpy__core_multiarray_failed_to -#define __pyx_kp_s_numpy__core_umath_failed_to_impo __pyx_mstate_global->__pyx_kp_s_numpy__core_umath_failed_to_impo -#define __pyx_n_s_obj __pyx_mstate_global->__pyx_n_s_obj -#define __pyx_n_s_pack __pyx_mstate_global->__pyx_n_s_pack -#define __pyx_n_s_pickle __pyx_mstate_global->__pyx_n_s_pickle -#define __pyx_n_s_print __pyx_mstate_global->__pyx_n_s_print -#define __pyx_n_s_pygom_model__tau_leap __pyx_mstate_global->__pyx_n_s_pygom_model__tau_leap -#define __pyx_kp_s_pygom_model__tau_leap_pyx __pyx_mstate_global->__pyx_kp_s_pygom_model__tau_leap_pyx -#define __pyx_n_s_pyx_PickleError __pyx_mstate_global->__pyx_n_s_pyx_PickleError -#define __pyx_n_s_pyx_checksum __pyx_mstate_global->__pyx_n_s_pyx_checksum -#define __pyx_n_s_pyx_result __pyx_mstate_global->__pyx_n_s_pyx_result -#define __pyx_n_s_pyx_state __pyx_mstate_global->__pyx_n_s_pyx_state -#define __pyx_n_s_pyx_type __pyx_mstate_global->__pyx_n_s_pyx_type -#define __pyx_n_s_pyx_unpickle_Enum __pyx_mstate_global->__pyx_n_s_pyx_unpickle_Enum -#define __pyx_n_s_pyx_vtable __pyx_mstate_global->__pyx_n_s_pyx_vtable -#define __pyx_n_s_range __pyx_mstate_global->__pyx_n_s_range -#define __pyx_n_s_rates __pyx_mstate_global->__pyx_n_s_rates -#define __pyx_n_s_rates_view __pyx_mstate_global->__pyx_n_s_rates_view -#define __pyx_n_s_reactant_mat __pyx_mstate_global->__pyx_n_s_reactant_mat -#define __pyx_n_s_reactant_mat_view __pyx_mstate_global->__pyx_n_s_reactant_mat_view -#define __pyx_n_s_reduce __pyx_mstate_global->__pyx_n_s_reduce -#define __pyx_n_s_reduce_cython __pyx_mstate_global->__pyx_n_s_reduce_cython -#define __pyx_n_s_reduce_ex __pyx_mstate_global->__pyx_n_s_reduce_ex -#define __pyx_n_s_register __pyx_mstate_global->__pyx_n_s_register -#define __pyx_n_s_safe __pyx_mstate_global->__pyx_n_s_safe -#define __pyx_n_s_setstate __pyx_mstate_global->__pyx_n_s_setstate -#define __pyx_n_s_setstate_cython __pyx_mstate_global->__pyx_n_s_setstate_cython -#define __pyx_n_s_shape __pyx_mstate_global->__pyx_n_s_shape -#define __pyx_n_s_size __pyx_mstate_global->__pyx_n_s_size -#define __pyx_n_s_spec __pyx_mstate_global->__pyx_n_s_spec -#define __pyx_n_s_start __pyx_mstate_global->__pyx_n_s_start -#define __pyx_n_s_step __pyx_mstate_global->__pyx_n_s_step -#define __pyx_n_s_stop __pyx_mstate_global->__pyx_n_s_stop -#define __pyx_kp_s_strided_and_direct __pyx_mstate_global->__pyx_kp_s_strided_and_direct -#define __pyx_kp_s_strided_and_direct_or_indirect __pyx_mstate_global->__pyx_kp_s_strided_and_direct_or_indirect -#define __pyx_kp_s_strided_and_indirect __pyx_mstate_global->__pyx_kp_s_strided_and_indirect -#define __pyx_kp_s_stringsource __pyx_mstate_global->__pyx_kp_s_stringsource -#define __pyx_n_s_struct __pyx_mstate_global->__pyx_n_s_struct -#define __pyx_n_s_sum __pyx_mstate_global->__pyx_n_s_sum -#define __pyx_n_s_sys __pyx_mstate_global->__pyx_n_s_sys -#define __pyx_n_s_tau_scale __pyx_mstate_global->__pyx_n_s_tau_scale -#define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test -#define __pyx_n_s_total_rate __pyx_mstate_global->__pyx_n_s_total_rate -#define __pyx_kp_s_unable_to_allocate_array_data __pyx_mstate_global->__pyx_kp_s_unable_to_allocate_array_data -#define __pyx_kp_s_unable_to_allocate_shape_and_str __pyx_mstate_global->__pyx_kp_s_unable_to_allocate_shape_and_str -#define __pyx_n_s_unpack __pyx_mstate_global->__pyx_n_s_unpack -#define __pyx_n_s_update __pyx_mstate_global->__pyx_n_s_update -#define __pyx_n_s_version_info __pyx_mstate_global->__pyx_n_s_version_info -#define __pyx_n_s_x __pyx_mstate_global->__pyx_n_s_x -#define __pyx_n_s_x_view __pyx_mstate_global->__pyx_n_s_x_view -#define __pyx_int_0 __pyx_mstate_global->__pyx_int_0 -#define __pyx_int_1 __pyx_mstate_global->__pyx_int_1 -#define __pyx_int_3 __pyx_mstate_global->__pyx_int_3 -#define __pyx_int_112105877 __pyx_mstate_global->__pyx_int_112105877 -#define __pyx_int_136983863 __pyx_mstate_global->__pyx_int_136983863 -#define __pyx_int_184977713 __pyx_mstate_global->__pyx_int_184977713 -#define __pyx_int_neg_1 __pyx_mstate_global->__pyx_int_neg_1 -#define __pyx_slice__5 __pyx_mstate_global->__pyx_slice__5 -#define __pyx_tuple__4 __pyx_mstate_global->__pyx_tuple__4 -#define __pyx_tuple__8 __pyx_mstate_global->__pyx_tuple__8 -#define __pyx_tuple__9 __pyx_mstate_global->__pyx_tuple__9 -#define __pyx_tuple__10 __pyx_mstate_global->__pyx_tuple__10 -#define __pyx_tuple__11 __pyx_mstate_global->__pyx_tuple__11 -#define __pyx_tuple__12 __pyx_mstate_global->__pyx_tuple__12 -#define __pyx_tuple__13 __pyx_mstate_global->__pyx_tuple__13 -#define __pyx_tuple__14 __pyx_mstate_global->__pyx_tuple__14 -#define __pyx_tuple__15 __pyx_mstate_global->__pyx_tuple__15 -#define __pyx_tuple__16 __pyx_mstate_global->__pyx_tuple__16 -#define __pyx_tuple__17 __pyx_mstate_global->__pyx_tuple__17 -#define __pyx_tuple__18 __pyx_mstate_global->__pyx_tuple__18 -#define __pyx_tuple__19 __pyx_mstate_global->__pyx_tuple__19 -#define __pyx_tuple__20 __pyx_mstate_global->__pyx_tuple__20 -#define __pyx_tuple__21 __pyx_mstate_global->__pyx_tuple__21 -#define __pyx_tuple__23 __pyx_mstate_global->__pyx_tuple__23 -#define __pyx_codeobj__22 __pyx_mstate_global->__pyx_codeobj__22 -#define __pyx_codeobj__24 __pyx_mstate_global->__pyx_codeobj__24 -/* #### Code section: module_code ### */ - -/* "View.MemoryView":131 - * cdef bint dtype_is_object - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< - * mode="c", bint allocate_buffer=True): - * - */ - -/* Python wrapper */ -static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_shape = 0; - Py_ssize_t __pyx_v_itemsize; - PyObject *__pyx_v_format = 0; - PyObject *__pyx_v_mode = 0; - int __pyx_v_allocate_buffer; - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[5] = {0,0,0,0,0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (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_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0}; - values[3] = __Pyx_Arg_NewRef_VARARGS(((PyObject *)__pyx_n_s_c)); - 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 (likely((values[0] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_shape)) != 0)) { - (void)__Pyx_Arg_NewRef_VARARGS(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_itemsize)) != 0)) { - (void)__Pyx_Arg_NewRef_VARARGS(values[1]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); __PYX_ERR(1, 131, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_format)) != 0)) { - (void)__Pyx_Arg_NewRef_VARARGS(values[2]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); __PYX_ERR(1, 131, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (kw_args > 0) { - PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_mode); - if (value) { values[3] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 4: - if (kw_args > 0) { - PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_allocate_buffer); - if (value) { values[4] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 131, __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, "__cinit__") < 0)) __PYX_ERR(1, 131, __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); - values[1] = __Pyx_Arg_VARARGS(__pyx_args, 1); - values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_shape = ((PyObject*)values[0]); - __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 131, __pyx_L3_error) - __pyx_v_format = values[2]; - __pyx_v_mode = values[3]; - if (values[4]) { - __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 132, __pyx_L3_error) - } else { - - /* "View.MemoryView":132 - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, - * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<< - * - * cdef int idx - */ - __pyx_v_allocate_buffer = ((int)1); - } - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, __pyx_nargs); __PYX_ERR(1, 131, __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("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) __PYX_ERR(1, 131, __pyx_L1_error) - if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) { - PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); __PYX_ERR(1, 131, __pyx_L1_error) - } - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer); - - /* "View.MemoryView":131 - * cdef bint dtype_is_object - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< - * mode="c", bint allocate_buffer=True): - * - */ - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = -1; - __pyx_L0:; - { - 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_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) { - int __pyx_v_idx; - Py_ssize_t __pyx_v_dim; - char __pyx_v_order; - int __pyx_r; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; - char *__pyx_t_8; - Py_ssize_t __pyx_t_9; - Py_UCS4 __pyx_t_10; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 0); - __Pyx_INCREF(__pyx_v_format); - - /* "View.MemoryView":137 - * cdef Py_ssize_t dim - * - * self.ndim = len(shape) # <<<<<<<<<<<<<< - * self.itemsize = itemsize - * - */ - if (unlikely(__pyx_v_shape == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 137, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(1, 137, __pyx_L1_error) - __pyx_v_self->ndim = ((int)__pyx_t_1); - - /* "View.MemoryView":138 - * - * self.ndim = len(shape) - * self.itemsize = itemsize # <<<<<<<<<<<<<< - * - * if not self.ndim: - */ - __pyx_v_self->itemsize = __pyx_v_itemsize; - - /* "View.MemoryView":140 - * self.itemsize = itemsize - * - * if not self.ndim: # <<<<<<<<<<<<<< - * raise ValueError, "Empty shape tuple for cython.array" - * - */ - __pyx_t_2 = (!(__pyx_v_self->ndim != 0)); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":141 - * - * if not self.ndim: - * raise ValueError, "Empty shape tuple for cython.array" # <<<<<<<<<<<<<< - * - * if itemsize <= 0: - */ - __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Empty_shape_tuple_for_cython_arr, 0, 0); - __PYX_ERR(1, 141, __pyx_L1_error) - - /* "View.MemoryView":140 - * self.itemsize = itemsize - * - * if not self.ndim: # <<<<<<<<<<<<<< - * raise ValueError, "Empty shape tuple for cython.array" - * - */ - } - - /* "View.MemoryView":143 - * raise ValueError, "Empty shape tuple for cython.array" - * - * if itemsize <= 0: # <<<<<<<<<<<<<< - * raise ValueError, "itemsize <= 0 for cython.array" - * - */ - __pyx_t_2 = (__pyx_v_itemsize <= 0); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":144 - * - * if itemsize <= 0: - * raise ValueError, "itemsize <= 0 for cython.array" # <<<<<<<<<<<<<< - * - * if not isinstance(format, bytes): - */ - __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_itemsize_0_for_cython_array, 0, 0); - __PYX_ERR(1, 144, __pyx_L1_error) - - /* "View.MemoryView":143 - * raise ValueError, "Empty shape tuple for cython.array" - * - * if itemsize <= 0: # <<<<<<<<<<<<<< - * raise ValueError, "itemsize <= 0 for cython.array" - * - */ - } - - /* "View.MemoryView":146 - * raise ValueError, "itemsize <= 0 for cython.array" - * - * if not isinstance(format, bytes): # <<<<<<<<<<<<<< - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string - */ - __pyx_t_2 = PyBytes_Check(__pyx_v_format); - __pyx_t_3 = (!__pyx_t_2); - if (__pyx_t_3) { - - /* "View.MemoryView":147 - * - * if not isinstance(format, bytes): - * format = format.encode('ASCII') # <<<<<<<<<<<<<< - * self._format = format # keep a reference to the byte string - * self.format = self._format - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_format, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = NULL; - __pyx_t_7 = 0; - #if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_6)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_6); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - __pyx_t_7 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_n_s_ASCII}; - __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7); - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_4); - __pyx_t_4 = 0; - - /* "View.MemoryView":146 - * raise ValueError, "itemsize <= 0 for cython.array" - * - * if not isinstance(format, bytes): # <<<<<<<<<<<<<< - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string - */ - } - - /* "View.MemoryView":148 - * if not isinstance(format, bytes): - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<< - * self.format = self._format - * - */ - if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None) || __Pyx_RaiseUnexpectedTypeError("bytes", __pyx_v_format))) __PYX_ERR(1, 148, __pyx_L1_error) - __pyx_t_4 = __pyx_v_format; - __Pyx_INCREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_4); - __Pyx_GOTREF(__pyx_v_self->_format); - __Pyx_DECREF(__pyx_v_self->_format); - __pyx_v_self->_format = ((PyObject*)__pyx_t_4); - __pyx_t_4 = 0; - - /* "View.MemoryView":149 - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string - * self.format = self._format # <<<<<<<<<<<<<< - * - * - */ - if (unlikely(__pyx_v_self->_format == Py_None)) { - PyErr_SetString(PyExc_TypeError, "expected bytes, NoneType found"); - __PYX_ERR(1, 149, __pyx_L1_error) - } - __pyx_t_8 = __Pyx_PyBytes_AsWritableString(__pyx_v_self->_format); if (unlikely((!__pyx_t_8) && PyErr_Occurred())) __PYX_ERR(1, 149, __pyx_L1_error) - __pyx_v_self->format = __pyx_t_8; - - /* "View.MemoryView":152 - * - * - * self._shape = PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<< - * self._strides = self._shape + self.ndim - * - */ - __pyx_v_self->_shape = ((Py_ssize_t *)PyObject_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2))); - - /* "View.MemoryView":153 - * - * self._shape = PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2) - * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<< - * - * if not self._shape: - */ - __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim); - - /* "View.MemoryView":155 - * self._strides = self._shape + self.ndim - * - * if not self._shape: # <<<<<<<<<<<<<< - * raise MemoryError, "unable to allocate shape and strides." - * - */ - __pyx_t_3 = (!(__pyx_v_self->_shape != 0)); - if (unlikely(__pyx_t_3)) { - - /* "View.MemoryView":156 - * - * if not self._shape: - * raise MemoryError, "unable to allocate shape and strides." # <<<<<<<<<<<<<< - * - * - */ - __Pyx_Raise(__pyx_builtin_MemoryError, __pyx_kp_s_unable_to_allocate_shape_and_str, 0, 0); - __PYX_ERR(1, 156, __pyx_L1_error) - - /* "View.MemoryView":155 - * self._strides = self._shape + self.ndim - * - * if not self._shape: # <<<<<<<<<<<<<< - * raise MemoryError, "unable to allocate shape and strides." - * - */ - } - - /* "View.MemoryView":159 - * - * - * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<< - * if dim <= 0: - * raise ValueError, f"Invalid shape in axis {idx}: {dim}." - */ - __pyx_t_7 = 0; - __pyx_t_4 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_4); - __pyx_t_1 = 0; - for (;;) { - { - Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_4); - #if !CYTHON_ASSUME_SAFE_MACROS - if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 159, __pyx_L1_error) - #endif - if (__pyx_t_1 >= __pyx_temp) break; - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_1); __Pyx_INCREF(__pyx_t_5); __pyx_t_1++; if (unlikely((0 < 0))) __PYX_ERR(1, 159, __pyx_L1_error) - #else - __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_4, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 159, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_t_5); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 159, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_dim = __pyx_t_9; - __pyx_v_idx = __pyx_t_7; - __pyx_t_7 = (__pyx_t_7 + 1); - - /* "View.MemoryView":160 - * - * for idx, dim in enumerate(shape): - * if dim <= 0: # <<<<<<<<<<<<<< - * raise ValueError, f"Invalid shape in axis {idx}: {dim}." - * self._shape[idx] = dim - */ - __pyx_t_3 = (__pyx_v_dim <= 0); - if (unlikely(__pyx_t_3)) { - - /* "View.MemoryView":161 - * for idx, dim in enumerate(shape): - * if dim <= 0: - * raise ValueError, f"Invalid shape in axis {idx}: {dim}." # <<<<<<<<<<<<<< - * self._shape[idx] = dim - * - */ - __pyx_t_5 = PyTuple_New(5); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 161, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_9 = 0; - __pyx_t_10 = 127; - __Pyx_INCREF(__pyx_kp_u_Invalid_shape_in_axis); - __pyx_t_9 += 22; - __Pyx_GIVEREF(__pyx_kp_u_Invalid_shape_in_axis); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_Invalid_shape_in_axis); - __pyx_t_6 = __Pyx_PyUnicode_From_int(__pyx_v_idx, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 161, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_INCREF(__pyx_kp_u_); - __pyx_t_9 += 2; - __Pyx_GIVEREF(__pyx_kp_u_); - PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u_); - __pyx_t_6 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_dim, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 161, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_INCREF(__pyx_kp_u__2); - __pyx_t_9 += 1; - __Pyx_GIVEREF(__pyx_kp_u__2); - PyTuple_SET_ITEM(__pyx_t_5, 4, __pyx_kp_u__2); - __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_5, 5, __pyx_t_9, __pyx_t_10); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 161, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_Raise(__pyx_builtin_ValueError, __pyx_t_6, 0, 0); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __PYX_ERR(1, 161, __pyx_L1_error) - - /* "View.MemoryView":160 - * - * for idx, dim in enumerate(shape): - * if dim <= 0: # <<<<<<<<<<<<<< - * raise ValueError, f"Invalid shape in axis {idx}: {dim}." - * self._shape[idx] = dim - */ - } - - /* "View.MemoryView":162 - * if dim <= 0: - * raise ValueError, f"Invalid shape in axis {idx}: {dim}." - * self._shape[idx] = dim # <<<<<<<<<<<<<< - * - * cdef char order - */ - (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim; - - /* "View.MemoryView":159 - * - * - * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<< - * if dim <= 0: - * raise ValueError, f"Invalid shape in axis {idx}: {dim}." - */ - } - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "View.MemoryView":165 - * - * cdef char order - * if mode == 'c': # <<<<<<<<<<<<<< - * order = b'C' - * self.mode = u'c' - */ - __pyx_t_3 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(1, 165, __pyx_L1_error) - if (__pyx_t_3) { - - /* "View.MemoryView":166 - * cdef char order - * if mode == 'c': - * order = b'C' # <<<<<<<<<<<<<< - * self.mode = u'c' - * elif mode == 'fortran': - */ - __pyx_v_order = 'C'; - - /* "View.MemoryView":167 - * if mode == 'c': - * order = b'C' - * self.mode = u'c' # <<<<<<<<<<<<<< - * elif mode == 'fortran': - * order = b'F' - */ - __Pyx_INCREF(__pyx_n_u_c); - __Pyx_GIVEREF(__pyx_n_u_c); - __Pyx_GOTREF(__pyx_v_self->mode); - __Pyx_DECREF(__pyx_v_self->mode); - __pyx_v_self->mode = __pyx_n_u_c; - - /* "View.MemoryView":165 - * - * cdef char order - * if mode == 'c': # <<<<<<<<<<<<<< - * order = b'C' - * self.mode = u'c' - */ - goto __pyx_L11; - } - - /* "View.MemoryView":168 - * order = b'C' - * self.mode = u'c' - * elif mode == 'fortran': # <<<<<<<<<<<<<< - * order = b'F' - * self.mode = u'fortran' - */ - __pyx_t_3 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(1, 168, __pyx_L1_error) - if (likely(__pyx_t_3)) { - - /* "View.MemoryView":169 - * self.mode = u'c' - * elif mode == 'fortran': - * order = b'F' # <<<<<<<<<<<<<< - * self.mode = u'fortran' - * else: - */ - __pyx_v_order = 'F'; - - /* "View.MemoryView":170 - * elif mode == 'fortran': - * order = b'F' - * self.mode = u'fortran' # <<<<<<<<<<<<<< - * else: - * raise ValueError, f"Invalid mode, expected 'c' or 'fortran', got {mode}" - */ - __Pyx_INCREF(__pyx_n_u_fortran); - __Pyx_GIVEREF(__pyx_n_u_fortran); - __Pyx_GOTREF(__pyx_v_self->mode); - __Pyx_DECREF(__pyx_v_self->mode); - __pyx_v_self->mode = __pyx_n_u_fortran; - - /* "View.MemoryView":168 - * order = b'C' - * self.mode = u'c' - * elif mode == 'fortran': # <<<<<<<<<<<<<< - * order = b'F' - * self.mode = u'fortran' - */ - goto __pyx_L11; - } - - /* "View.MemoryView":172 - * self.mode = u'fortran' - * else: - * raise ValueError, f"Invalid mode, expected 'c' or 'fortran', got {mode}" # <<<<<<<<<<<<<< - * - * self.len = fill_contig_strides_array(self._shape, self._strides, itemsize, self.ndim, order) - */ - /*else*/ { - __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_v_mode, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 172, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Invalid_mode_expected_c_or_fortr, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 172, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_builtin_ValueError, __pyx_t_6, 0, 0); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __PYX_ERR(1, 172, __pyx_L1_error) - } - __pyx_L11:; - - /* "View.MemoryView":174 - * raise ValueError, f"Invalid mode, expected 'c' or 'fortran', got {mode}" - * - * self.len = fill_contig_strides_array(self._shape, self._strides, itemsize, self.ndim, order) # <<<<<<<<<<<<<< - * - * self.free_data = allocate_buffer - */ - __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order); - - /* "View.MemoryView":176 - * self.len = fill_contig_strides_array(self._shape, self._strides, itemsize, self.ndim, order) - * - * self.free_data = allocate_buffer # <<<<<<<<<<<<<< - * self.dtype_is_object = format == b'O' - * - */ - __pyx_v_self->free_data = __pyx_v_allocate_buffer; - - /* "View.MemoryView":177 - * - * self.free_data = allocate_buffer - * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<< - * - * if allocate_buffer: - */ - __pyx_t_6 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 177, __pyx_L1_error) - __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 177, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_v_self->dtype_is_object = __pyx_t_3; - - /* "View.MemoryView":179 - * self.dtype_is_object = format == b'O' - * - * if allocate_buffer: # <<<<<<<<<<<<<< - * _allocate_buffer(self) - * - */ - if (__pyx_v_allocate_buffer) { - - /* "View.MemoryView":180 - * - * if allocate_buffer: - * _allocate_buffer(self) # <<<<<<<<<<<<<< - * - * @cname('getbuffer') - */ - __pyx_t_7 = __pyx_array_allocate_buffer(__pyx_v_self); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(1, 180, __pyx_L1_error) - - /* "View.MemoryView":179 - * self.dtype_is_object = format == b'O' - * - * if allocate_buffer: # <<<<<<<<<<<<<< - * _allocate_buffer(self) - * - */ - } - - /* "View.MemoryView":131 - * cdef bint dtype_is_object - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< - * mode="c", bint allocate_buffer=True): - * - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_format); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":182 - * _allocate_buffer(self) - * - * @cname('getbuffer') # <<<<<<<<<<<<<< - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 - */ - -/* Python wrapper */ -CYTHON_UNUSED static int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -CYTHON_UNUSED static int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_v_bufmode; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - char *__pyx_t_2; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - Py_ssize_t *__pyx_t_5; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - if (unlikely(__pyx_v_info == NULL)) { - PyErr_SetString(PyExc_BufferError, "PyObject_GetBuffer: view==NULL argument is obsolete"); - return -1; - } - __Pyx_RefNannySetupContext("__getbuffer__", 0); - __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(__pyx_v_info->obj); - - /* "View.MemoryView":184 - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 # <<<<<<<<<<<<<< - * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): - * if self.mode == u"c": - */ - __pyx_v_bufmode = -1; - - /* "View.MemoryView":185 - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 - * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): # <<<<<<<<<<<<<< - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - */ - __pyx_t_1 = ((__pyx_v_flags & ((PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS) | PyBUF_ANY_CONTIGUOUS)) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":186 - * cdef int bufmode = -1 - * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): - * if self.mode == u"c": # <<<<<<<<<<<<<< - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 186, __pyx_L1_error) - if (__pyx_t_1) { - - /* "View.MemoryView":187 - * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<< - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - */ - __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS); - - /* "View.MemoryView":186 - * cdef int bufmode = -1 - * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): - * if self.mode == u"c": # <<<<<<<<<<<<<< - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": - */ - goto __pyx_L4; - } - - /* "View.MemoryView":188 - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": # <<<<<<<<<<<<<< - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 188, __pyx_L1_error) - if (__pyx_t_1) { - - /* "View.MemoryView":189 - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<< - * if not (flags & bufmode): - * raise ValueError, "Can only create a buffer that is contiguous in memory." - */ - __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS); - - /* "View.MemoryView":188 - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": # <<<<<<<<<<<<<< - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - */ - } - __pyx_L4:; - - /* "View.MemoryView":190 - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): # <<<<<<<<<<<<<< - * raise ValueError, "Can only create a buffer that is contiguous in memory." - * info.buf = self.data - */ - __pyx_t_1 = (!((__pyx_v_flags & __pyx_v_bufmode) != 0)); - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":191 - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - * raise ValueError, "Can only create a buffer that is contiguous in memory." # <<<<<<<<<<<<<< - * info.buf = self.data - * info.len = self.len - */ - __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Can_only_create_a_buffer_that_is, 0, 0); - __PYX_ERR(1, 191, __pyx_L1_error) - - /* "View.MemoryView":190 - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): # <<<<<<<<<<<<<< - * raise ValueError, "Can only create a buffer that is contiguous in memory." - * info.buf = self.data - */ - } - - /* "View.MemoryView":185 - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 - * if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS): # <<<<<<<<<<<<<< - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - */ - } - - /* "View.MemoryView":192 - * if not (flags & bufmode): - * raise ValueError, "Can only create a buffer that is contiguous in memory." - * info.buf = self.data # <<<<<<<<<<<<<< - * info.len = self.len - * - */ - __pyx_t_2 = __pyx_v_self->data; - __pyx_v_info->buf = __pyx_t_2; - - /* "View.MemoryView":193 - * raise ValueError, "Can only create a buffer that is contiguous in memory." - * info.buf = self.data - * info.len = self.len # <<<<<<<<<<<<<< - * - * if flags & PyBUF_STRIDES: - */ - __pyx_t_3 = __pyx_v_self->len; - __pyx_v_info->len = __pyx_t_3; - - /* "View.MemoryView":195 - * info.len = self.len - * - * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< - * info.ndim = self.ndim - * info.shape = self._shape - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":196 - * - * if flags & PyBUF_STRIDES: - * info.ndim = self.ndim # <<<<<<<<<<<<<< - * info.shape = self._shape - * info.strides = self._strides - */ - __pyx_t_4 = __pyx_v_self->ndim; - __pyx_v_info->ndim = __pyx_t_4; - - /* "View.MemoryView":197 - * if flags & PyBUF_STRIDES: - * info.ndim = self.ndim - * info.shape = self._shape # <<<<<<<<<<<<<< - * info.strides = self._strides - * else: - */ - __pyx_t_5 = __pyx_v_self->_shape; - __pyx_v_info->shape = __pyx_t_5; - - /* "View.MemoryView":198 - * info.ndim = self.ndim - * info.shape = self._shape - * info.strides = self._strides # <<<<<<<<<<<<<< - * else: - * info.ndim = 1 - */ - __pyx_t_5 = __pyx_v_self->_strides; - __pyx_v_info->strides = __pyx_t_5; - - /* "View.MemoryView":195 - * info.len = self.len - * - * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< - * info.ndim = self.ndim - * info.shape = self._shape - */ - goto __pyx_L6; - } - - /* "View.MemoryView":200 - * info.strides = self._strides - * else: - * info.ndim = 1 # <<<<<<<<<<<<<< - * info.shape = &self.len if flags & PyBUF_ND else NULL - * info.strides = NULL - */ - /*else*/ { - __pyx_v_info->ndim = 1; - - /* "View.MemoryView":201 - * else: - * info.ndim = 1 - * info.shape = &self.len if flags & PyBUF_ND else NULL # <<<<<<<<<<<<<< - * info.strides = NULL - * - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_ND) != 0); - if (__pyx_t_1) { - __pyx_t_5 = (&__pyx_v_self->len); - } else { - __pyx_t_5 = NULL; - } - __pyx_v_info->shape = __pyx_t_5; - - /* "View.MemoryView":202 - * info.ndim = 1 - * info.shape = &self.len if flags & PyBUF_ND else NULL - * info.strides = NULL # <<<<<<<<<<<<<< - * - * info.suboffsets = NULL - */ - __pyx_v_info->strides = NULL; - } - __pyx_L6:; - - /* "View.MemoryView":204 - * info.strides = NULL - * - * info.suboffsets = NULL # <<<<<<<<<<<<<< - * info.itemsize = self.itemsize - * info.readonly = 0 - */ - __pyx_v_info->suboffsets = NULL; - - /* "View.MemoryView":205 - * - * info.suboffsets = NULL - * info.itemsize = self.itemsize # <<<<<<<<<<<<<< - * info.readonly = 0 - * info.format = self.format if flags & PyBUF_FORMAT else NULL - */ - __pyx_t_3 = __pyx_v_self->itemsize; - __pyx_v_info->itemsize = __pyx_t_3; - - /* "View.MemoryView":206 - * info.suboffsets = NULL - * info.itemsize = self.itemsize - * info.readonly = 0 # <<<<<<<<<<<<<< - * info.format = self.format if flags & PyBUF_FORMAT else NULL - * info.obj = self - */ - __pyx_v_info->readonly = 0; - - /* "View.MemoryView":207 - * info.itemsize = self.itemsize - * info.readonly = 0 - * info.format = self.format if flags & PyBUF_FORMAT else NULL # <<<<<<<<<<<<<< - * info.obj = self - * - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); - if (__pyx_t_1) { - __pyx_t_2 = __pyx_v_self->format; - } else { - __pyx_t_2 = NULL; - } - __pyx_v_info->format = __pyx_t_2; - - /* "View.MemoryView":208 - * info.readonly = 0 - * info.format = self.format if flags & PyBUF_FORMAT else NULL - * info.obj = self # <<<<<<<<<<<<<< - * - * def __dealloc__(array self): - */ - __Pyx_INCREF((PyObject *)__pyx_v_self); - __Pyx_GIVEREF((PyObject *)__pyx_v_self); - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); - __pyx_v_info->obj = ((PyObject *)__pyx_v_self); - - /* "View.MemoryView":182 - * _allocate_buffer(self) - * - * @cname('getbuffer') # <<<<<<<<<<<<<< - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - if (__pyx_v_info->obj != NULL) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - goto __pyx_L2; - __pyx_L0:; - if (__pyx_v_info->obj == Py_None) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - __pyx_L2:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":210 - * info.obj = self - * - * def __dealloc__(array self): # <<<<<<<<<<<<<< - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - */ - -/* Python wrapper */ -static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_array___dealloc__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) { - int __pyx_t_1; - int __pyx_t_2; - - /* "View.MemoryView":211 - * - * def __dealloc__(array self): - * if self.callback_free_data != NULL: # <<<<<<<<<<<<<< - * self.callback_free_data(self.data) - * elif self.free_data and self.data is not NULL: - */ - __pyx_t_1 = (__pyx_v_self->callback_free_data != NULL); - if (__pyx_t_1) { - - /* "View.MemoryView":212 - * def __dealloc__(array self): - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) # <<<<<<<<<<<<<< - * elif self.free_data and self.data is not NULL: - * if self.dtype_is_object: - */ - __pyx_v_self->callback_free_data(__pyx_v_self->data); - - /* "View.MemoryView":211 - * - * def __dealloc__(array self): - * if self.callback_free_data != NULL: # <<<<<<<<<<<<<< - * self.callback_free_data(self.data) - * elif self.free_data and self.data is not NULL: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":213 - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - * elif self.free_data and self.data is not NULL: # <<<<<<<<<<<<<< - * if self.dtype_is_object: - * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) - */ - if (__pyx_v_self->free_data) { - } else { - __pyx_t_1 = __pyx_v_self->free_data; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = (__pyx_v_self->data != NULL); - __pyx_t_1 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - if (__pyx_t_1) { - - /* "View.MemoryView":214 - * self.callback_free_data(self.data) - * elif self.free_data and self.data is not NULL: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) - * free(self.data) - */ - if (__pyx_v_self->dtype_is_object) { - - /* "View.MemoryView":215 - * elif self.free_data and self.data is not NULL: - * if self.dtype_is_object: - * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) # <<<<<<<<<<<<<< - * free(self.data) - * PyObject_Free(self._shape) - */ - __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0); - - /* "View.MemoryView":214 - * self.callback_free_data(self.data) - * elif self.free_data and self.data is not NULL: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) - * free(self.data) - */ - } - - /* "View.MemoryView":216 - * if self.dtype_is_object: - * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) - * free(self.data) # <<<<<<<<<<<<<< - * PyObject_Free(self._shape) - * - */ - free(__pyx_v_self->data); - - /* "View.MemoryView":213 - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - * elif self.free_data and self.data is not NULL: # <<<<<<<<<<<<<< - * if self.dtype_is_object: - * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) - */ - } - __pyx_L3:; - - /* "View.MemoryView":217 - * refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False) - * free(self.data) - * PyObject_Free(self._shape) # <<<<<<<<<<<<<< - * - * @property - */ - PyObject_Free(__pyx_v_self->_shape); - - /* "View.MemoryView":210 - * info.obj = self - * - * def __dealloc__(array self): # <<<<<<<<<<<<<< - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - */ - - /* function exit code */ -} - -/* "View.MemoryView":219 - * PyObject_Free(self._shape) - * - * @property # <<<<<<<<<<<<<< - * def memview(self): - * return self.get_memview() - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_pf_15View_dot_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 1); - - /* "View.MemoryView":221 - * @property - * def memview(self): - * return self.get_memview() # <<<<<<<<<<<<<< - * - * @cname('get_memview') - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = ((struct __pyx_vtabstruct_array *)__pyx_v_self->__pyx_vtab)->get_memview(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 221, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":219 - * PyObject_Free(self._shape) - * - * @property # <<<<<<<<<<<<<< - * def memview(self): - * return self.get_memview() - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":224 - * - * @cname('get_memview') - * cdef get_memview(self): # <<<<<<<<<<<<<< - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE - * return memoryview(self, flags, self.dtype_is_object) - */ - -static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *__pyx_v_self) { - int __pyx_v_flags; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_memview", 1); - - /* "View.MemoryView":225 - * @cname('get_memview') - * cdef get_memview(self): - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<< - * return memoryview(self, flags, self.dtype_is_object) - * - */ - __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE); - - /* "View.MemoryView":226 - * cdef get_memview(self): - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE - * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<< - * - * def __len__(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 226, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 226, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 226, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF((PyObject *)__pyx_v_self); - __Pyx_GIVEREF((PyObject *)__pyx_v_self); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self))) __PYX_ERR(1, 226, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_1); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1)) __PYX_ERR(1, 226, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_2); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2)) __PYX_ERR(1, 226, __pyx_L1_error); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 226, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":224 - * - * @cname('get_memview') - * cdef get_memview(self): # <<<<<<<<<<<<<< - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE - * return memoryview(self, flags, self.dtype_is_object) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.array.get_memview", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":228 - * return memoryview(self, flags, self.dtype_is_object) - * - * def __len__(self): # <<<<<<<<<<<<<< - * return self._shape[0] - * - */ - -/* Python wrapper */ -static Py_ssize_t __pyx_array___len__(PyObject *__pyx_v_self); /*proto*/ -static Py_ssize_t __pyx_array___len__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__len__(((struct __pyx_array_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static Py_ssize_t __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__len__(struct __pyx_array_obj *__pyx_v_self) { - Py_ssize_t __pyx_r; - - /* "View.MemoryView":229 - * - * def __len__(self): - * return self._shape[0] # <<<<<<<<<<<<<< - * - * def __getattr__(self, attr): - */ - __pyx_r = (__pyx_v_self->_shape[0]); - goto __pyx_L0; - - /* "View.MemoryView":228 - * return memoryview(self, flags, self.dtype_is_object) - * - * def __len__(self): # <<<<<<<<<<<<<< - * return self._shape[0] - * - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":231 - * return self._shape[0] - * - * def __getattr__(self, attr): # <<<<<<<<<<<<<< - * return getattr(self.memview, attr) - * - */ - -/* Python wrapper */ -static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/ -static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__getattr__", 1); - - /* "View.MemoryView":232 - * - * def __getattr__(self, attr): - * return getattr(self.memview, attr) # <<<<<<<<<<<<<< - * - * def __getitem__(self, item): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 232, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 232, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":231 - * return self._shape[0] - * - * def __getattr__(self, attr): # <<<<<<<<<<<<<< - * return getattr(self.memview, attr) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":234 - * return getattr(self.memview, attr) - * - * def __getitem__(self, item): # <<<<<<<<<<<<<< - * return self.memview[item] - * - */ - -/* Python wrapper */ -static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ -static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__getitem__", 1); - - /* "View.MemoryView":235 - * - * def __getitem__(self, item): - * return self.memview[item] # <<<<<<<<<<<<<< - * - * def __setitem__(self, item, value): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 235, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 235, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":234 - * return getattr(self.memview, attr) - * - * def __getitem__(self, item): # <<<<<<<<<<<<<< - * return self.memview[item] - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":237 - * return self.memview[item] - * - * def __setitem__(self, item, value): # <<<<<<<<<<<<<< - * self.memview[item] = value - * - */ - -/* Python wrapper */ -static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/ -static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_12__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_12__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setitem__", 1); - - /* "View.MemoryView":238 - * - * def __setitem__(self, item, value): - * self.memview[item] = value # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 238, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (unlikely((PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0))) __PYX_ERR(1, 238, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "View.MemoryView":237 - * return self.memview[item] - * - * def __setitem__(self, item, value): # <<<<<<<<<<<<<< - * self.memview[item] = value - * - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_array_1__reduce_cython__(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*/ -static PyObject *__pyx_pw___pyx_array_1__reduce_cython__(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 -) { - #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("__reduce_cython__ (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); - if (unlikely(__pyx_nargs > 0)) { - __Pyx_RaiseArgtupleInvalid("__reduce_cython__", 1, 0, 0, __pyx_nargs); return NULL;} - if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__reduce_cython__", 0))) return NULL; - __pyx_r = __pyx_pf___pyx_array___reduce_cython__(((struct __pyx_array_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_array___reduce_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 1); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); - __PYX_ERR(1, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView.array.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_array_3__setstate_cython__(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*/ -static PyObject *__pyx_pw___pyx_array_3__setstate_cython__(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 -) { - CYTHON_UNUSED PyObject *__pyx_v___pyx_state = 0; - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[1] = {0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (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_pyx_state,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - 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_pyx_state)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 3, __pyx_L3_error) - else goto __pyx_L5_argtuple_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, "__setstate_cython__") < 0)) __PYX_ERR(1, 3, __pyx_L3_error) - } - } else if (unlikely(__pyx_nargs != 1)) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - } - __pyx_v___pyx_state = values[0]; - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__setstate_cython__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 3, __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("View.MemoryView.array.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf___pyx_array_2__setstate_cython__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v___pyx_state); - - /* 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___pyx_array_2__setstate_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 1); - - /* "(tree fragment)":4 - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< - */ - __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); - __PYX_ERR(1, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView.array.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":248 - * - * @cname("__pyx_array_allocate_buffer") - * cdef int _allocate_buffer(array self) except -1: # <<<<<<<<<<<<<< - * - * - */ - -static int __pyx_array_allocate_buffer(struct __pyx_array_obj *__pyx_v_self) { - Py_ssize_t __pyx_v_i; - PyObject **__pyx_v_p; - int __pyx_r; - int __pyx_t_1; - Py_ssize_t __pyx_t_2; - Py_ssize_t __pyx_t_3; - Py_ssize_t __pyx_t_4; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - - /* "View.MemoryView":254 - * cdef PyObject **p - * - * self.free_data = True # <<<<<<<<<<<<<< - * self.data = malloc(self.len) - * if not self.data: - */ - __pyx_v_self->free_data = 1; - - /* "View.MemoryView":255 - * - * self.free_data = True - * self.data = malloc(self.len) # <<<<<<<<<<<<<< - * if not self.data: - * raise MemoryError, "unable to allocate array data." - */ - __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len)); - - /* "View.MemoryView":256 - * self.free_data = True - * self.data = malloc(self.len) - * if not self.data: # <<<<<<<<<<<<<< - * raise MemoryError, "unable to allocate array data." - * - */ - __pyx_t_1 = (!(__pyx_v_self->data != 0)); - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":257 - * self.data = malloc(self.len) - * if not self.data: - * raise MemoryError, "unable to allocate array data." # <<<<<<<<<<<<<< - * - * if self.dtype_is_object: - */ - __Pyx_Raise(__pyx_builtin_MemoryError, __pyx_kp_s_unable_to_allocate_array_data, 0, 0); - __PYX_ERR(1, 257, __pyx_L1_error) - - /* "View.MemoryView":256 - * self.free_data = True - * self.data = malloc(self.len) - * if not self.data: # <<<<<<<<<<<<<< - * raise MemoryError, "unable to allocate array data." - * - */ - } - - /* "View.MemoryView":259 - * raise MemoryError, "unable to allocate array data." - * - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * p = self.data - * for i in range(self.len // self.itemsize): - */ - if (__pyx_v_self->dtype_is_object) { - - /* "View.MemoryView":260 - * - * if self.dtype_is_object: - * p = self.data # <<<<<<<<<<<<<< - * for i in range(self.len // self.itemsize): - * p[i] = Py_None - */ - __pyx_v_p = ((PyObject **)__pyx_v_self->data); - - /* "View.MemoryView":261 - * if self.dtype_is_object: - * p = self.data - * for i in range(self.len // self.itemsize): # <<<<<<<<<<<<<< - * p[i] = Py_None - * Py_INCREF(Py_None) - */ - if (unlikely(__pyx_v_self->itemsize == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); - __PYX_ERR(1, 261, __pyx_L1_error) - } - else if (sizeof(Py_ssize_t) == sizeof(long) && (!(((Py_ssize_t)-1) > 0)) && unlikely(__pyx_v_self->itemsize == (Py_ssize_t)-1) && unlikely(__Pyx_UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) { - PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); - __PYX_ERR(1, 261, __pyx_L1_error) - } - __pyx_t_2 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_self->itemsize); - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; - - /* "View.MemoryView":262 - * p = self.data - * for i in range(self.len // self.itemsize): - * p[i] = Py_None # <<<<<<<<<<<<<< - * Py_INCREF(Py_None) - * return 0 - */ - (__pyx_v_p[__pyx_v_i]) = Py_None; - - /* "View.MemoryView":263 - * for i in range(self.len // self.itemsize): - * p[i] = Py_None - * Py_INCREF(Py_None) # <<<<<<<<<<<<<< - * return 0 - * - */ - Py_INCREF(Py_None); - } - - /* "View.MemoryView":259 - * raise MemoryError, "unable to allocate array data." - * - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * p = self.data - * for i in range(self.len // self.itemsize): - */ - } - - /* "View.MemoryView":264 - * p[i] = Py_None - * Py_INCREF(Py_None) - * return 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":248 - * - * @cname("__pyx_array_allocate_buffer") - * cdef int _allocate_buffer(array self) except -1: # <<<<<<<<<<<<<< - * - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView._allocate_buffer", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":268 - * - * @cname("__pyx_array_new") - * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *c_mode, char *buf): # <<<<<<<<<<<<<< - * cdef array result - * cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string. - */ - -static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_c_mode, char *__pyx_v_buf) { - struct __pyx_array_obj *__pyx_v_result = 0; - PyObject *__pyx_v_mode = 0; - struct __pyx_array_obj *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("array_cwrapper", 1); - - /* "View.MemoryView":270 - * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *c_mode, char *buf): - * cdef array result - * cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string. # <<<<<<<<<<<<<< - * - * if buf is NULL: - */ - __pyx_t_2 = ((__pyx_v_c_mode[0]) == 'f'); - if (__pyx_t_2) { - __Pyx_INCREF(__pyx_n_s_fortran); - __pyx_t_1 = __pyx_n_s_fortran; - } else { - __Pyx_INCREF(__pyx_n_s_c); - __pyx_t_1 = __pyx_n_s_c; - } - __pyx_v_mode = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "View.MemoryView":272 - * cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string. - * - * if buf is NULL: # <<<<<<<<<<<<<< - * result = array.__new__(array, shape, itemsize, format, mode) - * else: - */ - __pyx_t_2 = (__pyx_v_buf == NULL); - if (__pyx_t_2) { - - /* "View.MemoryView":273 - * - * if buf is NULL: - * result = array.__new__(array, shape, itemsize, format, mode) # <<<<<<<<<<<<<< - * else: - * result = array.__new__(array, shape, itemsize, format, mode, allocate_buffer=False) - */ - __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 273, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 273, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 273, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_INCREF(__pyx_v_shape); - __Pyx_GIVEREF(__pyx_v_shape); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_shape)) __PYX_ERR(1, 273, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_1); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1)) __PYX_ERR(1, 273, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_3); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3)) __PYX_ERR(1, 273, __pyx_L1_error); - __Pyx_INCREF(__pyx_v_mode); - __Pyx_GIVEREF(__pyx_v_mode); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 3, __pyx_v_mode)) __PYX_ERR(1, 273, __pyx_L1_error); - __pyx_t_1 = 0; - __pyx_t_3 = 0; - __pyx_t_3 = ((PyObject *)__pyx_tp_new_array(((PyTypeObject *)__pyx_array_type), __pyx_t_4, NULL)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 273, __pyx_L1_error) - __Pyx_GOTREF((PyObject *)__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":272 - * cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string. - * - * if buf is NULL: # <<<<<<<<<<<<<< - * result = array.__new__(array, shape, itemsize, format, mode) - * else: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":275 - * result = array.__new__(array, shape, itemsize, format, mode) - * else: - * result = array.__new__(array, shape, itemsize, format, mode, allocate_buffer=False) # <<<<<<<<<<<<<< - * result.data = buf - * - */ - /*else*/ { - __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 275, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 275, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 275, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_shape); - __Pyx_GIVEREF(__pyx_v_shape); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_shape)) __PYX_ERR(1, 275, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_3); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3)) __PYX_ERR(1, 275, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_4); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_4)) __PYX_ERR(1, 275, __pyx_L1_error); - __Pyx_INCREF(__pyx_v_mode); - __Pyx_GIVEREF(__pyx_v_mode); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_mode)) __PYX_ERR(1, 275, __pyx_L1_error); - __pyx_t_3 = 0; - __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 275, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_allocate_buffer, Py_False) < 0) __PYX_ERR(1, 275, __pyx_L1_error) - __pyx_t_3 = ((PyObject *)__pyx_tp_new_array(((PyTypeObject *)__pyx_array_type), __pyx_t_1, __pyx_t_4)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 275, __pyx_L1_error) - __Pyx_GOTREF((PyObject *)__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":276 - * else: - * result = array.__new__(array, shape, itemsize, format, mode, allocate_buffer=False) - * result.data = buf # <<<<<<<<<<<<<< - * - * return result - */ - __pyx_v_result->data = __pyx_v_buf; - } - __pyx_L3:; - - /* "View.MemoryView":278 - * result.data = buf - * - * return result # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF((PyObject *)__pyx_r); - __Pyx_INCREF((PyObject *)__pyx_v_result); - __pyx_r = __pyx_v_result; - goto __pyx_L0; - - /* "View.MemoryView":268 - * - * @cname("__pyx_array_new") - * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *c_mode, char *buf): # <<<<<<<<<<<<<< - * cdef array result - * cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XDECREF(__pyx_v_mode); - __Pyx_XGIVEREF((PyObject *)__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":304 - * cdef class Enum(object): - * cdef object name - * def __init__(self, name): # <<<<<<<<<<<<<< - * self.name = name - * def __repr__(self): - */ - -/* Python wrapper */ -static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_name = 0; - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[1] = {0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - 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_name,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - 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 (likely((values[0] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_name)) != 0)) { - (void)__Pyx_Arg_NewRef_VARARGS(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 304, __pyx_L3_error) - else goto __pyx_L5_argtuple_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(1, 304, __pyx_L3_error) - } - } else if (unlikely(__pyx_nargs != 1)) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); - } - __pyx_v_name = values[0]; - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 304, __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("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name); - - /* 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_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__", 1); - - /* "View.MemoryView":305 - * cdef object name - * def __init__(self, name): - * self.name = name # <<<<<<<<<<<<<< - * def __repr__(self): - * return self.name - */ - __Pyx_INCREF(__pyx_v_name); - __Pyx_GIVEREF(__pyx_v_name); - __Pyx_GOTREF(__pyx_v_self->name); - __Pyx_DECREF(__pyx_v_self->name); - __pyx_v_self->name = __pyx_v_name; - - /* "View.MemoryView":304 - * cdef class Enum(object): - * cdef object name - * def __init__(self, name): # <<<<<<<<<<<<<< - * self.name = name - * def __repr__(self): - */ - - /* function exit code */ - __pyx_r = 0; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":306 - * def __init__(self, name): - * self.name = name - * def __repr__(self): # <<<<<<<<<<<<<< - * return self.name - * - */ - -/* Python wrapper */ -static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__", 1); - - /* "View.MemoryView":307 - * self.name = name - * def __repr__(self): - * return self.name # <<<<<<<<<<<<<< - * - * cdef generic = Enum("") - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->name); - __pyx_r = __pyx_v_self->name; - goto __pyx_L0; - - /* "View.MemoryView":306 - * def __init__(self, name): - * self.name = name - * def __repr__(self): # <<<<<<<<<<<<<< - * return self.name - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_MemviewEnum_1__reduce_cython__(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*/ -static PyObject *__pyx_pw___pyx_MemviewEnum_1__reduce_cython__(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 -) { - #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("__reduce_cython__ (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); - if (unlikely(__pyx_nargs > 0)) { - __Pyx_RaiseArgtupleInvalid("__reduce_cython__", 1, 0, 0, __pyx_nargs); return NULL;} - if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__reduce_cython__", 0))) return NULL; - __pyx_r = __pyx_pf___pyx_MemviewEnum___reduce_cython__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_MemviewEnum___reduce_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self) { - PyObject *__pyx_v_state = 0; - PyObject *__pyx_v__dict = 0; - int __pyx_v_use_setstate; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 1); - - /* "(tree fragment)":5 - * cdef object _dict - * cdef bint use_setstate - * state = (self.name,) # <<<<<<<<<<<<<< - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - */ - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_self->name); - __Pyx_GIVEREF(__pyx_v_self->name); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->name)) __PYX_ERR(1, 5, __pyx_L1_error); - __pyx_v_state = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "(tree fragment)":6 - * cdef bint use_setstate - * state = (self.name,) - * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< - * if _dict is not None: - * state += (_dict,) - */ - __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v__dict = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":7 - * state = (self.name,) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - __pyx_t_2 = (__pyx_v__dict != Py_None); - if (__pyx_t_2) { - - /* "(tree fragment)":8 - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - * state += (_dict,) # <<<<<<<<<<<<<< - * use_setstate = True - * else: - */ - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v__dict); - __Pyx_GIVEREF(__pyx_v__dict); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__dict)) __PYX_ERR(1, 8, __pyx_L1_error); - __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "(tree fragment)":9 - * if _dict is not None: - * state += (_dict,) - * use_setstate = True # <<<<<<<<<<<<<< - * else: - * use_setstate = self.name is not None - */ - __pyx_v_use_setstate = 1; - - /* "(tree fragment)":7 - * state = (self.name,) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - goto __pyx_L3; - } - - /* "(tree fragment)":11 - * use_setstate = True - * else: - * use_setstate = self.name is not None # <<<<<<<<<<<<<< - * if use_setstate: - * return __pyx_unpickle_Enum, (type(self), 0x82a3537, None), state - */ - /*else*/ { - __pyx_t_2 = (__pyx_v_self->name != Py_None); - __pyx_v_use_setstate = __pyx_t_2; - } - __pyx_L3:; - - /* "(tree fragment)":12 - * else: - * use_setstate = self.name is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_Enum, (type(self), 0x82a3537, None), state - * else: - */ - if (__pyx_v_use_setstate) { - - /* "(tree fragment)":13 - * use_setstate = self.name is not None - * if use_setstate: - * return __pyx_unpickle_Enum, (type(self), 0x82a3537, None), state # <<<<<<<<<<<<<< - * else: - * return __pyx_unpickle_Enum, (type(self), 0x82a3537, state) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_pyx_unpickle_Enum); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))))) __PYX_ERR(1, 13, __pyx_L1_error); - __Pyx_INCREF(__pyx_int_136983863); - __Pyx_GIVEREF(__pyx_int_136983863); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_136983863)) __PYX_ERR(1, 13, __pyx_L1_error); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, Py_None)) __PYX_ERR(1, 13, __pyx_L1_error); - __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_3); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3)) __PYX_ERR(1, 13, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_1); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_state)) __PYX_ERR(1, 13, __pyx_L1_error); - __pyx_t_3 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_4; - __pyx_t_4 = 0; - goto __pyx_L0; - - /* "(tree fragment)":12 - * else: - * use_setstate = self.name is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_Enum, (type(self), 0x82a3537, None), state - * else: - */ - } - - /* "(tree fragment)":15 - * return __pyx_unpickle_Enum, (type(self), 0x82a3537, None), state - * else: - * return __pyx_unpickle_Enum, (type(self), 0x82a3537, state) # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_Enum__set_state(self, __pyx_state) - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyx_unpickle_Enum); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))))) __PYX_ERR(1, 15, __pyx_L1_error); - __Pyx_INCREF(__pyx_int_136983863); - __Pyx_GIVEREF(__pyx_int_136983863); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_136983863)) __PYX_ERR(1, 15, __pyx_L1_error); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_state)) __PYX_ERR(1, 15, __pyx_L1_error); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 15, __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(1, 15, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_1); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error); - __pyx_t_4 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - } - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView.Enum.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_state); - __Pyx_XDECREF(__pyx_v__dict); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":16 - * else: - * return __pyx_unpickle_Enum, (type(self), 0x82a3537, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state(self, __pyx_state) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_MemviewEnum_3__setstate_cython__(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*/ -static PyObject *__pyx_pw___pyx_MemviewEnum_3__setstate_cython__(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___pyx_state = 0; - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[1] = {0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (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_pyx_state,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - 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_pyx_state)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 16, __pyx_L3_error) - else goto __pyx_L5_argtuple_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, "__setstate_cython__") < 0)) __PYX_ERR(1, 16, __pyx_L3_error) - } - } else if (unlikely(__pyx_nargs != 1)) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - } - __pyx_v___pyx_state = values[0]; - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__setstate_cython__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 16, __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("View.MemoryView.Enum.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf___pyx_MemviewEnum_2__setstate_cython__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v___pyx_state); - - /* 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___pyx_MemviewEnum_2__setstate_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 1); - - /* "(tree fragment)":17 - * return __pyx_unpickle_Enum, (type(self), 0x82a3537, state) - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_Enum__set_state(self, __pyx_state) # <<<<<<<<<<<<<< - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None) || __Pyx_RaiseUnexpectedTypeError("tuple", __pyx_v___pyx_state))) __PYX_ERR(1, 17, __pyx_L1_error) - __pyx_t_1 = __pyx_unpickle_Enum__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":16 - * else: - * return __pyx_unpickle_Enum, (type(self), 0x82a3537, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state(self, __pyx_state) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.Enum.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":349 - * cdef __Pyx_TypeInfo *typeinfo - * - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<< - * self.obj = obj - * self.flags = flags - */ - -/* Python wrapper */ -static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_obj = 0; - int __pyx_v_flags; - int __pyx_v_dtype_is_object; - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[3] = {0,0,0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (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_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - 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 (likely((values[0] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_obj)) != 0)) { - (void)__Pyx_Arg_NewRef_VARARGS(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 349, __pyx_L3_error) - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_flags)) != 0)) { - (void)__Pyx_Arg_NewRef_VARARGS(values[1]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 349, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); __PYX_ERR(1, 349, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (kw_args > 0) { - PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_dtype_is_object); - if (value) { values[2] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 349, __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, "__cinit__") < 0)) __PYX_ERR(1, 349, __pyx_L3_error) - } - } else { - switch (__pyx_nargs) { - case 3: values[2] = __Pyx_Arg_VARARGS(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = __Pyx_Arg_VARARGS(__pyx_args, 1); - values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_obj = values[0]; - __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 349, __pyx_L3_error) - if (values[2]) { - __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 349, __pyx_L3_error) - } else { - __pyx_v_dtype_is_object = ((int)0); - } - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, __pyx_nargs); __PYX_ERR(1, 349, __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("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object); - - /* 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_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - Py_intptr_t __pyx_t_4; - size_t __pyx_t_5; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 1); - - /* "View.MemoryView":350 - * - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): - * self.obj = obj # <<<<<<<<<<<<<< - * self.flags = flags - * if type(self) is memoryview or obj is not None: - */ - __Pyx_INCREF(__pyx_v_obj); - __Pyx_GIVEREF(__pyx_v_obj); - __Pyx_GOTREF(__pyx_v_self->obj); - __Pyx_DECREF(__pyx_v_self->obj); - __pyx_v_self->obj = __pyx_v_obj; - - /* "View.MemoryView":351 - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): - * self.obj = obj - * self.flags = flags # <<<<<<<<<<<<<< - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) - */ - __pyx_v_self->flags = __pyx_v_flags; - - /* "View.MemoryView":352 - * self.obj = obj - * self.flags = flags - * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<< - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: - */ - __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)__pyx_memoryview_type)); - if (!__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = (__pyx_v_obj != Py_None); - __pyx_t_1 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - if (__pyx_t_1) { - - /* "View.MemoryView":353 - * self.flags = flags - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<< - * if self.view.obj == NULL: - * (<__pyx_buffer *> &self.view).obj = Py_None - */ - __pyx_t_3 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(1, 353, __pyx_L1_error) - - /* "View.MemoryView":354 - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: # <<<<<<<<<<<<<< - * (<__pyx_buffer *> &self.view).obj = Py_None - * Py_INCREF(Py_None) - */ - __pyx_t_1 = (((PyObject *)__pyx_v_self->view.obj) == NULL); - if (__pyx_t_1) { - - /* "View.MemoryView":355 - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: - * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<< - * Py_INCREF(Py_None) - * - */ - ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None; - - /* "View.MemoryView":356 - * if self.view.obj == NULL: - * (<__pyx_buffer *> &self.view).obj = Py_None - * Py_INCREF(Py_None) # <<<<<<<<<<<<<< - * - * if not __PYX_CYTHON_ATOMICS_ENABLED(): - */ - Py_INCREF(Py_None); - - /* "View.MemoryView":354 - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: # <<<<<<<<<<<<<< - * (<__pyx_buffer *> &self.view).obj = Py_None - * Py_INCREF(Py_None) - */ - } - - /* "View.MemoryView":352 - * self.obj = obj - * self.flags = flags - * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<< - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: - */ - } - - /* "View.MemoryView":358 - * Py_INCREF(Py_None) - * - * if not __PYX_CYTHON_ATOMICS_ENABLED(): # <<<<<<<<<<<<<< - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < 8: - */ - __pyx_t_1 = (!__PYX_CYTHON_ATOMICS_ENABLED()); - if (__pyx_t_1) { - - /* "View.MemoryView":360 - * if not __PYX_CYTHON_ATOMICS_ENABLED(): - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < 8: # <<<<<<<<<<<<<< - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - */ - __pyx_t_1 = (__pyx_memoryview_thread_locks_used < 8); - if (__pyx_t_1) { - - /* "View.MemoryView":361 - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < 8: - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: - */ - __pyx_v_self->lock = (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]); - - /* "View.MemoryView":362 - * if __pyx_memoryview_thread_locks_used < 8: - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 # <<<<<<<<<<<<<< - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() - */ - __pyx_memoryview_thread_locks_used = (__pyx_memoryview_thread_locks_used + 1); - - /* "View.MemoryView":360 - * if not __PYX_CYTHON_ATOMICS_ENABLED(): - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < 8: # <<<<<<<<<<<<<< - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - */ - } - - /* "View.MemoryView":363 - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: # <<<<<<<<<<<<<< - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: - */ - __pyx_t_1 = (__pyx_v_self->lock == NULL); - if (__pyx_t_1) { - - /* "View.MemoryView":364 - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<< - * if self.lock is NULL: - * raise MemoryError - */ - __pyx_v_self->lock = PyThread_allocate_lock(); - - /* "View.MemoryView":365 - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: # <<<<<<<<<<<<<< - * raise MemoryError - * - */ - __pyx_t_1 = (__pyx_v_self->lock == NULL); - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":366 - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: - * raise MemoryError # <<<<<<<<<<<<<< - * - * if flags & PyBUF_FORMAT: - */ - PyErr_NoMemory(); __PYX_ERR(1, 366, __pyx_L1_error) - - /* "View.MemoryView":365 - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: # <<<<<<<<<<<<<< - * raise MemoryError - * - */ - } - - /* "View.MemoryView":363 - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: # <<<<<<<<<<<<<< - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: - */ - } - - /* "View.MemoryView":358 - * Py_INCREF(Py_None) - * - * if not __PYX_CYTHON_ATOMICS_ENABLED(): # <<<<<<<<<<<<<< - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < 8: - */ - } - - /* "View.MemoryView":368 - * raise MemoryError - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":369 - * - * if flags & PyBUF_FORMAT: - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') # <<<<<<<<<<<<<< - * else: - * self.dtype_is_object = dtype_is_object - */ - __pyx_t_2 = ((__pyx_v_self->view.format[0]) == 'O'); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L12_bool_binop_done; - } - __pyx_t_2 = ((__pyx_v_self->view.format[1]) == '\x00'); - __pyx_t_1 = __pyx_t_2; - __pyx_L12_bool_binop_done:; - __pyx_v_self->dtype_is_object = __pyx_t_1; - - /* "View.MemoryView":368 - * raise MemoryError - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') - * else: - */ - goto __pyx_L11; - } - - /* "View.MemoryView":371 - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') - * else: - * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<< - * - * assert (&self.acquisition_count) % sizeof(__pyx_atomic_int_type) == 0 - */ - /*else*/ { - __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object; - } - __pyx_L11:; - - /* "View.MemoryView":373 - * self.dtype_is_object = dtype_is_object - * - * assert (&self.acquisition_count) % sizeof(__pyx_atomic_int_type) == 0 # <<<<<<<<<<<<<< - * self.typeinfo = NULL - * - */ - #ifndef CYTHON_WITHOUT_ASSERTIONS - if (unlikely(__pyx_assertions_enabled())) { - __pyx_t_4 = ((Py_intptr_t)((void *)(&__pyx_v_self->acquisition_count))); - __pyx_t_5 = (sizeof(__pyx_atomic_int_type)); - if (unlikely(__pyx_t_5 == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); - __PYX_ERR(1, 373, __pyx_L1_error) - } - __pyx_t_1 = ((__pyx_t_4 % __pyx_t_5) == 0); - if (unlikely(!__pyx_t_1)) { - __Pyx_Raise(__pyx_builtin_AssertionError, 0, 0, 0); - __PYX_ERR(1, 373, __pyx_L1_error) - } - } - #else - if ((1)); else __PYX_ERR(1, 373, __pyx_L1_error) - #endif - - /* "View.MemoryView":374 - * - * assert (&self.acquisition_count) % sizeof(__pyx_atomic_int_type) == 0 - * self.typeinfo = NULL # <<<<<<<<<<<<<< - * - * def __dealloc__(memoryview self): - */ - __pyx_v_self->typeinfo = NULL; - - /* "View.MemoryView":349 - * cdef __Pyx_TypeInfo *typeinfo - * - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<< - * self.obj = obj - * self.flags = flags - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":376 - * self.typeinfo = NULL - * - * def __dealloc__(memoryview self): # <<<<<<<<<<<<<< - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) - */ - -/* Python wrapper */ -static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) { - int __pyx_v_i; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - PyThread_type_lock __pyx_t_5; - PyThread_type_lock __pyx_t_6; - - /* "View.MemoryView":377 - * - * def __dealloc__(memoryview self): - * if self.obj is not None: # <<<<<<<<<<<<<< - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: - */ - __pyx_t_1 = (__pyx_v_self->obj != Py_None); - if (__pyx_t_1) { - - /* "View.MemoryView":378 - * def __dealloc__(memoryview self): - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<< - * elif (<__pyx_buffer *> &self.view).obj == Py_None: - * - */ - __Pyx_ReleaseBuffer((&__pyx_v_self->view)); - - /* "View.MemoryView":377 - * - * def __dealloc__(memoryview self): - * if self.obj is not None: # <<<<<<<<<<<<<< - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":379 - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: # <<<<<<<<<<<<<< - * - * (<__pyx_buffer *> &self.view).obj = NULL - */ - __pyx_t_1 = (((Py_buffer *)(&__pyx_v_self->view))->obj == Py_None); - if (__pyx_t_1) { - - /* "View.MemoryView":381 - * elif (<__pyx_buffer *> &self.view).obj == Py_None: - * - * (<__pyx_buffer *> &self.view).obj = NULL # <<<<<<<<<<<<<< - * Py_DECREF(Py_None) - * - */ - ((Py_buffer *)(&__pyx_v_self->view))->obj = NULL; - - /* "View.MemoryView":382 - * - * (<__pyx_buffer *> &self.view).obj = NULL - * Py_DECREF(Py_None) # <<<<<<<<<<<<<< - * - * cdef int i - */ - Py_DECREF(Py_None); - - /* "View.MemoryView":379 - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: # <<<<<<<<<<<<<< - * - * (<__pyx_buffer *> &self.view).obj = NULL - */ - } - __pyx_L3:; - - /* "View.MemoryView":386 - * cdef int i - * global __pyx_memoryview_thread_locks_used - * if self.lock != NULL: # <<<<<<<<<<<<<< - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: - */ - __pyx_t_1 = (__pyx_v_self->lock != NULL); - if (__pyx_t_1) { - - /* "View.MemoryView":387 - * global __pyx_memoryview_thread_locks_used - * if self.lock != NULL: - * for i in range(__pyx_memoryview_thread_locks_used): # <<<<<<<<<<<<<< - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 - */ - __pyx_t_2 = __pyx_memoryview_thread_locks_used; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; - - /* "View.MemoryView":388 - * if self.lock != NULL: - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: - */ - __pyx_t_1 = ((__pyx_memoryview_thread_locks[__pyx_v_i]) == __pyx_v_self->lock); - if (__pyx_t_1) { - - /* "View.MemoryView":389 - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 # <<<<<<<<<<<<<< - * if i != __pyx_memoryview_thread_locks_used: - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - */ - __pyx_memoryview_thread_locks_used = (__pyx_memoryview_thread_locks_used - 1); - - /* "View.MemoryView":390 - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - */ - __pyx_t_1 = (__pyx_v_i != __pyx_memoryview_thread_locks_used); - if (__pyx_t_1) { - - /* "View.MemoryView":392 - * if i != __pyx_memoryview_thread_locks_used: - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) # <<<<<<<<<<<<<< - * break - * else: - */ - __pyx_t_5 = (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]); - __pyx_t_6 = (__pyx_memoryview_thread_locks[__pyx_v_i]); - - /* "View.MemoryView":391 - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - * break - */ - (__pyx_memoryview_thread_locks[__pyx_v_i]) = __pyx_t_5; - (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]) = __pyx_t_6; - - /* "View.MemoryView":390 - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - */ - } - - /* "View.MemoryView":393 - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - * break # <<<<<<<<<<<<<< - * else: - * PyThread_free_lock(self.lock) - */ - goto __pyx_L6_break; - - /* "View.MemoryView":388 - * if self.lock != NULL: - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: - */ - } - } - /*else*/ { - - /* "View.MemoryView":395 - * break - * else: - * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<< - * - * cdef char *get_item_pointer(memoryview self, object index) except NULL: - */ - PyThread_free_lock(__pyx_v_self->lock); - } - __pyx_L6_break:; - - /* "View.MemoryView":386 - * cdef int i - * global __pyx_memoryview_thread_locks_used - * if self.lock != NULL: # <<<<<<<<<<<<<< - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: - */ - } - - /* "View.MemoryView":376 - * self.typeinfo = NULL - * - * def __dealloc__(memoryview self): # <<<<<<<<<<<<<< - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) - */ - - /* function exit code */ -} - -/* "View.MemoryView":397 - * PyThread_free_lock(self.lock) - * - * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<< - * cdef Py_ssize_t dim - * cdef char *itemp = self.view.buf - */ - -static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) { - Py_ssize_t __pyx_v_dim; - char *__pyx_v_itemp; - PyObject *__pyx_v_idx = NULL; - char *__pyx_r; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - Py_ssize_t __pyx_t_3; - PyObject *(*__pyx_t_4)(PyObject *); - PyObject *__pyx_t_5 = NULL; - Py_ssize_t __pyx_t_6; - char *__pyx_t_7; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_item_pointer", 1); - - /* "View.MemoryView":399 - * cdef char *get_item_pointer(memoryview self, object index) except NULL: - * cdef Py_ssize_t dim - * cdef char *itemp = self.view.buf # <<<<<<<<<<<<<< - * - * for dim, idx in enumerate(index): - */ - __pyx_v_itemp = ((char *)__pyx_v_self->view.buf); - - /* "View.MemoryView":401 - * cdef char *itemp = self.view.buf - * - * for dim, idx in enumerate(index): # <<<<<<<<<<<<<< - * itemp = pybuffer_index(&self.view, itemp, idx, dim) - * - */ - __pyx_t_1 = 0; - if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) { - __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); - __pyx_t_3 = 0; - __pyx_t_4 = NULL; - } else { - __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 401, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 401, __pyx_L1_error) - } - for (;;) { - if (likely(!__pyx_t_4)) { - if (likely(PyList_CheckExact(__pyx_t_2))) { - { - Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); - #if !CYTHON_ASSUME_SAFE_MACROS - if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 401, __pyx_L1_error) - #endif - if (__pyx_t_3 >= __pyx_temp) break; - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(1, 401, __pyx_L1_error) - #else - __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 401, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - } else { - { - Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2); - #if !CYTHON_ASSUME_SAFE_MACROS - if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 401, __pyx_L1_error) - #endif - if (__pyx_t_3 >= __pyx_temp) break; - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely((0 < 0))) __PYX_ERR(1, 401, __pyx_L1_error) - #else - __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 401, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - } - } else { - __pyx_t_5 = __pyx_t_4(__pyx_t_2); - if (unlikely(!__pyx_t_5)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(1, 401, __pyx_L1_error) - } - break; - } - __Pyx_GOTREF(__pyx_t_5); - } - __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5); - __pyx_t_5 = 0; - __pyx_v_dim = __pyx_t_1; - __pyx_t_1 = (__pyx_t_1 + 1); - - /* "View.MemoryView":402 - * - * for dim, idx in enumerate(index): - * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<< - * - * return itemp - */ - __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 402, __pyx_L1_error) - __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == ((char *)NULL))) __PYX_ERR(1, 402, __pyx_L1_error) - __pyx_v_itemp = __pyx_t_7; - - /* "View.MemoryView":401 - * cdef char *itemp = self.view.buf - * - * for dim, idx in enumerate(index): # <<<<<<<<<<<<<< - * itemp = pybuffer_index(&self.view, itemp, idx, dim) - * - */ - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "View.MemoryView":404 - * itemp = pybuffer_index(&self.view, itemp, idx, dim) - * - * return itemp # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_itemp; - goto __pyx_L0; - - /* "View.MemoryView":397 - * PyThread_free_lock(self.lock) - * - * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<< - * cdef Py_ssize_t dim - * cdef char *itemp = self.view.buf - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_idx); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":407 - * - * - * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<< - * if index is Ellipsis: - * return self - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/ -static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) { - PyObject *__pyx_v_have_slices = NULL; - PyObject *__pyx_v_indices = NULL; - char *__pyx_v_itemp; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - char *__pyx_t_5; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__getitem__", 1); - - /* "View.MemoryView":408 - * - * def __getitem__(memoryview self, object index): - * if index is Ellipsis: # <<<<<<<<<<<<<< - * return self - * - */ - __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis); - if (__pyx_t_1) { - - /* "View.MemoryView":409 - * def __getitem__(memoryview self, object index): - * if index is Ellipsis: - * return self # <<<<<<<<<<<<<< - * - * have_slices, indices = _unellipsify(index, self.view.ndim) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF((PyObject *)__pyx_v_self); - __pyx_r = ((PyObject *)__pyx_v_self); - goto __pyx_L0; - - /* "View.MemoryView":408 - * - * def __getitem__(memoryview self, object index): - * if index is Ellipsis: # <<<<<<<<<<<<<< - * return self - * - */ - } - - /* "View.MemoryView":411 - * return self - * - * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<< - * - * cdef char *itemp - */ - __pyx_t_2 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 411, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (likely(__pyx_t_2 != Py_None)) { - PyObject* sequence = __pyx_t_2; - 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(1, 411, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - #else - __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 411, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 411, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - #endif - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } else { - __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 411, __pyx_L1_error) - } - __pyx_v_have_slices = __pyx_t_3; - __pyx_t_3 = 0; - __pyx_v_indices = __pyx_t_4; - __pyx_t_4 = 0; - - /* "View.MemoryView":414 - * - * cdef char *itemp - * if have_slices: # <<<<<<<<<<<<<< - * return memview_slice(self, indices) - * else: - */ - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 414, __pyx_L1_error) - if (__pyx_t_1) { - - /* "View.MemoryView":415 - * cdef char *itemp - * if have_slices: - * return memview_slice(self, indices) # <<<<<<<<<<<<<< - * else: - * itemp = self.get_item_pointer(indices) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 415, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":414 - * - * cdef char *itemp - * if have_slices: # <<<<<<<<<<<<<< - * return memview_slice(self, indices) - * else: - */ - } - - /* "View.MemoryView":417 - * return memview_slice(self, indices) - * else: - * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<< - * return self.convert_item_to_object(itemp) - * - */ - /*else*/ { - __pyx_t_5 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_5 == ((char *)NULL))) __PYX_ERR(1, 417, __pyx_L1_error) - __pyx_v_itemp = __pyx_t_5; - - /* "View.MemoryView":418 - * else: - * itemp = self.get_item_pointer(indices) - * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<< - * - * def __setitem__(memoryview self, object index, object value): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 418, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - } - - /* "View.MemoryView":407 - * - * - * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<< - * if index is Ellipsis: - * return self - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_have_slices); - __Pyx_XDECREF(__pyx_v_indices); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":420 - * return self.convert_item_to_object(itemp) - * - * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<< - * if self.view.readonly: - * raise TypeError, "Cannot assign to read-only memoryview" - */ - -/* Python wrapper */ -static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/ -static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { - PyObject *__pyx_v_have_slices = NULL; - PyObject *__pyx_v_obj = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setitem__", 0); - __Pyx_INCREF(__pyx_v_index); - - /* "View.MemoryView":421 - * - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: # <<<<<<<<<<<<<< - * raise TypeError, "Cannot assign to read-only memoryview" - * - */ - if (unlikely(__pyx_v_self->view.readonly)) { - - /* "View.MemoryView":422 - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: - * raise TypeError, "Cannot assign to read-only memoryview" # <<<<<<<<<<<<<< - * - * have_slices, index = _unellipsify(index, self.view.ndim) - */ - __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_Cannot_assign_to_read_only_memor, 0, 0); - __PYX_ERR(1, 422, __pyx_L1_error) - - /* "View.MemoryView":421 - * - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: # <<<<<<<<<<<<<< - * raise TypeError, "Cannot assign to read-only memoryview" - * - */ - } - - /* "View.MemoryView":424 - * raise TypeError, "Cannot assign to read-only memoryview" - * - * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<< - * - * if have_slices: - */ - __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 424, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (likely(__pyx_t_1 != Py_None)) { - PyObject* sequence = __pyx_t_1; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 2)) { - if (size > 2) __Pyx_RaiseTooManyValuesError(2); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(1, 424, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - #else - __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 424, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 424, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } else { - __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 424, __pyx_L1_error) - } - __pyx_v_have_slices = __pyx_t_2; - __pyx_t_2 = 0; - __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":426 - * have_slices, index = _unellipsify(index, self.view.ndim) - * - * if have_slices: # <<<<<<<<<<<<<< - * obj = self.is_slice(value) - * if obj: - */ - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(1, 426, __pyx_L1_error) - if (__pyx_t_4) { - - /* "View.MemoryView":427 - * - * if have_slices: - * obj = self.is_slice(value) # <<<<<<<<<<<<<< - * if obj: - * self.setitem_slice_assignment(self[index], obj) - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 427, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_obj = __pyx_t_1; - __pyx_t_1 = 0; - - /* "View.MemoryView":428 - * if have_slices: - * obj = self.is_slice(value) - * if obj: # <<<<<<<<<<<<<< - * self.setitem_slice_assignment(self[index], obj) - * else: - */ - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(1, 428, __pyx_L1_error) - if (__pyx_t_4) { - - /* "View.MemoryView":429 - * obj = self.is_slice(value) - * if obj: - * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<< - * else: - * self.setitem_slice_assign_scalar(self[index], value) - */ - __pyx_t_1 = __Pyx_PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 429, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 429, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "View.MemoryView":428 - * if have_slices: - * obj = self.is_slice(value) - * if obj: # <<<<<<<<<<<<<< - * self.setitem_slice_assignment(self[index], obj) - * else: - */ - goto __pyx_L5; - } - - /* "View.MemoryView":431 - * self.setitem_slice_assignment(self[index], obj) - * else: - * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<< - * else: - * self.setitem_indexed(index, value) - */ - /*else*/ { - __pyx_t_3 = __Pyx_PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 431, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) __PYX_ERR(1, 431, __pyx_L1_error) - __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 431, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } - __pyx_L5:; - - /* "View.MemoryView":426 - * have_slices, index = _unellipsify(index, self.view.ndim) - * - * if have_slices: # <<<<<<<<<<<<<< - * obj = self.is_slice(value) - * if obj: - */ - goto __pyx_L4; - } - - /* "View.MemoryView":433 - * self.setitem_slice_assign_scalar(self[index], value) - * else: - * self.setitem_indexed(index, value) # <<<<<<<<<<<<<< - * - * cdef is_slice(self, obj): - */ - /*else*/ { - __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 433, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } - __pyx_L4:; - - /* "View.MemoryView":420 - * return self.convert_item_to_object(itemp) - * - * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<< - * if self.view.readonly: - * raise TypeError, "Cannot assign to read-only memoryview" - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_have_slices); - __Pyx_XDECREF(__pyx_v_obj); - __Pyx_XDECREF(__pyx_v_index); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":435 - * self.setitem_indexed(index, value) - * - * cdef is_slice(self, obj): # <<<<<<<<<<<<<< - * if not isinstance(obj, memoryview): - * try: - */ - -static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("is_slice", 0); - __Pyx_INCREF(__pyx_v_obj); - - /* "View.MemoryView":436 - * - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<< - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - */ - __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, __pyx_memoryview_type); - __pyx_t_2 = (!__pyx_t_1); - if (__pyx_t_2) { - - /* "View.MemoryView":437 - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): - * try: # <<<<<<<<<<<<<< - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - /*try:*/ { - - /* "View.MemoryView":438 - * if not isinstance(obj, memoryview): - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<< - * self.dtype_is_object) - * except TypeError: - */ - __pyx_t_6 = __Pyx_PyInt_From_int(((__pyx_v_self->flags & (~PyBUF_WRITABLE)) | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 438, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - - /* "View.MemoryView":439 - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) # <<<<<<<<<<<<<< - * except TypeError: - * return None - */ - __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 439, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_7); - - /* "View.MemoryView":438 - * if not isinstance(obj, memoryview): - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<< - * self.dtype_is_object) - * except TypeError: - */ - __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 438, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_INCREF(__pyx_v_obj); - __Pyx_GIVEREF(__pyx_v_obj); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj)) __PYX_ERR(1, 438, __pyx_L4_error); - __Pyx_GIVEREF(__pyx_t_6); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6)) __PYX_ERR(1, 438, __pyx_L4_error); - __Pyx_GIVEREF(__pyx_t_7); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7)) __PYX_ERR(1, 438, __pyx_L4_error); - __pyx_t_6 = 0; - __pyx_t_7 = 0; - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 438, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7); - __pyx_t_7 = 0; - - /* "View.MemoryView":437 - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): - * try: # <<<<<<<<<<<<<< - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - goto __pyx_L9_try_end; - __pyx_L4_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - - /* "View.MemoryView":440 - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) - * except TypeError: # <<<<<<<<<<<<<< - * return None - * - */ - __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError); - if (__pyx_t_9) { - __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) __PYX_ERR(1, 440, __pyx_L6_except_error) - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_6); - - /* "View.MemoryView":441 - * self.dtype_is_object) - * except TypeError: - * return None # <<<<<<<<<<<<<< - * - * return obj - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - goto __pyx_L7_except_return; - } - goto __pyx_L6_except_error; - - /* "View.MemoryView":437 - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): - * try: # <<<<<<<<<<<<<< - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) - */ - __pyx_L6_except_error:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L1_error; - __pyx_L7_except_return:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L0; - __pyx_L9_try_end:; - } - - /* "View.MemoryView":436 - * - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<< - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - */ - } - - /* "View.MemoryView":443 - * return None - * - * return obj # <<<<<<<<<<<<<< - * - * cdef setitem_slice_assignment(self, dst, src): - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_obj); - __pyx_r = __pyx_v_obj; - goto __pyx_L0; - - /* "View.MemoryView":435 - * self.setitem_indexed(index, value) - * - * cdef is_slice(self, obj): # <<<<<<<<<<<<<< - * if not isinstance(obj, memoryview): - * try: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_obj); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":445 - * return obj - * - * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice dst_slice - * cdef __Pyx_memviewslice src_slice - */ - -static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) { - __Pyx_memviewslice __pyx_v_dst_slice; - __Pyx_memviewslice __pyx_v_src_slice; - __Pyx_memviewslice __pyx_v_msrc; - __Pyx_memviewslice __pyx_v_mdst; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("setitem_slice_assignment", 1); - - /* "View.MemoryView":448 - * cdef __Pyx_memviewslice dst_slice - * cdef __Pyx_memviewslice src_slice - * cdef __Pyx_memviewslice msrc = get_slice_from_memview(src, &src_slice)[0] # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice mdst = get_slice_from_memview(dst, &dst_slice)[0] - * - */ - if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) __PYX_ERR(1, 448, __pyx_L1_error) - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(1, 448, __pyx_L1_error) - __pyx_v_msrc = (__pyx_t_1[0]); - - /* "View.MemoryView":449 - * cdef __Pyx_memviewslice src_slice - * cdef __Pyx_memviewslice msrc = get_slice_from_memview(src, &src_slice)[0] - * cdef __Pyx_memviewslice mdst = get_slice_from_memview(dst, &dst_slice)[0] # <<<<<<<<<<<<<< - * - * memoryview_copy_contents(msrc, mdst, src.ndim, dst.ndim, self.dtype_is_object) - */ - if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) __PYX_ERR(1, 449, __pyx_L1_error) - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(1, 449, __pyx_L1_error) - __pyx_v_mdst = (__pyx_t_1[0]); - - /* "View.MemoryView":451 - * cdef __Pyx_memviewslice mdst = get_slice_from_memview(dst, &dst_slice)[0] - * - * memoryview_copy_contents(msrc, mdst, src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<< - * - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 451, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 451, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 451, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 451, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_5 = __pyx_memoryview_copy_contents(__pyx_v_msrc, __pyx_v_mdst, __pyx_t_3, __pyx_t_4, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(1, 451, __pyx_L1_error) - - /* "View.MemoryView":445 - * return obj - * - * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice dst_slice - * cdef __Pyx_memviewslice src_slice - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":453 - * memoryview_copy_contents(msrc, mdst, src.ndim, dst.ndim, self.dtype_is_object) - * - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<< - * cdef int array[128] - * cdef void *tmp = NULL - */ - -static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) { - int __pyx_v_array[0x80]; - void *__pyx_v_tmp; - void *__pyx_v_item; - __Pyx_memviewslice *__pyx_v_dst_slice; - __Pyx_memviewslice __pyx_v_tmp_slice; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - int __pyx_t_5; - char const *__pyx_t_6; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - PyObject *__pyx_t_12 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 1); - - /* "View.MemoryView":455 - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): - * cdef int array[128] - * cdef void *tmp = NULL # <<<<<<<<<<<<<< - * cdef void *item - * - */ - __pyx_v_tmp = NULL; - - /* "View.MemoryView":460 - * cdef __Pyx_memviewslice *dst_slice - * cdef __Pyx_memviewslice tmp_slice - * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<< - * - * if self.view.itemsize > sizeof(array): - */ - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(1, 460, __pyx_L1_error) - __pyx_v_dst_slice = __pyx_t_1; - - /* "View.MemoryView":462 - * dst_slice = get_slice_from_memview(dst, &tmp_slice) - * - * if self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<< - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: - */ - __pyx_t_2 = (((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))); - if (__pyx_t_2) { - - /* "View.MemoryView":463 - * - * if self.view.itemsize > sizeof(array): - * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<< - * if tmp == NULL: - * raise MemoryError - */ - __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize); - - /* "View.MemoryView":464 - * if self.view.itemsize > sizeof(array): - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: # <<<<<<<<<<<<<< - * raise MemoryError - * item = tmp - */ - __pyx_t_2 = (__pyx_v_tmp == NULL); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":465 - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: - * raise MemoryError # <<<<<<<<<<<<<< - * item = tmp - * else: - */ - PyErr_NoMemory(); __PYX_ERR(1, 465, __pyx_L1_error) - - /* "View.MemoryView":464 - * if self.view.itemsize > sizeof(array): - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: # <<<<<<<<<<<<<< - * raise MemoryError - * item = tmp - */ - } - - /* "View.MemoryView":466 - * if tmp == NULL: - * raise MemoryError - * item = tmp # <<<<<<<<<<<<<< - * else: - * item = array - */ - __pyx_v_item = __pyx_v_tmp; - - /* "View.MemoryView":462 - * dst_slice = get_slice_from_memview(dst, &tmp_slice) - * - * if self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<< - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":468 - * item = tmp - * else: - * item = array # <<<<<<<<<<<<<< - * - * try: - */ - /*else*/ { - __pyx_v_item = ((void *)__pyx_v_array); - } - __pyx_L3:; - - /* "View.MemoryView":470 - * item = array - * - * try: # <<<<<<<<<<<<<< - * if self.dtype_is_object: - * ( item)[0] = value - */ - /*try:*/ { - - /* "View.MemoryView":471 - * - * try: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * ( item)[0] = value - * else: - */ - if (__pyx_v_self->dtype_is_object) { - - /* "View.MemoryView":472 - * try: - * if self.dtype_is_object: - * ( item)[0] = value # <<<<<<<<<<<<<< - * else: - * self.assign_item_from_object( item, value) - */ - (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value); - - /* "View.MemoryView":471 - * - * try: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * ( item)[0] = value - * else: - */ - goto __pyx_L8; - } - - /* "View.MemoryView":474 - * ( item)[0] = value - * else: - * self.assign_item_from_object( item, value) # <<<<<<<<<<<<<< - * - * - */ - /*else*/ { - __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 474, __pyx_L6_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_L8:; - - /* "View.MemoryView":478 - * - * - * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<< - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, - */ - __pyx_t_2 = (__pyx_v_self->view.suboffsets != NULL); - if (__pyx_t_2) { - - /* "View.MemoryView":479 - * - * if self.view.suboffsets != NULL: - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<< - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, - * item, self.dtype_is_object) - */ - __pyx_t_4 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 479, __pyx_L6_error) - - /* "View.MemoryView":478 - * - * - * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<< - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, - */ - } - - /* "View.MemoryView":480 - * if self.view.suboffsets != NULL: - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<< - * item, self.dtype_is_object) - * finally: - */ - __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object); - } - - /* "View.MemoryView":483 - * item, self.dtype_is_object) - * finally: - * PyMem_Free(tmp) # <<<<<<<<<<<<<< - * - * cdef setitem_indexed(self, index, value): - */ - /*finally:*/ { - /*normal exit:*/{ - PyMem_Free(__pyx_v_tmp); - goto __pyx_L7; - } - __pyx_L6_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9) < 0)) __Pyx_ErrFetch(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_9); - __Pyx_XGOTREF(__pyx_t_10); - __Pyx_XGOTREF(__pyx_t_11); - __Pyx_XGOTREF(__pyx_t_12); - __pyx_t_4 = __pyx_lineno; __pyx_t_5 = __pyx_clineno; __pyx_t_6 = __pyx_filename; - { - PyMem_Free(__pyx_v_tmp); - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_10); - __Pyx_XGIVEREF(__pyx_t_11); - __Pyx_XGIVEREF(__pyx_t_12); - __Pyx_ExceptionReset(__pyx_t_10, __pyx_t_11, __pyx_t_12); - } - __Pyx_XGIVEREF(__pyx_t_7); - __Pyx_XGIVEREF(__pyx_t_8); - __Pyx_XGIVEREF(__pyx_t_9); - __Pyx_ErrRestore(__pyx_t_7, __pyx_t_8, __pyx_t_9); - __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; - __pyx_lineno = __pyx_t_4; __pyx_clineno = __pyx_t_5; __pyx_filename = __pyx_t_6; - goto __pyx_L1_error; - } - __pyx_L7:; - } - - /* "View.MemoryView":453 - * memoryview_copy_contents(msrc, mdst, src.ndim, dst.ndim, self.dtype_is_object) - * - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<< - * cdef int array[128] - * cdef void *tmp = NULL - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":485 - * PyMem_Free(tmp) - * - * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<< - * cdef char *itemp = self.get_item_pointer(index) - * self.assign_item_from_object(itemp, value) - */ - -static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { - char *__pyx_v_itemp; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - char *__pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("setitem_indexed", 1); - - /* "View.MemoryView":486 - * - * cdef setitem_indexed(self, index, value): - * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<< - * self.assign_item_from_object(itemp, value) - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == ((char *)NULL))) __PYX_ERR(1, 486, __pyx_L1_error) - __pyx_v_itemp = __pyx_t_1; - - /* "View.MemoryView":487 - * cdef setitem_indexed(self, index, value): - * cdef char *itemp = self.get_item_pointer(index) - * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<< - * - * cdef convert_item_to_object(self, char *itemp): - */ - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 487, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "View.MemoryView":485 - * PyMem_Free(tmp) - * - * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<< - * cdef char *itemp = self.get_item_pointer(index) - * self.assign_item_from_object(itemp, value) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":489 - * self.assign_item_from_object(itemp, value) - * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - */ - -static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) { - PyObject *__pyx_v_struct = NULL; - PyObject *__pyx_v_bytesitem = 0; - PyObject *__pyx_v_result = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - Py_ssize_t __pyx_t_9; - int __pyx_t_10; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("convert_item_to_object", 1); - - /* "View.MemoryView":492 - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - * import struct # <<<<<<<<<<<<<< - * cdef bytes bytesitem - * - */ - __pyx_t_1 = __Pyx_ImportDottedModule(__pyx_n_s_struct, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 492, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_struct = __pyx_t_1; - __pyx_t_1 = 0; - - /* "View.MemoryView":495 - * cdef bytes bytesitem - * - * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<< - * try: - * result = struct.unpack(self.view.format, bytesitem) - */ - __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 495, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_bytesitem = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "View.MemoryView":496 - * - * bytesitem = itemp[:self.view.itemsize] - * try: # <<<<<<<<<<<<<< - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "View.MemoryView":497 - * bytesitem = itemp[:self.view.itemsize] - * try: - * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<< - * except struct.error: - * raise ValueError, "Unable to convert item to object" - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 497, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 497, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = NULL; - __pyx_t_8 = 0; - #if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_7)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_7); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - __pyx_t_8 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[3] = {__pyx_t_7, __pyx_t_6, __pyx_v_bytesitem}; - __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_8, 2+__pyx_t_8); - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 497, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - __pyx_v_result = __pyx_t_1; - __pyx_t_1 = 0; - - /* "View.MemoryView":496 - * - * bytesitem = itemp[:self.view.itemsize] - * try: # <<<<<<<<<<<<<< - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - */ - } - - /* "View.MemoryView":501 - * raise ValueError, "Unable to convert item to object" - * else: - * if len(self.view.format) == 1: # <<<<<<<<<<<<<< - * return result[0] - * return result - */ - /*else:*/ { - __pyx_t_9 = __Pyx_ssize_strlen(__pyx_v_self->view.format); if (unlikely(__pyx_t_9 == ((Py_ssize_t)-1))) __PYX_ERR(1, 501, __pyx_L5_except_error) - __pyx_t_10 = (__pyx_t_9 == 1); - if (__pyx_t_10) { - - /* "View.MemoryView":502 - * else: - * if len(self.view.format) == 1: - * return result[0] # <<<<<<<<<<<<<< - * return result - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 502, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L6_except_return; - - /* "View.MemoryView":501 - * raise ValueError, "Unable to convert item to object" - * else: - * if len(self.view.format) == 1: # <<<<<<<<<<<<<< - * return result[0] - * return result - */ - } - - /* "View.MemoryView":503 - * if len(self.view.format) == 1: - * return result[0] - * return result # <<<<<<<<<<<<<< - * - * cdef assign_item_from_object(self, char *itemp, object value): - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_result); - __pyx_r = __pyx_v_result; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "View.MemoryView":498 - * try: - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: # <<<<<<<<<<<<<< - * raise ValueError, "Unable to convert item to object" - * else: - */ - __Pyx_ErrFetch(&__pyx_t_1, &__pyx_t_5, &__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 498, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_8 = __Pyx_PyErr_GivenExceptionMatches(__pyx_t_1, __pyx_t_7); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_ErrRestore(__pyx_t_1, __pyx_t_5, __pyx_t_6); - __pyx_t_1 = 0; __pyx_t_5 = 0; __pyx_t_6 = 0; - if (__pyx_t_8) { - __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_5, &__pyx_t_1) < 0) __PYX_ERR(1, 498, __pyx_L5_except_error) - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_1); - - /* "View.MemoryView":499 - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - * raise ValueError, "Unable to convert item to object" # <<<<<<<<<<<<<< - * else: - * if len(self.view.format) == 1: - */ - __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Unable_to_convert_item_to_object, 0, 0); - __PYX_ERR(1, 499, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - - /* "View.MemoryView":496 - * - * bytesitem = itemp[:self.view.itemsize] - * try: # <<<<<<<<<<<<<< - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - */ - __pyx_L5_except_error:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "View.MemoryView":489 - * self.assign_item_from_object(itemp, value) - * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_struct); - __Pyx_XDECREF(__pyx_v_bytesitem); - __Pyx_XDECREF(__pyx_v_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":505 - * return result - * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - */ - -static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) { - PyObject *__pyx_v_struct = NULL; - char __pyx_v_c; - PyObject *__pyx_v_bytesvalue = 0; - Py_ssize_t __pyx_v_i; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - Py_ssize_t __pyx_t_7; - PyObject *__pyx_t_8 = NULL; - char *__pyx_t_9; - char *__pyx_t_10; - char *__pyx_t_11; - char *__pyx_t_12; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("assign_item_from_object", 1); - - /* "View.MemoryView":508 - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - * import struct # <<<<<<<<<<<<<< - * cdef char c - * cdef bytes bytesvalue - */ - __pyx_t_1 = __Pyx_ImportDottedModule(__pyx_n_s_struct, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 508, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_struct = __pyx_t_1; - __pyx_t_1 = 0; - - /* "View.MemoryView":513 - * cdef Py_ssize_t i - * - * if isinstance(value, tuple): # <<<<<<<<<<<<<< - * bytesvalue = struct.pack(self.view.format, *value) - * else: - */ - __pyx_t_2 = PyTuple_Check(__pyx_v_value); - if (__pyx_t_2) { - - /* "View.MemoryView":514 - * - * if isinstance(value, tuple): - * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<< - * else: - * bytesvalue = struct.pack(self.view.format, value) - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 514, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 514, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 514, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_3); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3)) __PYX_ERR(1, 514, __pyx_L1_error); - __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 514, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyNumber_Add(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 514, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 514, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (!(likely(PyBytes_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None) || __Pyx_RaiseUnexpectedTypeError("bytes", __pyx_t_3))) __PYX_ERR(1, 514, __pyx_L1_error) - __pyx_v_bytesvalue = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":513 - * cdef Py_ssize_t i - * - * if isinstance(value, tuple): # <<<<<<<<<<<<<< - * bytesvalue = struct.pack(self.view.format, *value) - * else: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":516 - * bytesvalue = struct.pack(self.view.format, *value) - * else: - * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<< - * - * for i, c in enumerate(bytesvalue): - */ - /*else*/ { - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 516, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 516, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = NULL; - __pyx_t_6 = 0; - #if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - __pyx_t_6 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_t_1, __pyx_v_value}; - __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 516, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - if (!(likely(PyBytes_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None) || __Pyx_RaiseUnexpectedTypeError("bytes", __pyx_t_3))) __PYX_ERR(1, 516, __pyx_L1_error) - __pyx_v_bytesvalue = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - } - __pyx_L3:; - - /* "View.MemoryView":518 - * bytesvalue = struct.pack(self.view.format, value) - * - * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<< - * itemp[i] = c - * - */ - __pyx_t_7 = 0; - if (unlikely(__pyx_v_bytesvalue == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable"); - __PYX_ERR(1, 518, __pyx_L1_error) - } - __Pyx_INCREF(__pyx_v_bytesvalue); - __pyx_t_8 = __pyx_v_bytesvalue; - __pyx_t_10 = PyBytes_AS_STRING(__pyx_t_8); - __pyx_t_11 = (__pyx_t_10 + PyBytes_GET_SIZE(__pyx_t_8)); - for (__pyx_t_12 = __pyx_t_10; __pyx_t_12 < __pyx_t_11; __pyx_t_12++) { - __pyx_t_9 = __pyx_t_12; - __pyx_v_c = (__pyx_t_9[0]); - - /* "View.MemoryView":519 - * - * for i, c in enumerate(bytesvalue): - * itemp[i] = c # <<<<<<<<<<<<<< - * - * @cname('getbuffer') - */ - __pyx_v_i = __pyx_t_7; - - /* "View.MemoryView":518 - * bytesvalue = struct.pack(self.view.format, value) - * - * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<< - * itemp[i] = c - * - */ - __pyx_t_7 = (__pyx_t_7 + 1); - - /* "View.MemoryView":519 - * - * for i, c in enumerate(bytesvalue): - * itemp[i] = c # <<<<<<<<<<<<<< - * - * @cname('getbuffer') - */ - (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c; - } - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - - /* "View.MemoryView":505 - * return result - * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_struct); - __Pyx_XDECREF(__pyx_v_bytesvalue); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":521 - * itemp[i] = c - * - * @cname('getbuffer') # <<<<<<<<<<<<<< - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: - */ - -/* Python wrapper */ -CYTHON_UNUSED static int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -CYTHON_UNUSED static int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - Py_ssize_t *__pyx_t_3; - char *__pyx_t_4; - void *__pyx_t_5; - int __pyx_t_6; - Py_ssize_t __pyx_t_7; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - if (unlikely(__pyx_v_info == NULL)) { - PyErr_SetString(PyExc_BufferError, "PyObject_GetBuffer: view==NULL argument is obsolete"); - return -1; - } - __Pyx_RefNannySetupContext("__getbuffer__", 0); - __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(__pyx_v_info->obj); - - /* "View.MemoryView":523 - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: # <<<<<<<<<<<<<< - * raise ValueError, "Cannot create writable memory view from read-only memoryview" - * - */ - __pyx_t_2 = ((__pyx_v_flags & PyBUF_WRITABLE) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_1 = __pyx_v_self->view.readonly; - __pyx_L4_bool_binop_done:; - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":524 - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: - * raise ValueError, "Cannot create writable memory view from read-only memoryview" # <<<<<<<<<<<<<< - * - * if flags & PyBUF_ND: - */ - __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Cannot_create_writable_memory_vi, 0, 0); - __PYX_ERR(1, 524, __pyx_L1_error) - - /* "View.MemoryView":523 - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: # <<<<<<<<<<<<<< - * raise ValueError, "Cannot create writable memory view from read-only memoryview" - * - */ - } - - /* "View.MemoryView":526 - * raise ValueError, "Cannot create writable memory view from read-only memoryview" - * - * if flags & PyBUF_ND: # <<<<<<<<<<<<<< - * info.shape = self.view.shape - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_ND) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":527 - * - * if flags & PyBUF_ND: - * info.shape = self.view.shape # <<<<<<<<<<<<<< - * else: - * info.shape = NULL - */ - __pyx_t_3 = __pyx_v_self->view.shape; - __pyx_v_info->shape = __pyx_t_3; - - /* "View.MemoryView":526 - * raise ValueError, "Cannot create writable memory view from read-only memoryview" - * - * if flags & PyBUF_ND: # <<<<<<<<<<<<<< - * info.shape = self.view.shape - * else: - */ - goto __pyx_L6; - } - - /* "View.MemoryView":529 - * info.shape = self.view.shape - * else: - * info.shape = NULL # <<<<<<<<<<<<<< - * - * if flags & PyBUF_STRIDES: - */ - /*else*/ { - __pyx_v_info->shape = NULL; - } - __pyx_L6:; - - /* "View.MemoryView":531 - * info.shape = NULL - * - * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< - * info.strides = self.view.strides - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":532 - * - * if flags & PyBUF_STRIDES: - * info.strides = self.view.strides # <<<<<<<<<<<<<< - * else: - * info.strides = NULL - */ - __pyx_t_3 = __pyx_v_self->view.strides; - __pyx_v_info->strides = __pyx_t_3; - - /* "View.MemoryView":531 - * info.shape = NULL - * - * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< - * info.strides = self.view.strides - * else: - */ - goto __pyx_L7; - } - - /* "View.MemoryView":534 - * info.strides = self.view.strides - * else: - * info.strides = NULL # <<<<<<<<<<<<<< - * - * if flags & PyBUF_INDIRECT: - */ - /*else*/ { - __pyx_v_info->strides = NULL; - } - __pyx_L7:; - - /* "View.MemoryView":536 - * info.strides = NULL - * - * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<< - * info.suboffsets = self.view.suboffsets - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":537 - * - * if flags & PyBUF_INDIRECT: - * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<< - * else: - * info.suboffsets = NULL - */ - __pyx_t_3 = __pyx_v_self->view.suboffsets; - __pyx_v_info->suboffsets = __pyx_t_3; - - /* "View.MemoryView":536 - * info.strides = NULL - * - * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<< - * info.suboffsets = self.view.suboffsets - * else: - */ - goto __pyx_L8; - } - - /* "View.MemoryView":539 - * info.suboffsets = self.view.suboffsets - * else: - * info.suboffsets = NULL # <<<<<<<<<<<<<< - * - * if flags & PyBUF_FORMAT: - */ - /*else*/ { - __pyx_v_info->suboffsets = NULL; - } - __pyx_L8:; - - /* "View.MemoryView":541 - * info.suboffsets = NULL - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * info.format = self.view.format - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":542 - * - * if flags & PyBUF_FORMAT: - * info.format = self.view.format # <<<<<<<<<<<<<< - * else: - * info.format = NULL - */ - __pyx_t_4 = __pyx_v_self->view.format; - __pyx_v_info->format = __pyx_t_4; - - /* "View.MemoryView":541 - * info.suboffsets = NULL - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * info.format = self.view.format - * else: - */ - goto __pyx_L9; - } - - /* "View.MemoryView":544 - * info.format = self.view.format - * else: - * info.format = NULL # <<<<<<<<<<<<<< - * - * info.buf = self.view.buf - */ - /*else*/ { - __pyx_v_info->format = NULL; - } - __pyx_L9:; - - /* "View.MemoryView":546 - * info.format = NULL - * - * info.buf = self.view.buf # <<<<<<<<<<<<<< - * info.ndim = self.view.ndim - * info.itemsize = self.view.itemsize - */ - __pyx_t_5 = __pyx_v_self->view.buf; - __pyx_v_info->buf = __pyx_t_5; - - /* "View.MemoryView":547 - * - * info.buf = self.view.buf - * info.ndim = self.view.ndim # <<<<<<<<<<<<<< - * info.itemsize = self.view.itemsize - * info.len = self.view.len - */ - __pyx_t_6 = __pyx_v_self->view.ndim; - __pyx_v_info->ndim = __pyx_t_6; - - /* "View.MemoryView":548 - * info.buf = self.view.buf - * info.ndim = self.view.ndim - * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<< - * info.len = self.view.len - * info.readonly = self.view.readonly - */ - __pyx_t_7 = __pyx_v_self->view.itemsize; - __pyx_v_info->itemsize = __pyx_t_7; - - /* "View.MemoryView":549 - * info.ndim = self.view.ndim - * info.itemsize = self.view.itemsize - * info.len = self.view.len # <<<<<<<<<<<<<< - * info.readonly = self.view.readonly - * info.obj = self - */ - __pyx_t_7 = __pyx_v_self->view.len; - __pyx_v_info->len = __pyx_t_7; - - /* "View.MemoryView":550 - * info.itemsize = self.view.itemsize - * info.len = self.view.len - * info.readonly = self.view.readonly # <<<<<<<<<<<<<< - * info.obj = self - * - */ - __pyx_t_1 = __pyx_v_self->view.readonly; - __pyx_v_info->readonly = __pyx_t_1; - - /* "View.MemoryView":551 - * info.len = self.view.len - * info.readonly = self.view.readonly - * info.obj = self # <<<<<<<<<<<<<< - * - * - */ - __Pyx_INCREF((PyObject *)__pyx_v_self); - __Pyx_GIVEREF((PyObject *)__pyx_v_self); - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); - __pyx_v_info->obj = ((PyObject *)__pyx_v_self); - - /* "View.MemoryView":521 - * itemp[i] = c - * - * @cname('getbuffer') # <<<<<<<<<<<<<< - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView.memoryview.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - if (__pyx_v_info->obj != NULL) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - goto __pyx_L2; - __pyx_L0:; - if (__pyx_v_info->obj == Py_None) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - __pyx_L2:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":554 - * - * - * @property # <<<<<<<<<<<<<< - * def T(self): - * cdef _memoryviewslice result = memoryview_copy(self) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - struct __pyx_memoryviewslice_obj *__pyx_v_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 1); - - /* "View.MemoryView":556 - * @property - * def T(self): - * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<< - * transpose_memslice(&result.from_slice) - * return result - */ - __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 556, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) __PYX_ERR(1, 556, __pyx_L1_error) - __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "View.MemoryView":557 - * def T(self): - * cdef _memoryviewslice result = memoryview_copy(self) - * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<< - * return result - * - */ - __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(1, 557, __pyx_L1_error) - - /* "View.MemoryView":558 - * cdef _memoryviewslice result = memoryview_copy(self) - * transpose_memslice(&result.from_slice) - * return result # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF((PyObject *)__pyx_v_result); - __pyx_r = ((PyObject *)__pyx_v_result); - goto __pyx_L0; - - /* "View.MemoryView":554 - * - * - * @property # <<<<<<<<<<<<<< - * def T(self): - * cdef _memoryviewslice result = memoryview_copy(self) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":560 - * return result - * - * @property # <<<<<<<<<<<<<< - * def base(self): - * return self._get_base() - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 1); - - /* "View.MemoryView":562 - * @property - * def base(self): - * return self._get_base() # <<<<<<<<<<<<<< - * - * cdef _get_base(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->_get_base(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 562, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":560 - * return result - * - * @property # <<<<<<<<<<<<<< - * def base(self): - * return self._get_base() - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.base.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":564 - * return self._get_base() - * - * cdef _get_base(self): # <<<<<<<<<<<<<< - * return self.obj - * - */ - -static PyObject *__pyx_memoryview__get_base(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_get_base", 1); - - /* "View.MemoryView":565 - * - * cdef _get_base(self): - * return self.obj # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->obj); - __pyx_r = __pyx_v_self->obj; - goto __pyx_L0; - - /* "View.MemoryView":564 - * return self._get_base() - * - * cdef _get_base(self): # <<<<<<<<<<<<<< - * return self.obj - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":567 - * return self.obj - * - * @property # <<<<<<<<<<<<<< - * def shape(self): - * return tuple([length for length in self.view.shape[:self.view.ndim]]) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_7genexpr__pyx_v_length; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t *__pyx_t_2; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 1); - - /* "View.MemoryView":569 - * @property - * def shape(self): - * return tuple([length for length in self.view.shape[:self.view.ndim]]) # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - { /* enter inner scope */ - __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 569, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = (__pyx_v_self->view.shape + __pyx_v_self->view.ndim); - for (__pyx_t_4 = __pyx_v_self->view.shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { - __pyx_t_2 = __pyx_t_4; - __pyx_7genexpr__pyx_v_length = (__pyx_t_2[0]); - __pyx_t_5 = PyInt_FromSsize_t(__pyx_7genexpr__pyx_v_length); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 569, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(1, 569, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - } /* exit inner scope */ - __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 569, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; - goto __pyx_L0; - - /* "View.MemoryView":567 - * return self.obj - * - * @property # <<<<<<<<<<<<<< - * def shape(self): - * return tuple([length for length in self.view.shape[:self.view.ndim]]) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":571 - * return tuple([length for length in self.view.shape[:self.view.ndim]]) - * - * @property # <<<<<<<<<<<<<< - * def strides(self): - * if self.view.strides == NULL: - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_8genexpr1__pyx_v_stride; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - Py_ssize_t *__pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 1); - - /* "View.MemoryView":573 - * @property - * def strides(self): - * if self.view.strides == NULL: # <<<<<<<<<<<<<< - * - * raise ValueError, "Buffer view does not expose strides" - */ - __pyx_t_1 = (__pyx_v_self->view.strides == NULL); - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":575 - * if self.view.strides == NULL: - * - * raise ValueError, "Buffer view does not expose strides" # <<<<<<<<<<<<<< - * - * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) - */ - __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Buffer_view_does_not_expose_stri, 0, 0); - __PYX_ERR(1, 575, __pyx_L1_error) - - /* "View.MemoryView":573 - * @property - * def strides(self): - * if self.view.strides == NULL: # <<<<<<<<<<<<<< - * - * raise ValueError, "Buffer view does not expose strides" - */ - } - - /* "View.MemoryView":577 - * raise ValueError, "Buffer view does not expose strides" - * - * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - { /* enter inner scope */ - __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 577, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = (__pyx_v_self->view.strides + __pyx_v_self->view.ndim); - for (__pyx_t_5 = __pyx_v_self->view.strides; __pyx_t_5 < __pyx_t_4; __pyx_t_5++) { - __pyx_t_3 = __pyx_t_5; - __pyx_8genexpr1__pyx_v_stride = (__pyx_t_3[0]); - __pyx_t_6 = PyInt_FromSsize_t(__pyx_8genexpr1__pyx_v_stride); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 577, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) __PYX_ERR(1, 577, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - } /* exit inner scope */ - __pyx_t_6 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 577, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_6; - __pyx_t_6 = 0; - goto __pyx_L0; - - /* "View.MemoryView":571 - * return tuple([length for length in self.view.shape[:self.view.ndim]]) - * - * @property # <<<<<<<<<<<<<< - * def strides(self): - * if self.view.strides == NULL: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":579 - * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) - * - * @property # <<<<<<<<<<<<<< - * def suboffsets(self): - * if self.view.suboffsets == NULL: - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_8genexpr2__pyx_v_suboffset; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - Py_ssize_t *__pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 1); - - /* "View.MemoryView":581 - * @property - * def suboffsets(self): - * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<< - * return (-1,) * self.view.ndim - * - */ - __pyx_t_1 = (__pyx_v_self->view.suboffsets == NULL); - if (__pyx_t_1) { - - /* "View.MemoryView":582 - * def suboffsets(self): - * if self.view.suboffsets == NULL: - * return (-1,) * self.view.ndim # <<<<<<<<<<<<<< - * - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PySequence_Multiply(__pyx_tuple__4, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 582, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":581 - * @property - * def suboffsets(self): - * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<< - * return (-1,) * self.view.ndim - * - */ - } - - /* "View.MemoryView":584 - * return (-1,) * self.view.ndim - * - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - { /* enter inner scope */ - __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 584, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = (__pyx_v_self->view.suboffsets + __pyx_v_self->view.ndim); - for (__pyx_t_5 = __pyx_v_self->view.suboffsets; __pyx_t_5 < __pyx_t_4; __pyx_t_5++) { - __pyx_t_3 = __pyx_t_5; - __pyx_8genexpr2__pyx_v_suboffset = (__pyx_t_3[0]); - __pyx_t_6 = PyInt_FromSsize_t(__pyx_8genexpr2__pyx_v_suboffset); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 584, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) __PYX_ERR(1, 584, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - } /* exit inner scope */ - __pyx_t_6 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 584, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_6; - __pyx_t_6 = 0; - goto __pyx_L0; - - /* "View.MemoryView":579 - * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) - * - * @property # <<<<<<<<<<<<<< - * def suboffsets(self): - * if self.view.suboffsets == NULL: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":586 - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) - * - * @property # <<<<<<<<<<<<<< - * def ndim(self): - * return self.view.ndim - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 1); - - /* "View.MemoryView":588 - * @property - * def ndim(self): - * return self.view.ndim # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 588, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":586 - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) - * - * @property # <<<<<<<<<<<<<< - * def ndim(self): - * return self.view.ndim - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":590 - * return self.view.ndim - * - * @property # <<<<<<<<<<<<<< - * def itemsize(self): - * return self.view.itemsize - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 1); - - /* "View.MemoryView":592 - * @property - * def itemsize(self): - * return self.view.itemsize # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 592, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":590 - * return self.view.ndim - * - * @property # <<<<<<<<<<<<<< - * def itemsize(self): - * return self.view.itemsize - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":594 - * return self.view.itemsize - * - * @property # <<<<<<<<<<<<<< - * def nbytes(self): - * return self.size * self.view.itemsize - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 1); - - /* "View.MemoryView":596 - * @property - * def nbytes(self): - * return self.size * self.view.itemsize # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 596, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 596, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 596, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "View.MemoryView":594 - * return self.view.itemsize - * - * @property # <<<<<<<<<<<<<< - * def nbytes(self): - * return self.size * self.view.itemsize - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":598 - * return self.size * self.view.itemsize - * - * @property # <<<<<<<<<<<<<< - * def size(self): - * if self._size is None: - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_v_result = NULL; - PyObject *__pyx_v_length = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - Py_ssize_t *__pyx_t_2; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 1); - - /* "View.MemoryView":600 - * @property - * def size(self): - * if self._size is None: # <<<<<<<<<<<<<< - * result = 1 - * - */ - __pyx_t_1 = (__pyx_v_self->_size == Py_None); - if (__pyx_t_1) { - - /* "View.MemoryView":601 - * def size(self): - * if self._size is None: - * result = 1 # <<<<<<<<<<<<<< - * - * for length in self.view.shape[:self.view.ndim]: - */ - __Pyx_INCREF(__pyx_int_1); - __pyx_v_result = __pyx_int_1; - - /* "View.MemoryView":603 - * result = 1 - * - * for length in self.view.shape[:self.view.ndim]: # <<<<<<<<<<<<<< - * result *= length - * - */ - __pyx_t_3 = (__pyx_v_self->view.shape + __pyx_v_self->view.ndim); - for (__pyx_t_4 = __pyx_v_self->view.shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { - __pyx_t_2 = __pyx_t_4; - __pyx_t_5 = PyInt_FromSsize_t((__pyx_t_2[0])); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 603, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_5); - __pyx_t_5 = 0; - - /* "View.MemoryView":604 - * - * for length in self.view.shape[:self.view.ndim]: - * result *= length # <<<<<<<<<<<<<< - * - * self._size = result - */ - __pyx_t_5 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 604, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_5); - __pyx_t_5 = 0; - } - - /* "View.MemoryView":606 - * result *= length - * - * self._size = result # <<<<<<<<<<<<<< - * - * return self._size - */ - __Pyx_INCREF(__pyx_v_result); - __Pyx_GIVEREF(__pyx_v_result); - __Pyx_GOTREF(__pyx_v_self->_size); - __Pyx_DECREF(__pyx_v_self->_size); - __pyx_v_self->_size = __pyx_v_result; - - /* "View.MemoryView":600 - * @property - * def size(self): - * if self._size is None: # <<<<<<<<<<<<<< - * result = 1 - * - */ - } - - /* "View.MemoryView":608 - * self._size = result - * - * return self._size # <<<<<<<<<<<<<< - * - * def __len__(self): - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->_size); - __pyx_r = __pyx_v_self->_size; - goto __pyx_L0; - - /* "View.MemoryView":598 - * return self.size * self.view.itemsize - * - * @property # <<<<<<<<<<<<<< - * def size(self): - * if self._size is None: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_result); - __Pyx_XDECREF(__pyx_v_length); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":610 - * return self._size - * - * def __len__(self): # <<<<<<<<<<<<<< - * if self.view.ndim >= 1: - * return self.view.shape[0] - */ - -/* Python wrapper */ -static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/ -static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static Py_ssize_t __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_r; - int __pyx_t_1; - - /* "View.MemoryView":611 - * - * def __len__(self): - * if self.view.ndim >= 1: # <<<<<<<<<<<<<< - * return self.view.shape[0] - * - */ - __pyx_t_1 = (__pyx_v_self->view.ndim >= 1); - if (__pyx_t_1) { - - /* "View.MemoryView":612 - * def __len__(self): - * if self.view.ndim >= 1: - * return self.view.shape[0] # <<<<<<<<<<<<<< - * - * return 0 - */ - __pyx_r = (__pyx_v_self->view.shape[0]); - goto __pyx_L0; - - /* "View.MemoryView":611 - * - * def __len__(self): - * if self.view.ndim >= 1: # <<<<<<<<<<<<<< - * return self.view.shape[0] - * - */ - } - - /* "View.MemoryView":614 - * return self.view.shape[0] - * - * return 0 # <<<<<<<<<<<<<< - * - * def __repr__(self): - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":610 - * return self._size - * - * def __len__(self): # <<<<<<<<<<<<<< - * if self.view.ndim >= 1: - * return self.view.shape[0] - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":616 - * return 0 - * - * def __repr__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__, - * id(self)) - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__repr__", 1); - - /* "View.MemoryView":617 - * - * def __repr__(self): - * return "" % (self.base.__class__.__name__, # <<<<<<<<<<<<<< - * id(self)) - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 617, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 617, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 617, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "View.MemoryView":618 - * def __repr__(self): - * return "" % (self.base.__class__.__name__, - * id(self)) # <<<<<<<<<<<<<< - * - * def __str__(self): - */ - __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 618, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - - /* "View.MemoryView":617 - * - * def __repr__(self): - * return "" % (self.base.__class__.__name__, # <<<<<<<<<<<<<< - * id(self)) - * - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 617, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(1, 617, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_2); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2)) __PYX_ERR(1, 617, __pyx_L1_error); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 617, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":616 - * return 0 - * - * def __repr__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__, - * id(self)) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":620 - * id(self)) - * - * def __str__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__,) - * - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__str__", 1); - - /* "View.MemoryView":621 - * - * def __str__(self): - * return "" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 621, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 621, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 621, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 621, __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(1, 621, __pyx_L1_error); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 621, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":620 - * id(self)) - * - * def __str__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__,) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":624 - * - * - * def is_c_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview_is_c_contig(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*/ -static PyObject *__pyx_memoryview_is_c_contig(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 -) { - #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("is_c_contig (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); - if (unlikely(__pyx_nargs > 0)) { - __Pyx_RaiseArgtupleInvalid("is_c_contig", 1, 0, 0, __pyx_nargs); return NULL;} - if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "is_c_contig", 0))) return NULL; - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice *__pyx_v_mslice; - __Pyx_memviewslice __pyx_v_tmp; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("is_c_contig", 1); - - /* "View.MemoryView":627 - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<< - * return slice_is_contig(mslice[0], 'C', self.view.ndim) - * - */ - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(1, 627, __pyx_L1_error) - __pyx_v_mslice = __pyx_t_1; - - /* "View.MemoryView":628 - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) - * return slice_is_contig(mslice[0], 'C', self.view.ndim) # <<<<<<<<<<<<<< - * - * def is_f_contig(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig((__pyx_v_mslice[0]), 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 628, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":624 - * - * - * def is_c_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":630 - * return slice_is_contig(mslice[0], 'C', self.view.ndim) - * - * def is_f_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview_is_f_contig(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*/ -static PyObject *__pyx_memoryview_is_f_contig(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 -) { - #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("is_f_contig (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); - if (unlikely(__pyx_nargs > 0)) { - __Pyx_RaiseArgtupleInvalid("is_f_contig", 1, 0, 0, __pyx_nargs); return NULL;} - if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "is_f_contig", 0))) return NULL; - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice *__pyx_v_mslice; - __Pyx_memviewslice __pyx_v_tmp; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("is_f_contig", 1); - - /* "View.MemoryView":633 - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<< - * return slice_is_contig(mslice[0], 'F', self.view.ndim) - * - */ - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(1, 633, __pyx_L1_error) - __pyx_v_mslice = __pyx_t_1; - - /* "View.MemoryView":634 - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) - * return slice_is_contig(mslice[0], 'F', self.view.ndim) # <<<<<<<<<<<<<< - * - * def copy(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig((__pyx_v_mslice[0]), 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 634, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":630 - * return slice_is_contig(mslice[0], 'C', self.view.ndim) - * - * def is_f_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":636 - * return slice_is_contig(mslice[0], 'F', self.view.ndim) - * - * def copy(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice mslice - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview_copy(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*/ -static PyObject *__pyx_memoryview_copy(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 -) { - #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("copy (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); - if (unlikely(__pyx_nargs > 0)) { - __Pyx_RaiseArgtupleInvalid("copy", 1, 0, 0, __pyx_nargs); return NULL;} - if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "copy", 0))) return NULL; - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice __pyx_v_mslice; - int __pyx_v_flags; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("copy", 1); - - /* "View.MemoryView":638 - * def copy(self): - * cdef __Pyx_memviewslice mslice - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<< - * - * slice_copy(self, &mslice) - */ - __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS)); - - /* "View.MemoryView":640 - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS - * - * slice_copy(self, &mslice) # <<<<<<<<<<<<<< - * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, - * self.view.itemsize, - */ - __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice)); - - /* "View.MemoryView":641 - * - * slice_copy(self, &mslice) - * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<< - * self.view.itemsize, - * flags|PyBUF_C_CONTIGUOUS, - */ - __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), ((char *)"c"), __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 641, __pyx_L1_error) - __pyx_v_mslice = __pyx_t_1; - - /* "View.MemoryView":646 - * self.dtype_is_object) - * - * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<< - * - * def copy_fortran(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 646, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":636 - * return slice_is_contig(mslice[0], 'F', self.view.ndim) - * - * def copy(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice mslice - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":648 - * return memoryview_copy_from_slice(self, &mslice) - * - * def copy_fortran(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice src, dst - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview_copy_fortran(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*/ -static PyObject *__pyx_memoryview_copy_fortran(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 -) { - #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("copy_fortran (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); - if (unlikely(__pyx_nargs > 0)) { - __Pyx_RaiseArgtupleInvalid("copy_fortran", 1, 0, 0, __pyx_nargs); return NULL;} - if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "copy_fortran", 0))) return NULL; - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice __pyx_v_src; - __Pyx_memviewslice __pyx_v_dst; - int __pyx_v_flags; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("copy_fortran", 1); - - /* "View.MemoryView":650 - * def copy_fortran(self): - * cdef __Pyx_memviewslice src, dst - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<< - * - * slice_copy(self, &src) - */ - __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS)); - - /* "View.MemoryView":652 - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS - * - * slice_copy(self, &src) # <<<<<<<<<<<<<< - * dst = slice_copy_contig(&src, "fortran", self.view.ndim, - * self.view.itemsize, - */ - __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src)); - - /* "View.MemoryView":653 - * - * slice_copy(self, &src) - * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<< - * self.view.itemsize, - * flags|PyBUF_F_CONTIGUOUS, - */ - __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), ((char *)"fortran"), __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 653, __pyx_L1_error) - __pyx_v_dst = __pyx_t_1; - - /* "View.MemoryView":658 - * self.dtype_is_object) - * - * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 658, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":648 - * return memoryview_copy_from_slice(self, &mslice) - * - * def copy_fortran(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice src, dst - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryview_1__reduce_cython__(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*/ -static PyObject *__pyx_pw___pyx_memoryview_1__reduce_cython__(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 -) { - #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("__reduce_cython__ (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); - if (unlikely(__pyx_nargs > 0)) { - __Pyx_RaiseArgtupleInvalid("__reduce_cython__", 1, 0, 0, __pyx_nargs); return NULL;} - if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__reduce_cython__", 0))) return NULL; - __pyx_r = __pyx_pf___pyx_memoryview___reduce_cython__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_memoryview___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 1); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); - __PYX_ERR(1, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView.memoryview.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryview_3__setstate_cython__(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*/ -static PyObject *__pyx_pw___pyx_memoryview_3__setstate_cython__(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 -) { - CYTHON_UNUSED PyObject *__pyx_v___pyx_state = 0; - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[1] = {0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (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_pyx_state,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - 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_pyx_state)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 3, __pyx_L3_error) - else goto __pyx_L5_argtuple_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, "__setstate_cython__") < 0)) __PYX_ERR(1, 3, __pyx_L3_error) - } - } else if (unlikely(__pyx_nargs != 1)) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - } - __pyx_v___pyx_state = values[0]; - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__setstate_cython__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 3, __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("View.MemoryView.memoryview.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf___pyx_memoryview_2__setstate_cython__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v___pyx_state); - - /* 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___pyx_memoryview_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 1); - - /* "(tree fragment)":4 - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< - */ - __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); - __PYX_ERR(1, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView.memoryview.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":662 - * - * @cname('__pyx_memoryview_new') - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<< - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo - */ - -static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) { - struct __pyx_memoryview_obj *__pyx_v_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_cwrapper", 1); - - /* "View.MemoryView":663 - * @cname('__pyx_memoryview_new') - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): - * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<< - * result.typeinfo = typeinfo - * return result - */ - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 663, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 663, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 663, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_o); - __Pyx_GIVEREF(__pyx_v_o); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o)) __PYX_ERR(1, 663, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_1); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1)) __PYX_ERR(1, 663, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_2); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2)) __PYX_ERR(1, 663, __pyx_L1_error); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 663, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2); - __pyx_t_2 = 0; - - /* "View.MemoryView":664 - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo # <<<<<<<<<<<<<< - * return result - * - */ - __pyx_v_result->typeinfo = __pyx_v_typeinfo; - - /* "View.MemoryView":665 - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo - * return result # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_check') - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF((PyObject *)__pyx_v_result); - __pyx_r = ((PyObject *)__pyx_v_result); - goto __pyx_L0; - - /* "View.MemoryView":662 - * - * @cname('__pyx_memoryview_new') - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<< - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":668 - * - * @cname('__pyx_memoryview_check') - * cdef inline bint memoryview_check(object o) noexcept: # <<<<<<<<<<<<<< - * return isinstance(o, memoryview) - * - */ - -static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) { - int __pyx_r; - int __pyx_t_1; - - /* "View.MemoryView":669 - * @cname('__pyx_memoryview_check') - * cdef inline bint memoryview_check(object o) noexcept: - * return isinstance(o, memoryview) # <<<<<<<<<<<<<< - * - * cdef tuple _unellipsify(object index, int ndim): - */ - __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, __pyx_memoryview_type); - __pyx_r = __pyx_t_1; - goto __pyx_L0; - - /* "View.MemoryView":668 - * - * @cname('__pyx_memoryview_check') - * cdef inline bint memoryview_check(object o) noexcept: # <<<<<<<<<<<<<< - * return isinstance(o, memoryview) - * - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":671 - * return isinstance(o, memoryview) - * - * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<< - * """ - * Replace all ellipses with full slices and fill incomplete indices with - */ - -static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) { - Py_ssize_t __pyx_v_idx; - PyObject *__pyx_v_tup = NULL; - PyObject *__pyx_v_result = NULL; - int __pyx_v_have_slices; - int __pyx_v_seen_ellipsis; - PyObject *__pyx_v_item = NULL; - Py_ssize_t __pyx_v_nslices; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - Py_ssize_t __pyx_t_4; - Py_ssize_t __pyx_t_5; - Py_UCS4 __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_unellipsify", 1); - - /* "View.MemoryView":677 - * """ - * cdef Py_ssize_t idx - * tup = index if isinstance(index, tuple) else (index,) # <<<<<<<<<<<<<< - * - * result = [slice(None)] * ndim - */ - __pyx_t_2 = PyTuple_Check(__pyx_v_index); - if (__pyx_t_2) { - __Pyx_INCREF(((PyObject*)__pyx_v_index)); - __pyx_t_1 = __pyx_v_index; - } else { - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 677, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_index); - __Pyx_GIVEREF(__pyx_v_index); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index)) __PYX_ERR(1, 677, __pyx_L1_error); - __pyx_t_1 = __pyx_t_3; - __pyx_t_3 = 0; - } - __pyx_v_tup = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "View.MemoryView":679 - * tup = index if isinstance(index, tuple) else (index,) - * - * result = [slice(None)] * ndim # <<<<<<<<<<<<<< - * have_slices = False - * seen_ellipsis = False - */ - __pyx_t_1 = PyList_New(1 * ((__pyx_v_ndim<0) ? 0:__pyx_v_ndim)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 679, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - { Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < __pyx_v_ndim; __pyx_temp++) { - __Pyx_INCREF(__pyx_slice__5); - __Pyx_GIVEREF(__pyx_slice__5); - if (__Pyx_PyList_SET_ITEM(__pyx_t_1, __pyx_temp, __pyx_slice__5)) __PYX_ERR(1, 679, __pyx_L1_error); - } - } - __pyx_v_result = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "View.MemoryView":680 - * - * result = [slice(None)] * ndim - * have_slices = False # <<<<<<<<<<<<<< - * seen_ellipsis = False - * idx = 0 - */ - __pyx_v_have_slices = 0; - - /* "View.MemoryView":681 - * result = [slice(None)] * ndim - * have_slices = False - * seen_ellipsis = False # <<<<<<<<<<<<<< - * idx = 0 - * for item in tup: - */ - __pyx_v_seen_ellipsis = 0; - - /* "View.MemoryView":682 - * have_slices = False - * seen_ellipsis = False - * idx = 0 # <<<<<<<<<<<<<< - * for item in tup: - * if item is Ellipsis: - */ - __pyx_v_idx = 0; - - /* "View.MemoryView":683 - * seen_ellipsis = False - * idx = 0 - * for item in tup: # <<<<<<<<<<<<<< - * if item is Ellipsis: - * if not seen_ellipsis: - */ - if (unlikely(__pyx_v_tup == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); - __PYX_ERR(1, 683, __pyx_L1_error) - } - __pyx_t_1 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_1); - __pyx_t_4 = 0; - for (;;) { - { - Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); - #if !CYTHON_ASSUME_SAFE_MACROS - if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 683, __pyx_L1_error) - #endif - if (__pyx_t_4 >= __pyx_temp) break; - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_4); __Pyx_INCREF(__pyx_t_3); __pyx_t_4++; if (unlikely((0 < 0))) __PYX_ERR(1, 683, __pyx_L1_error) - #else - __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 683, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":684 - * idx = 0 - * for item in tup: - * if item is Ellipsis: # <<<<<<<<<<<<<< - * if not seen_ellipsis: - * idx += ndim - len(tup) - */ - __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis); - if (__pyx_t_2) { - - /* "View.MemoryView":685 - * for item in tup: - * if item is Ellipsis: - * if not seen_ellipsis: # <<<<<<<<<<<<<< - * idx += ndim - len(tup) - * seen_ellipsis = True - */ - __pyx_t_2 = (!__pyx_v_seen_ellipsis); - if (__pyx_t_2) { - - /* "View.MemoryView":686 - * if item is Ellipsis: - * if not seen_ellipsis: - * idx += ndim - len(tup) # <<<<<<<<<<<<<< - * seen_ellipsis = True - * have_slices = True - */ - if (unlikely(__pyx_v_tup == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 686, __pyx_L1_error) - } - __pyx_t_5 = __Pyx_PyTuple_GET_SIZE(__pyx_v_tup); if (unlikely(__pyx_t_5 == ((Py_ssize_t)-1))) __PYX_ERR(1, 686, __pyx_L1_error) - __pyx_v_idx = (__pyx_v_idx + (__pyx_v_ndim - __pyx_t_5)); - - /* "View.MemoryView":687 - * if not seen_ellipsis: - * idx += ndim - len(tup) - * seen_ellipsis = True # <<<<<<<<<<<<<< - * have_slices = True - * else: - */ - __pyx_v_seen_ellipsis = 1; - - /* "View.MemoryView":685 - * for item in tup: - * if item is Ellipsis: - * if not seen_ellipsis: # <<<<<<<<<<<<<< - * idx += ndim - len(tup) - * seen_ellipsis = True - */ - } - - /* "View.MemoryView":688 - * idx += ndim - len(tup) - * seen_ellipsis = True - * have_slices = True # <<<<<<<<<<<<<< - * else: - * if isinstance(item, slice): - */ - __pyx_v_have_slices = 1; - - /* "View.MemoryView":684 - * idx = 0 - * for item in tup: - * if item is Ellipsis: # <<<<<<<<<<<<<< - * if not seen_ellipsis: - * idx += ndim - len(tup) - */ - goto __pyx_L5; - } - - /* "View.MemoryView":690 - * have_slices = True - * else: - * if isinstance(item, slice): # <<<<<<<<<<<<<< - * have_slices = True - * elif not PyIndex_Check(item): - */ - /*else*/ { - __pyx_t_2 = PySlice_Check(__pyx_v_item); - if (__pyx_t_2) { - - /* "View.MemoryView":691 - * else: - * if isinstance(item, slice): - * have_slices = True # <<<<<<<<<<<<<< - * elif not PyIndex_Check(item): - * raise TypeError, f"Cannot index with type '{type(item)}'" - */ - __pyx_v_have_slices = 1; - - /* "View.MemoryView":690 - * have_slices = True - * else: - * if isinstance(item, slice): # <<<<<<<<<<<<<< - * have_slices = True - * elif not PyIndex_Check(item): - */ - goto __pyx_L7; - } - - /* "View.MemoryView":692 - * if isinstance(item, slice): - * have_slices = True - * elif not PyIndex_Check(item): # <<<<<<<<<<<<<< - * raise TypeError, f"Cannot index with type '{type(item)}'" - * result[idx] = item - */ - __pyx_t_2 = (!(PyIndex_Check(__pyx_v_item) != 0)); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":693 - * have_slices = True - * elif not PyIndex_Check(item): - * raise TypeError, f"Cannot index with type '{type(item)}'" # <<<<<<<<<<<<<< - * result[idx] = item - * idx += 1 - */ - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 693, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = 0; - __pyx_t_6 = 127; - __Pyx_INCREF(__pyx_kp_u_Cannot_index_with_type); - __pyx_t_5 += 24; - __Pyx_GIVEREF(__pyx_kp_u_Cannot_index_with_type); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Cannot_index_with_type); - __pyx_t_7 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_item)), __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 693, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_6; - __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_7); - __pyx_t_7 = 0; - __Pyx_INCREF(__pyx_kp_u__6); - __pyx_t_5 += 1; - __Pyx_GIVEREF(__pyx_kp_u__6); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__6); - __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 693, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_builtin_TypeError, __pyx_t_7, 0, 0); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __PYX_ERR(1, 693, __pyx_L1_error) - - /* "View.MemoryView":692 - * if isinstance(item, slice): - * have_slices = True - * elif not PyIndex_Check(item): # <<<<<<<<<<<<<< - * raise TypeError, f"Cannot index with type '{type(item)}'" - * result[idx] = item - */ - } - __pyx_L7:; - - /* "View.MemoryView":694 - * elif not PyIndex_Check(item): - * raise TypeError, f"Cannot index with type '{type(item)}'" - * result[idx] = item # <<<<<<<<<<<<<< - * idx += 1 - * - */ - if (unlikely((__Pyx_SetItemInt(__pyx_v_result, __pyx_v_idx, __pyx_v_item, Py_ssize_t, 1, PyInt_FromSsize_t, 1, 1, 1) < 0))) __PYX_ERR(1, 694, __pyx_L1_error) - } - __pyx_L5:; - - /* "View.MemoryView":695 - * raise TypeError, f"Cannot index with type '{type(item)}'" - * result[idx] = item - * idx += 1 # <<<<<<<<<<<<<< - * - * nslices = ndim - idx - */ - __pyx_v_idx = (__pyx_v_idx + 1); - - /* "View.MemoryView":683 - * seen_ellipsis = False - * idx = 0 - * for item in tup: # <<<<<<<<<<<<<< - * if item is Ellipsis: - * if not seen_ellipsis: - */ - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "View.MemoryView":697 - * idx += 1 - * - * nslices = ndim - idx # <<<<<<<<<<<<<< - * return have_slices or nslices, tuple(result) - * - */ - __pyx_v_nslices = (__pyx_v_ndim - __pyx_v_idx); - - /* "View.MemoryView":698 - * - * nslices = ndim - idx - * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<< - * - * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: - */ - __Pyx_XDECREF(__pyx_r); - if (!__pyx_v_have_slices) { - } else { - __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 698, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_1 = __pyx_t_7; - __pyx_t_7 = 0; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_7 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 698, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_1 = __pyx_t_7; - __pyx_t_7 = 0; - __pyx_L9_bool_binop_done:; - __pyx_t_7 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 698, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 698, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(1, 698, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_7); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_7)) __PYX_ERR(1, 698, __pyx_L1_error); - __pyx_t_1 = 0; - __pyx_t_7 = 0; - __pyx_r = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "View.MemoryView":671 - * return isinstance(o, memoryview) - * - * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<< - * """ - * Replace all ellipses with full slices and fill incomplete indices with - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_tup); - __Pyx_XDECREF(__pyx_v_result); - __Pyx_XDECREF(__pyx_v_item); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":700 - * return have_slices or nslices, tuple(result) - * - * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: # <<<<<<<<<<<<<< - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: - */ - -static int assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) { - Py_ssize_t __pyx_v_suboffset; - int __pyx_r; - Py_ssize_t *__pyx_t_1; - Py_ssize_t *__pyx_t_2; - Py_ssize_t *__pyx_t_3; - int __pyx_t_4; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - - /* "View.MemoryView":701 - * - * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: - * for suboffset in suboffsets[:ndim]: # <<<<<<<<<<<<<< - * if suboffset >= 0: - * raise ValueError, "Indirect dimensions not supported" - */ - __pyx_t_2 = (__pyx_v_suboffsets + __pyx_v_ndim); - for (__pyx_t_3 = __pyx_v_suboffsets; __pyx_t_3 < __pyx_t_2; __pyx_t_3++) { - __pyx_t_1 = __pyx_t_3; - __pyx_v_suboffset = (__pyx_t_1[0]); - - /* "View.MemoryView":702 - * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * raise ValueError, "Indirect dimensions not supported" - * return 0 # return type just used as an error flag - */ - __pyx_t_4 = (__pyx_v_suboffset >= 0); - if (unlikely(__pyx_t_4)) { - - /* "View.MemoryView":703 - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: - * raise ValueError, "Indirect dimensions not supported" # <<<<<<<<<<<<<< - * return 0 # return type just used as an error flag - * - */ - __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_s_Indirect_dimensions_not_supporte, 0, 0); - __PYX_ERR(1, 703, __pyx_L1_error) - - /* "View.MemoryView":702 - * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * raise ValueError, "Indirect dimensions not supported" - * return 0 # return type just used as an error flag - */ - } - } - - /* "View.MemoryView":704 - * if suboffset >= 0: - * raise ValueError, "Indirect dimensions not supported" - * return 0 # return type just used as an error flag # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":700 - * return have_slices or nslices, tuple(result) - * - * cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1: # <<<<<<<<<<<<<< - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":711 - * - * @cname('__pyx_memview_slice') - * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<< - * cdef int new_ndim = 0, suboffset_dim = -1, dim - * cdef bint negative_step - */ - -static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) { - int __pyx_v_new_ndim; - int __pyx_v_suboffset_dim; - int __pyx_v_dim; - __Pyx_memviewslice __pyx_v_src; - __Pyx_memviewslice __pyx_v_dst; - __Pyx_memviewslice *__pyx_v_p_src; - struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0; - __Pyx_memviewslice *__pyx_v_p_dst; - int *__pyx_v_p_suboffset_dim; - Py_ssize_t __pyx_v_start; - Py_ssize_t __pyx_v_stop; - Py_ssize_t __pyx_v_step; - Py_ssize_t __pyx_v_cindex; - int __pyx_v_have_start; - int __pyx_v_have_stop; - int __pyx_v_have_step; - PyObject *__pyx_v_index = NULL; - struct __pyx_memoryview_obj *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - struct __pyx_memoryview_obj *__pyx_t_3; - char *__pyx_t_4; - int __pyx_t_5; - Py_ssize_t __pyx_t_6; - PyObject *(*__pyx_t_7)(PyObject *); - PyObject *__pyx_t_8 = NULL; - Py_ssize_t __pyx_t_9; - int __pyx_t_10; - Py_ssize_t __pyx_t_11; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memview_slice", 1); - - /* "View.MemoryView":712 - * @cname('__pyx_memview_slice') - * cdef memoryview memview_slice(memoryview memview, object indices): - * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<< - * cdef bint negative_step - * cdef __Pyx_memviewslice src, dst - */ - __pyx_v_new_ndim = 0; - __pyx_v_suboffset_dim = -1; - - /* "View.MemoryView":719 - * - * - * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<< - * - * cdef _memoryviewslice memviewsliceobj - */ - (void)(memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)))); - - /* "View.MemoryView":723 - * cdef _memoryviewslice memviewsliceobj - * - * assert memview.view.ndim > 0 # <<<<<<<<<<<<<< - * - * if isinstance(memview, _memoryviewslice): - */ - #ifndef CYTHON_WITHOUT_ASSERTIONS - if (unlikely(__pyx_assertions_enabled())) { - __pyx_t_1 = (__pyx_v_memview->view.ndim > 0); - if (unlikely(!__pyx_t_1)) { - __Pyx_Raise(__pyx_builtin_AssertionError, 0, 0, 0); - __PYX_ERR(1, 723, __pyx_L1_error) - } - } - #else - if ((1)); else __PYX_ERR(1, 723, __pyx_L1_error) - #endif - - /* "View.MemoryView":725 - * assert memview.view.ndim > 0 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * memviewsliceobj = memview - * p_src = &memviewsliceobj.from_slice - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - if (__pyx_t_1) { - - /* "View.MemoryView":726 - * - * if isinstance(memview, _memoryviewslice): - * memviewsliceobj = memview # <<<<<<<<<<<<<< - * p_src = &memviewsliceobj.from_slice - * else: - */ - if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) __PYX_ERR(1, 726, __pyx_L1_error) - __pyx_t_2 = ((PyObject *)__pyx_v_memview); - __Pyx_INCREF(__pyx_t_2); - __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2); - __pyx_t_2 = 0; - - /* "View.MemoryView":727 - * if isinstance(memview, _memoryviewslice): - * memviewsliceobj = memview - * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<< - * else: - * slice_copy(memview, &src) - */ - __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice); - - /* "View.MemoryView":725 - * assert memview.view.ndim > 0 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * memviewsliceobj = memview - * p_src = &memviewsliceobj.from_slice - */ - goto __pyx_L3; - } - - /* "View.MemoryView":729 - * p_src = &memviewsliceobj.from_slice - * else: - * slice_copy(memview, &src) # <<<<<<<<<<<<<< - * p_src = &src - * - */ - /*else*/ { - __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src)); - - /* "View.MemoryView":730 - * else: - * slice_copy(memview, &src) - * p_src = &src # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_p_src = (&__pyx_v_src); - } - __pyx_L3:; - - /* "View.MemoryView":736 - * - * - * dst.memview = p_src.memview # <<<<<<<<<<<<<< - * dst.data = p_src.data - * - */ - __pyx_t_3 = __pyx_v_p_src->memview; - __pyx_v_dst.memview = __pyx_t_3; - - /* "View.MemoryView":737 - * - * dst.memview = p_src.memview - * dst.data = p_src.data # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_4 = __pyx_v_p_src->data; - __pyx_v_dst.data = __pyx_t_4; - - /* "View.MemoryView":742 - * - * - * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<< - * cdef int *p_suboffset_dim = &suboffset_dim - * cdef Py_ssize_t start, stop, step, cindex - */ - __pyx_v_p_dst = (&__pyx_v_dst); - - /* "View.MemoryView":743 - * - * cdef __Pyx_memviewslice *p_dst = &dst - * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<< - * cdef Py_ssize_t start, stop, step, cindex - * cdef bint have_start, have_stop, have_step - */ - __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim); - - /* "View.MemoryView":747 - * cdef bint have_start, have_stop, have_step - * - * for dim, index in enumerate(indices): # <<<<<<<<<<<<<< - * if PyIndex_Check(index): - * cindex = index - */ - __pyx_t_5 = 0; - if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) { - __pyx_t_2 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_2); - __pyx_t_6 = 0; - __pyx_t_7 = NULL; - } else { - __pyx_t_6 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 747, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 747, __pyx_L1_error) - } - for (;;) { - if (likely(!__pyx_t_7)) { - if (likely(PyList_CheckExact(__pyx_t_2))) { - { - Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); - #if !CYTHON_ASSUME_SAFE_MACROS - if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 747, __pyx_L1_error) - #endif - if (__pyx_t_6 >= __pyx_temp) break; - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_8 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_t_8); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(1, 747, __pyx_L1_error) - #else - __pyx_t_8 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 747, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - #endif - } else { - { - Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2); - #if !CYTHON_ASSUME_SAFE_MACROS - if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 747, __pyx_L1_error) - #endif - if (__pyx_t_6 >= __pyx_temp) break; - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_t_8); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(1, 747, __pyx_L1_error) - #else - __pyx_t_8 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 747, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - #endif - } - } else { - __pyx_t_8 = __pyx_t_7(__pyx_t_2); - if (unlikely(!__pyx_t_8)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(1, 747, __pyx_L1_error) - } - break; - } - __Pyx_GOTREF(__pyx_t_8); - } - __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_8); - __pyx_t_8 = 0; - __pyx_v_dim = __pyx_t_5; - __pyx_t_5 = (__pyx_t_5 + 1); - - /* "View.MemoryView":748 - * - * for dim, index in enumerate(indices): - * if PyIndex_Check(index): # <<<<<<<<<<<<<< - * cindex = index - * slice_memviewslice( - */ - __pyx_t_1 = (PyIndex_Check(__pyx_v_index) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":749 - * for dim, index in enumerate(indices): - * if PyIndex_Check(index): - * cindex = index # <<<<<<<<<<<<<< - * slice_memviewslice( - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - */ - __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 749, __pyx_L1_error) - __pyx_v_cindex = __pyx_t_9; - - /* "View.MemoryView":750 - * if PyIndex_Check(index): - * cindex = index - * slice_memviewslice( # <<<<<<<<<<<<<< - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - * dim, new_ndim, p_suboffset_dim, - */ - __pyx_t_10 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_cindex, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(1, 750, __pyx_L1_error) - - /* "View.MemoryView":748 - * - * for dim, index in enumerate(indices): - * if PyIndex_Check(index): # <<<<<<<<<<<<<< - * cindex = index - * slice_memviewslice( - */ - goto __pyx_L6; - } - - /* "View.MemoryView":756 - * 0, 0, 0, # have_{start,stop,step} - * False) - * elif index is None: # <<<<<<<<<<<<<< - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 - */ - __pyx_t_1 = (__pyx_v_index == Py_None); - if (__pyx_t_1) { - - /* "View.MemoryView":757 - * False) - * elif index is None: - * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<< - * p_dst.strides[new_ndim] = 0 - * p_dst.suboffsets[new_ndim] = -1 - */ - (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1; - - /* "View.MemoryView":758 - * elif index is None: - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<< - * p_dst.suboffsets[new_ndim] = -1 - * new_ndim += 1 - */ - (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0; - - /* "View.MemoryView":759 - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 - * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<< - * new_ndim += 1 - * else: - */ - (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1L; - - /* "View.MemoryView":760 - * p_dst.strides[new_ndim] = 0 - * p_dst.suboffsets[new_ndim] = -1 - * new_ndim += 1 # <<<<<<<<<<<<<< - * else: - * start = index.start or 0 - */ - __pyx_v_new_ndim = (__pyx_v_new_ndim + 1); - - /* "View.MemoryView":756 - * 0, 0, 0, # have_{start,stop,step} - * False) - * elif index is None: # <<<<<<<<<<<<<< - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 - */ - goto __pyx_L6; - } - - /* "View.MemoryView":762 - * new_ndim += 1 - * else: - * start = index.start or 0 # <<<<<<<<<<<<<< - * stop = index.stop or 0 - * step = index.step or 0 - */ - /*else*/ { - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 762, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 762, __pyx_L1_error) - if (!__pyx_t_1) { - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - } else { - __pyx_t_11 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_11 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 762, __pyx_L1_error) - __pyx_t_9 = __pyx_t_11; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - goto __pyx_L7_bool_binop_done; - } - __pyx_t_9 = 0; - __pyx_L7_bool_binop_done:; - __pyx_v_start = __pyx_t_9; - - /* "View.MemoryView":763 - * else: - * start = index.start or 0 - * stop = index.stop or 0 # <<<<<<<<<<<<<< - * step = index.step or 0 - * - */ - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 763, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 763, __pyx_L1_error) - if (!__pyx_t_1) { - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - } else { - __pyx_t_11 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_11 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 763, __pyx_L1_error) - __pyx_t_9 = __pyx_t_11; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_9 = 0; - __pyx_L9_bool_binop_done:; - __pyx_v_stop = __pyx_t_9; - - /* "View.MemoryView":764 - * start = index.start or 0 - * stop = index.stop or 0 - * step = index.step or 0 # <<<<<<<<<<<<<< - * - * have_start = index.start is not None - */ - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 764, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(1, 764, __pyx_L1_error) - if (!__pyx_t_1) { - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - } else { - __pyx_t_11 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_11 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(1, 764, __pyx_L1_error) - __pyx_t_9 = __pyx_t_11; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - goto __pyx_L11_bool_binop_done; - } - __pyx_t_9 = 0; - __pyx_L11_bool_binop_done:; - __pyx_v_step = __pyx_t_9; - - /* "View.MemoryView":766 - * step = index.step or 0 - * - * have_start = index.start is not None # <<<<<<<<<<<<<< - * have_stop = index.stop is not None - * have_step = index.step is not None - */ - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 766, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_1 = (__pyx_t_8 != Py_None); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __pyx_v_have_start = __pyx_t_1; - - /* "View.MemoryView":767 - * - * have_start = index.start is not None - * have_stop = index.stop is not None # <<<<<<<<<<<<<< - * have_step = index.step is not None - * - */ - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 767, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_1 = (__pyx_t_8 != Py_None); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __pyx_v_have_stop = __pyx_t_1; - - /* "View.MemoryView":768 - * have_start = index.start is not None - * have_stop = index.stop is not None - * have_step = index.step is not None # <<<<<<<<<<<<<< - * - * slice_memviewslice( - */ - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 768, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_1 = (__pyx_t_8 != Py_None); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __pyx_v_have_step = __pyx_t_1; - - /* "View.MemoryView":770 - * have_step = index.step is not None - * - * slice_memviewslice( # <<<<<<<<<<<<<< - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - * dim, new_ndim, p_suboffset_dim, - */ - __pyx_t_10 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(1, 770, __pyx_L1_error) - - /* "View.MemoryView":776 - * have_start, have_stop, have_step, - * True) - * new_ndim += 1 # <<<<<<<<<<<<<< - * - * if isinstance(memview, _memoryviewslice): - */ - __pyx_v_new_ndim = (__pyx_v_new_ndim + 1); - } - __pyx_L6:; - - /* "View.MemoryView":747 - * cdef bint have_start, have_stop, have_step - * - * for dim, index in enumerate(indices): # <<<<<<<<<<<<<< - * if PyIndex_Check(index): - * cindex = index - */ - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "View.MemoryView":778 - * new_ndim += 1 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - if (__pyx_t_1) { - - /* "View.MemoryView":779 - * - * if isinstance(memview, _memoryviewslice): - * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<< - * memviewsliceobj.to_object_func, - * memviewsliceobj.to_dtype_func, - */ - __Pyx_XDECREF((PyObject *)__pyx_r); - - /* "View.MemoryView":780 - * if isinstance(memview, _memoryviewslice): - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<< - * memviewsliceobj.to_dtype_func, - * memview.dtype_is_object) - */ - if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); __PYX_ERR(1, 780, __pyx_L1_error) } - - /* "View.MemoryView":781 - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, - * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<< - * memview.dtype_is_object) - * else: - */ - if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); __PYX_ERR(1, 781, __pyx_L1_error) } - - /* "View.MemoryView":779 - * - * if isinstance(memview, _memoryviewslice): - * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<< - * memviewsliceobj.to_object_func, - * memviewsliceobj.to_dtype_func, - */ - __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 779, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_memoryview_type))))) __PYX_ERR(1, 779, __pyx_L1_error) - __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_2); - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":778 - * new_ndim += 1 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, - */ - } - - /* "View.MemoryView":784 - * memview.dtype_is_object) - * else: - * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<< - * memview.dtype_is_object) - * - */ - /*else*/ { - __Pyx_XDECREF((PyObject *)__pyx_r); - - /* "View.MemoryView":785 - * else: - * return memoryview_fromslice(dst, new_ndim, NULL, NULL, - * memview.dtype_is_object) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 784, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - - /* "View.MemoryView":784 - * memview.dtype_is_object) - * else: - * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<< - * memview.dtype_is_object) - * - */ - if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_memoryview_type))))) __PYX_ERR(1, 784, __pyx_L1_error) - __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_2); - __pyx_t_2 = 0; - goto __pyx_L0; - } - - /* "View.MemoryView":711 - * - * @cname('__pyx_memview_slice') - * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<< - * cdef int new_ndim = 0, suboffset_dim = -1, dim - * cdef bint negative_step - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj); - __Pyx_XDECREF(__pyx_v_index); - __Pyx_XGIVEREF((PyObject *)__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":793 - * - * @cname('__pyx_memoryview_slice_memviewslice') - * cdef int slice_memviewslice( # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, - */ - -static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) { - Py_ssize_t __pyx_v_new_shape; - int __pyx_v_negative_step; - int __pyx_r; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save; - #endif - - /* "View.MemoryView":813 - * cdef bint negative_step - * - * if not is_slice: # <<<<<<<<<<<<<< - * - * if start < 0: - */ - __pyx_t_1 = (!__pyx_v_is_slice); - if (__pyx_t_1) { - - /* "View.MemoryView":815 - * if not is_slice: - * - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if not 0 <= start < shape: - */ - __pyx_t_1 = (__pyx_v_start < 0); - if (__pyx_t_1) { - - /* "View.MemoryView":816 - * - * if start < 0: - * start += shape # <<<<<<<<<<<<<< - * if not 0 <= start < shape: - * _err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim) - */ - __pyx_v_start = (__pyx_v_start + __pyx_v_shape); - - /* "View.MemoryView":815 - * if not is_slice: - * - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if not 0 <= start < shape: - */ - } - - /* "View.MemoryView":817 - * if start < 0: - * start += shape - * if not 0 <= start < shape: # <<<<<<<<<<<<<< - * _err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim) - * else: - */ - __pyx_t_1 = (0 <= __pyx_v_start); - if (__pyx_t_1) { - __pyx_t_1 = (__pyx_v_start < __pyx_v_shape); - } - __pyx_t_2 = (!__pyx_t_1); - if (__pyx_t_2) { - - /* "View.MemoryView":818 - * start += shape - * if not 0 <= start < shape: - * _err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<< - * else: - * - */ - __pyx_t_3 = __pyx_memoryview_err_dim(PyExc_IndexError, __pyx_kp_s_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(1, 818, __pyx_L1_error) - - /* "View.MemoryView":817 - * if start < 0: - * start += shape - * if not 0 <= start < shape: # <<<<<<<<<<<<<< - * _err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim) - * else: - */ - } - - /* "View.MemoryView":813 - * cdef bint negative_step - * - * if not is_slice: # <<<<<<<<<<<<<< - * - * if start < 0: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":821 - * else: - * - * if have_step: # <<<<<<<<<<<<<< - * negative_step = step < 0 - * if step == 0: - */ - /*else*/ { - __pyx_t_2 = (__pyx_v_have_step != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":822 - * - * if have_step: - * negative_step = step < 0 # <<<<<<<<<<<<<< - * if step == 0: - * _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim) - */ - __pyx_v_negative_step = (__pyx_v_step < 0); - - /* "View.MemoryView":823 - * if have_step: - * negative_step = step < 0 - * if step == 0: # <<<<<<<<<<<<<< - * _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim) - * else: - */ - __pyx_t_2 = (__pyx_v_step == 0); - if (__pyx_t_2) { - - /* "View.MemoryView":824 - * negative_step = step < 0 - * if step == 0: - * _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<< - * else: - * negative_step = False - */ - __pyx_t_3 = __pyx_memoryview_err_dim(PyExc_ValueError, __pyx_kp_s_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(1, 824, __pyx_L1_error) - - /* "View.MemoryView":823 - * if have_step: - * negative_step = step < 0 - * if step == 0: # <<<<<<<<<<<<<< - * _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim) - * else: - */ - } - - /* "View.MemoryView":821 - * else: - * - * if have_step: # <<<<<<<<<<<<<< - * negative_step = step < 0 - * if step == 0: - */ - goto __pyx_L6; - } - - /* "View.MemoryView":826 - * _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim) - * else: - * negative_step = False # <<<<<<<<<<<<<< - * step = 1 - * - */ - /*else*/ { - __pyx_v_negative_step = 0; - - /* "View.MemoryView":827 - * else: - * negative_step = False - * step = 1 # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_step = 1; - } - __pyx_L6:; - - /* "View.MemoryView":830 - * - * - * if have_start: # <<<<<<<<<<<<<< - * if start < 0: - * start += shape - */ - __pyx_t_2 = (__pyx_v_have_start != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":831 - * - * if have_start: - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if start < 0: - */ - __pyx_t_2 = (__pyx_v_start < 0); - if (__pyx_t_2) { - - /* "View.MemoryView":832 - * if have_start: - * if start < 0: - * start += shape # <<<<<<<<<<<<<< - * if start < 0: - * start = 0 - */ - __pyx_v_start = (__pyx_v_start + __pyx_v_shape); - - /* "View.MemoryView":833 - * if start < 0: - * start += shape - * if start < 0: # <<<<<<<<<<<<<< - * start = 0 - * elif start >= shape: - */ - __pyx_t_2 = (__pyx_v_start < 0); - if (__pyx_t_2) { - - /* "View.MemoryView":834 - * start += shape - * if start < 0: - * start = 0 # <<<<<<<<<<<<<< - * elif start >= shape: - * if negative_step: - */ - __pyx_v_start = 0; - - /* "View.MemoryView":833 - * if start < 0: - * start += shape - * if start < 0: # <<<<<<<<<<<<<< - * start = 0 - * elif start >= shape: - */ - } - - /* "View.MemoryView":831 - * - * if have_start: - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if start < 0: - */ - goto __pyx_L9; - } - - /* "View.MemoryView":835 - * if start < 0: - * start = 0 - * elif start >= shape: # <<<<<<<<<<<<<< - * if negative_step: - * start = shape - 1 - */ - __pyx_t_2 = (__pyx_v_start >= __pyx_v_shape); - if (__pyx_t_2) { - - /* "View.MemoryView":836 - * start = 0 - * elif start >= shape: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: - */ - if (__pyx_v_negative_step) { - - /* "View.MemoryView":837 - * elif start >= shape: - * if negative_step: - * start = shape - 1 # <<<<<<<<<<<<<< - * else: - * start = shape - */ - __pyx_v_start = (__pyx_v_shape - 1); - - /* "View.MemoryView":836 - * start = 0 - * elif start >= shape: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: - */ - goto __pyx_L11; - } - - /* "View.MemoryView":839 - * start = shape - 1 - * else: - * start = shape # <<<<<<<<<<<<<< - * else: - * if negative_step: - */ - /*else*/ { - __pyx_v_start = __pyx_v_shape; - } - __pyx_L11:; - - /* "View.MemoryView":835 - * if start < 0: - * start = 0 - * elif start >= shape: # <<<<<<<<<<<<<< - * if negative_step: - * start = shape - 1 - */ - } - __pyx_L9:; - - /* "View.MemoryView":830 - * - * - * if have_start: # <<<<<<<<<<<<<< - * if start < 0: - * start += shape - */ - goto __pyx_L8; - } - - /* "View.MemoryView":841 - * start = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: - */ - /*else*/ { - if (__pyx_v_negative_step) { - - /* "View.MemoryView":842 - * else: - * if negative_step: - * start = shape - 1 # <<<<<<<<<<<<<< - * else: - * start = 0 - */ - __pyx_v_start = (__pyx_v_shape - 1); - - /* "View.MemoryView":841 - * start = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: - */ - goto __pyx_L12; - } - - /* "View.MemoryView":844 - * start = shape - 1 - * else: - * start = 0 # <<<<<<<<<<<<<< - * - * if have_stop: - */ - /*else*/ { - __pyx_v_start = 0; - } - __pyx_L12:; - } - __pyx_L8:; - - /* "View.MemoryView":846 - * start = 0 - * - * if have_stop: # <<<<<<<<<<<<<< - * if stop < 0: - * stop += shape - */ - __pyx_t_2 = (__pyx_v_have_stop != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":847 - * - * if have_stop: - * if stop < 0: # <<<<<<<<<<<<<< - * stop += shape - * if stop < 0: - */ - __pyx_t_2 = (__pyx_v_stop < 0); - if (__pyx_t_2) { - - /* "View.MemoryView":848 - * if have_stop: - * if stop < 0: - * stop += shape # <<<<<<<<<<<<<< - * if stop < 0: - * stop = 0 - */ - __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape); - - /* "View.MemoryView":849 - * if stop < 0: - * stop += shape - * if stop < 0: # <<<<<<<<<<<<<< - * stop = 0 - * elif stop > shape: - */ - __pyx_t_2 = (__pyx_v_stop < 0); - if (__pyx_t_2) { - - /* "View.MemoryView":850 - * stop += shape - * if stop < 0: - * stop = 0 # <<<<<<<<<<<<<< - * elif stop > shape: - * stop = shape - */ - __pyx_v_stop = 0; - - /* "View.MemoryView":849 - * if stop < 0: - * stop += shape - * if stop < 0: # <<<<<<<<<<<<<< - * stop = 0 - * elif stop > shape: - */ - } - - /* "View.MemoryView":847 - * - * if have_stop: - * if stop < 0: # <<<<<<<<<<<<<< - * stop += shape - * if stop < 0: - */ - goto __pyx_L14; - } - - /* "View.MemoryView":851 - * if stop < 0: - * stop = 0 - * elif stop > shape: # <<<<<<<<<<<<<< - * stop = shape - * else: - */ - __pyx_t_2 = (__pyx_v_stop > __pyx_v_shape); - if (__pyx_t_2) { - - /* "View.MemoryView":852 - * stop = 0 - * elif stop > shape: - * stop = shape # <<<<<<<<<<<<<< - * else: - * if negative_step: - */ - __pyx_v_stop = __pyx_v_shape; - - /* "View.MemoryView":851 - * if stop < 0: - * stop = 0 - * elif stop > shape: # <<<<<<<<<<<<<< - * stop = shape - * else: - */ - } - __pyx_L14:; - - /* "View.MemoryView":846 - * start = 0 - * - * if have_stop: # <<<<<<<<<<<<<< - * if stop < 0: - * stop += shape - */ - goto __pyx_L13; - } - - /* "View.MemoryView":854 - * stop = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * stop = -1 - * else: - */ - /*else*/ { - if (__pyx_v_negative_step) { - - /* "View.MemoryView":855 - * else: - * if negative_step: - * stop = -1 # <<<<<<<<<<<<<< - * else: - * stop = shape - */ - __pyx_v_stop = -1L; - - /* "View.MemoryView":854 - * stop = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * stop = -1 - * else: - */ - goto __pyx_L16; - } - - /* "View.MemoryView":857 - * stop = -1 - * else: - * stop = shape # <<<<<<<<<<<<<< - * - * - */ - /*else*/ { - __pyx_v_stop = __pyx_v_shape; - } - __pyx_L16:; - } - __pyx_L13:; - - /* "View.MemoryView":861 - * - * with cython.cdivision(True): - * new_shape = (stop - start) // step # <<<<<<<<<<<<<< - * - * if (stop - start) - step * new_shape: - */ - __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step); - - /* "View.MemoryView":863 - * new_shape = (stop - start) // step - * - * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<< - * new_shape += 1 - * - */ - __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":864 - * - * if (stop - start) - step * new_shape: - * new_shape += 1 # <<<<<<<<<<<<<< - * - * if new_shape < 0: - */ - __pyx_v_new_shape = (__pyx_v_new_shape + 1); - - /* "View.MemoryView":863 - * new_shape = (stop - start) // step - * - * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<< - * new_shape += 1 - * - */ - } - - /* "View.MemoryView":866 - * new_shape += 1 - * - * if new_shape < 0: # <<<<<<<<<<<<<< - * new_shape = 0 - * - */ - __pyx_t_2 = (__pyx_v_new_shape < 0); - if (__pyx_t_2) { - - /* "View.MemoryView":867 - * - * if new_shape < 0: - * new_shape = 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_new_shape = 0; - - /* "View.MemoryView":866 - * new_shape += 1 - * - * if new_shape < 0: # <<<<<<<<<<<<<< - * new_shape = 0 - * - */ - } - - /* "View.MemoryView":870 - * - * - * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<< - * dst.shape[new_ndim] = new_shape - * dst.suboffsets[new_ndim] = suboffset - */ - (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step); - - /* "View.MemoryView":871 - * - * dst.strides[new_ndim] = stride * step - * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<< - * dst.suboffsets[new_ndim] = suboffset - * - */ - (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape; - - /* "View.MemoryView":872 - * dst.strides[new_ndim] = stride * step - * dst.shape[new_ndim] = new_shape - * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<< - * - * - */ - (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset; - } - __pyx_L3:; - - /* "View.MemoryView":875 - * - * - * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<< - * dst.data += start * stride - * else: - */ - __pyx_t_2 = ((__pyx_v_suboffset_dim[0]) < 0); - if (__pyx_t_2) { - - /* "View.MemoryView":876 - * - * if suboffset_dim[0] < 0: - * dst.data += start * stride # <<<<<<<<<<<<<< - * else: - * dst.suboffsets[suboffset_dim[0]] += start * stride - */ - __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride)); - - /* "View.MemoryView":875 - * - * - * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<< - * dst.data += start * stride - * else: - */ - goto __pyx_L19; - } - - /* "View.MemoryView":878 - * dst.data += start * stride - * else: - * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<< - * - * if suboffset >= 0: - */ - /*else*/ { - __pyx_t_3 = (__pyx_v_suboffset_dim[0]); - (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride)); - } - __pyx_L19:; - - /* "View.MemoryView":880 - * dst.suboffsets[suboffset_dim[0]] += start * stride - * - * if suboffset >= 0: # <<<<<<<<<<<<<< - * if not is_slice: - * if new_ndim == 0: - */ - __pyx_t_2 = (__pyx_v_suboffset >= 0); - if (__pyx_t_2) { - - /* "View.MemoryView":881 - * - * if suboffset >= 0: - * if not is_slice: # <<<<<<<<<<<<<< - * if new_ndim == 0: - * dst.data = ( dst.data)[0] + suboffset - */ - __pyx_t_2 = (!__pyx_v_is_slice); - if (__pyx_t_2) { - - /* "View.MemoryView":882 - * if suboffset >= 0: - * if not is_slice: - * if new_ndim == 0: # <<<<<<<<<<<<<< - * dst.data = ( dst.data)[0] + suboffset - * else: - */ - __pyx_t_2 = (__pyx_v_new_ndim == 0); - if (__pyx_t_2) { - - /* "View.MemoryView":883 - * if not is_slice: - * if new_ndim == 0: - * dst.data = ( dst.data)[0] + suboffset # <<<<<<<<<<<<<< - * else: - * _err_dim(PyExc_IndexError, "All dimensions preceding dimension %d " - */ - __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset); - - /* "View.MemoryView":882 - * if suboffset >= 0: - * if not is_slice: - * if new_ndim == 0: # <<<<<<<<<<<<<< - * dst.data = ( dst.data)[0] + suboffset - * else: - */ - goto __pyx_L22; - } - - /* "View.MemoryView":885 - * dst.data = ( dst.data)[0] + suboffset - * else: - * _err_dim(PyExc_IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<< - * "must be indexed and not sliced", dim) - * else: - */ - /*else*/ { - - /* "View.MemoryView":886 - * else: - * _err_dim(PyExc_IndexError, "All dimensions preceding dimension %d " - * "must be indexed and not sliced", dim) # <<<<<<<<<<<<<< - * else: - * suboffset_dim[0] = new_ndim - */ - __pyx_t_3 = __pyx_memoryview_err_dim(PyExc_IndexError, __pyx_kp_s_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(1, 885, __pyx_L1_error) - } - __pyx_L22:; - - /* "View.MemoryView":881 - * - * if suboffset >= 0: - * if not is_slice: # <<<<<<<<<<<<<< - * if new_ndim == 0: - * dst.data = ( dst.data)[0] + suboffset - */ - goto __pyx_L21; - } - - /* "View.MemoryView":888 - * "must be indexed and not sliced", dim) - * else: - * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<< - * - * return 0 - */ - /*else*/ { - (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim; - } - __pyx_L21:; - - /* "View.MemoryView":880 - * dst.suboffsets[suboffset_dim[0]] += start * stride - * - * if suboffset >= 0: # <<<<<<<<<<<<<< - * if not is_slice: - * if new_ndim == 0: - */ - } - - /* "View.MemoryView":890 - * suboffset_dim[0] = new_ndim - * - * return 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":793 - * - * @cname('__pyx_memoryview_slice_memviewslice') - * cdef int slice_memviewslice( # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, - */ - - /* function exit code */ - __pyx_L1_error:; - #ifdef WITH_THREAD - __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":896 - * - * @cname('__pyx_pybuffer_index') - * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<< - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 - */ - -static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) { - Py_ssize_t __pyx_v_shape; - Py_ssize_t __pyx_v_stride; - Py_ssize_t __pyx_v_suboffset; - Py_ssize_t __pyx_v_itemsize; - char *__pyx_v_resultp; - char *__pyx_r; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - Py_UCS4 __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("pybuffer_index", 1); - - /* "View.MemoryView":898 - * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<< - * cdef Py_ssize_t itemsize = view.itemsize - * cdef char *resultp - */ - __pyx_v_suboffset = -1L; - - /* "View.MemoryView":899 - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 - * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<< - * cdef char *resultp - * - */ - __pyx_t_1 = __pyx_v_view->itemsize; - __pyx_v_itemsize = __pyx_t_1; - - /* "View.MemoryView":902 - * cdef char *resultp - * - * if view.ndim == 0: # <<<<<<<<<<<<<< - * shape = view.len // itemsize - * stride = itemsize - */ - __pyx_t_2 = (__pyx_v_view->ndim == 0); - if (__pyx_t_2) { - - /* "View.MemoryView":903 - * - * if view.ndim == 0: - * shape = view.len // itemsize # <<<<<<<<<<<<<< - * stride = itemsize - * else: - */ - if (unlikely(__pyx_v_itemsize == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); - __PYX_ERR(1, 903, __pyx_L1_error) - } - else if (sizeof(Py_ssize_t) == sizeof(long) && (!(((Py_ssize_t)-1) > 0)) && unlikely(__pyx_v_itemsize == (Py_ssize_t)-1) && unlikely(__Pyx_UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) { - PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); - __PYX_ERR(1, 903, __pyx_L1_error) - } - __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize); - - /* "View.MemoryView":904 - * if view.ndim == 0: - * shape = view.len // itemsize - * stride = itemsize # <<<<<<<<<<<<<< - * else: - * shape = view.shape[dim] - */ - __pyx_v_stride = __pyx_v_itemsize; - - /* "View.MemoryView":902 - * cdef char *resultp - * - * if view.ndim == 0: # <<<<<<<<<<<<<< - * shape = view.len // itemsize - * stride = itemsize - */ - goto __pyx_L3; - } - - /* "View.MemoryView":906 - * stride = itemsize - * else: - * shape = view.shape[dim] # <<<<<<<<<<<<<< - * stride = view.strides[dim] - * if view.suboffsets != NULL: - */ - /*else*/ { - __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]); - - /* "View.MemoryView":907 - * else: - * shape = view.shape[dim] - * stride = view.strides[dim] # <<<<<<<<<<<<<< - * if view.suboffsets != NULL: - * suboffset = view.suboffsets[dim] - */ - __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]); - - /* "View.MemoryView":908 - * shape = view.shape[dim] - * stride = view.strides[dim] - * if view.suboffsets != NULL: # <<<<<<<<<<<<<< - * suboffset = view.suboffsets[dim] - * - */ - __pyx_t_2 = (__pyx_v_view->suboffsets != NULL); - if (__pyx_t_2) { - - /* "View.MemoryView":909 - * stride = view.strides[dim] - * if view.suboffsets != NULL: - * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<< - * - * if index < 0: - */ - __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]); - - /* "View.MemoryView":908 - * shape = view.shape[dim] - * stride = view.strides[dim] - * if view.suboffsets != NULL: # <<<<<<<<<<<<<< - * suboffset = view.suboffsets[dim] - * - */ - } - } - __pyx_L3:; - - /* "View.MemoryView":911 - * suboffset = view.suboffsets[dim] - * - * if index < 0: # <<<<<<<<<<<<<< - * index += view.shape[dim] - * if index < 0: - */ - __pyx_t_2 = (__pyx_v_index < 0); - if (__pyx_t_2) { - - /* "View.MemoryView":912 - * - * if index < 0: - * index += view.shape[dim] # <<<<<<<<<<<<<< - * if index < 0: - * raise IndexError, f"Out of bounds on buffer access (axis {dim})" - */ - __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim])); - - /* "View.MemoryView":913 - * if index < 0: - * index += view.shape[dim] - * if index < 0: # <<<<<<<<<<<<<< - * raise IndexError, f"Out of bounds on buffer access (axis {dim})" - * - */ - __pyx_t_2 = (__pyx_v_index < 0); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":914 - * index += view.shape[dim] - * if index < 0: - * raise IndexError, f"Out of bounds on buffer access (axis {dim})" # <<<<<<<<<<<<<< - * - * if index >= shape: - */ - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 914, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = 0; - __pyx_t_4 = 127; - __Pyx_INCREF(__pyx_kp_u_Out_of_bounds_on_buffer_access_a); - __pyx_t_1 += 37; - __Pyx_GIVEREF(__pyx_kp_u_Out_of_bounds_on_buffer_access_a); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Out_of_bounds_on_buffer_access_a); - __pyx_t_5 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_dim, 0, ' ', 'd'); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 914, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5); - __pyx_t_5 = 0; - __Pyx_INCREF(__pyx_kp_u__7); - __pyx_t_1 += 1; - __Pyx_GIVEREF(__pyx_kp_u__7); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__7); - __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 914, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_builtin_IndexError, __pyx_t_5, 0, 0); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __PYX_ERR(1, 914, __pyx_L1_error) - - /* "View.MemoryView":913 - * if index < 0: - * index += view.shape[dim] - * if index < 0: # <<<<<<<<<<<<<< - * raise IndexError, f"Out of bounds on buffer access (axis {dim})" - * - */ - } - - /* "View.MemoryView":911 - * suboffset = view.suboffsets[dim] - * - * if index < 0: # <<<<<<<<<<<<<< - * index += view.shape[dim] - * if index < 0: - */ - } - - /* "View.MemoryView":916 - * raise IndexError, f"Out of bounds on buffer access (axis {dim})" - * - * if index >= shape: # <<<<<<<<<<<<<< - * raise IndexError, f"Out of bounds on buffer access (axis {dim})" - * - */ - __pyx_t_2 = (__pyx_v_index >= __pyx_v_shape); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":917 - * - * if index >= shape: - * raise IndexError, f"Out of bounds on buffer access (axis {dim})" # <<<<<<<<<<<<<< - * - * resultp = bufp + index * stride - */ - __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 917, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = 0; - __pyx_t_4 = 127; - __Pyx_INCREF(__pyx_kp_u_Out_of_bounds_on_buffer_access_a); - __pyx_t_1 += 37; - __Pyx_GIVEREF(__pyx_kp_u_Out_of_bounds_on_buffer_access_a); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_Out_of_bounds_on_buffer_access_a); - __pyx_t_3 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_dim, 0, ' ', 'd'); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 917, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_3); - __pyx_t_3 = 0; - __Pyx_INCREF(__pyx_kp_u__7); - __pyx_t_1 += 1; - __Pyx_GIVEREF(__pyx_kp_u__7); - PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u__7); - __pyx_t_3 = __Pyx_PyUnicode_Join(__pyx_t_5, 3, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 917, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_Raise(__pyx_builtin_IndexError, __pyx_t_3, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 917, __pyx_L1_error) - - /* "View.MemoryView":916 - * raise IndexError, f"Out of bounds on buffer access (axis {dim})" - * - * if index >= shape: # <<<<<<<<<<<<<< - * raise IndexError, f"Out of bounds on buffer access (axis {dim})" - * - */ - } - - /* "View.MemoryView":919 - * raise IndexError, f"Out of bounds on buffer access (axis {dim})" - * - * resultp = bufp + index * stride # <<<<<<<<<<<<<< - * if suboffset >= 0: - * resultp = ( resultp)[0] + suboffset - */ - __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride)); - - /* "View.MemoryView":920 - * - * resultp = bufp + index * stride - * if suboffset >= 0: # <<<<<<<<<<<<<< - * resultp = ( resultp)[0] + suboffset - * - */ - __pyx_t_2 = (__pyx_v_suboffset >= 0); - if (__pyx_t_2) { - - /* "View.MemoryView":921 - * resultp = bufp + index * stride - * if suboffset >= 0: - * resultp = ( resultp)[0] + suboffset # <<<<<<<<<<<<<< - * - * return resultp - */ - __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset); - - /* "View.MemoryView":920 - * - * resultp = bufp + index * stride - * if suboffset >= 0: # <<<<<<<<<<<<<< - * resultp = ( resultp)[0] + suboffset - * - */ - } - - /* "View.MemoryView":923 - * resultp = ( resultp)[0] + suboffset - * - * return resultp # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_resultp; - goto __pyx_L0; - - /* "View.MemoryView":896 - * - * @cname('__pyx_pybuffer_index') - * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<< - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":929 - * - * @cname('__pyx_memslice_transpose') - * cdef int transpose_memslice(__Pyx_memviewslice *memslice) except -1 nogil: # <<<<<<<<<<<<<< - * cdef int ndim = memslice.memview.view.ndim - * - */ - -static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) { - int __pyx_v_ndim; - Py_ssize_t *__pyx_v_shape; - Py_ssize_t *__pyx_v_strides; - int __pyx_v_i; - int __pyx_v_j; - int __pyx_r; - int __pyx_t_1; - Py_ssize_t *__pyx_t_2; - long __pyx_t_3; - long __pyx_t_4; - Py_ssize_t __pyx_t_5; - Py_ssize_t __pyx_t_6; - int __pyx_t_7; - int __pyx_t_8; - int __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save; - #endif - - /* "View.MemoryView":930 - * @cname('__pyx_memslice_transpose') - * cdef int transpose_memslice(__Pyx_memviewslice *memslice) except -1 nogil: - * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<< - * - * cdef Py_ssize_t *shape = memslice.shape - */ - __pyx_t_1 = __pyx_v_memslice->memview->view.ndim; - __pyx_v_ndim = __pyx_t_1; - - /* "View.MemoryView":932 - * cdef int ndim = memslice.memview.view.ndim - * - * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<< - * cdef Py_ssize_t *strides = memslice.strides - * - */ - __pyx_t_2 = __pyx_v_memslice->shape; - __pyx_v_shape = __pyx_t_2; - - /* "View.MemoryView":933 - * - * cdef Py_ssize_t *shape = memslice.shape - * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = __pyx_v_memslice->strides; - __pyx_v_strides = __pyx_t_2; - - /* "View.MemoryView":937 - * - * cdef int i, j - * for i in range(ndim // 2): # <<<<<<<<<<<<<< - * j = ndim - 1 - i - * strides[i], strides[j] = strides[j], strides[i] - */ - __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2); - __pyx_t_4 = __pyx_t_3; - for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_4; __pyx_t_1+=1) { - __pyx_v_i = __pyx_t_1; - - /* "View.MemoryView":938 - * cdef int i, j - * for i in range(ndim // 2): - * j = ndim - 1 - i # <<<<<<<<<<<<<< - * strides[i], strides[j] = strides[j], strides[i] - * shape[i], shape[j] = shape[j], shape[i] - */ - __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i); - - /* "View.MemoryView":939 - * for i in range(ndim // 2): - * j = ndim - 1 - i - * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<< - * shape[i], shape[j] = shape[j], shape[i] - * - */ - __pyx_t_5 = (__pyx_v_strides[__pyx_v_j]); - __pyx_t_6 = (__pyx_v_strides[__pyx_v_i]); - (__pyx_v_strides[__pyx_v_i]) = __pyx_t_5; - (__pyx_v_strides[__pyx_v_j]) = __pyx_t_6; - - /* "View.MemoryView":940 - * j = ndim - 1 - i - * strides[i], strides[j] = strides[j], strides[i] - * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<< - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: - */ - __pyx_t_6 = (__pyx_v_shape[__pyx_v_j]); - __pyx_t_5 = (__pyx_v_shape[__pyx_v_i]); - (__pyx_v_shape[__pyx_v_i]) = __pyx_t_6; - (__pyx_v_shape[__pyx_v_j]) = __pyx_t_5; - - /* "View.MemoryView":942 - * shape[i], shape[j] = shape[j], shape[i] - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<< - * _err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions") - * - */ - __pyx_t_8 = ((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0); - if (!__pyx_t_8) { - } else { - __pyx_t_7 = __pyx_t_8; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_8 = ((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0); - __pyx_t_7 = __pyx_t_8; - __pyx_L6_bool_binop_done:; - if (__pyx_t_7) { - - /* "View.MemoryView":943 - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: - * _err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<< - * - * return 0 - */ - __pyx_t_9 = __pyx_memoryview_err(PyExc_ValueError, __pyx_kp_s_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(1, 943, __pyx_L1_error) - - /* "View.MemoryView":942 - * shape[i], shape[j] = shape[j], shape[i] - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<< - * _err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions") - * - */ - } - } - - /* "View.MemoryView":945 - * _err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions") - * - * return 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":929 - * - * @cname('__pyx_memslice_transpose') - * cdef int transpose_memslice(__Pyx_memviewslice *memslice) except -1 nogil: # <<<<<<<<<<<<<< - * cdef int ndim = memslice.memview.view.ndim - * - */ - - /* function exit code */ - __pyx_L1_error:; - #ifdef WITH_THREAD - __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":963 - * cdef int (*to_dtype_func)(char *, object) except 0 - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1) - * - */ - -/* Python wrapper */ -static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) { - - /* "View.MemoryView":964 - * - * def __dealloc__(self): - * __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<< - * - * cdef convert_item_to_object(self, char *itemp): - */ - __PYX_XCLEAR_MEMVIEW((&__pyx_v_self->from_slice), 1); - - /* "View.MemoryView":963 - * cdef int (*to_dtype_func)(char *, object) except 0 - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1) - * - */ - - /* function exit code */ -} - -/* "View.MemoryView":966 - * __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1) - * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * if self.to_object_func != NULL: - * return self.to_object_func(itemp) - */ - -static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("convert_item_to_object", 1); - - /* "View.MemoryView":967 - * - * cdef convert_item_to_object(self, char *itemp): - * if self.to_object_func != NULL: # <<<<<<<<<<<<<< - * return self.to_object_func(itemp) - * else: - */ - __pyx_t_1 = (__pyx_v_self->to_object_func != NULL); - if (__pyx_t_1) { - - /* "View.MemoryView":968 - * cdef convert_item_to_object(self, char *itemp): - * if self.to_object_func != NULL: - * return self.to_object_func(itemp) # <<<<<<<<<<<<<< - * else: - * return memoryview.convert_item_to_object(self, itemp) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 968, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":967 - * - * cdef convert_item_to_object(self, char *itemp): - * if self.to_object_func != NULL: # <<<<<<<<<<<<<< - * return self.to_object_func(itemp) - * else: - */ - } - - /* "View.MemoryView":970 - * return self.to_object_func(itemp) - * else: - * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<< - * - * cdef assign_item_from_object(self, char *itemp, object value): - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 970, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - } - - /* "View.MemoryView":966 - * __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1) - * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * if self.to_object_func != NULL: - * return self.to_object_func(itemp) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":972 - * return memoryview.convert_item_to_object(self, itemp) - * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * if self.to_dtype_func != NULL: - * self.to_dtype_func(itemp, value) - */ - -static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("assign_item_from_object", 1); - - /* "View.MemoryView":973 - * - * cdef assign_item_from_object(self, char *itemp, object value): - * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<< - * self.to_dtype_func(itemp, value) - * else: - */ - __pyx_t_1 = (__pyx_v_self->to_dtype_func != NULL); - if (__pyx_t_1) { - - /* "View.MemoryView":974 - * cdef assign_item_from_object(self, char *itemp, object value): - * if self.to_dtype_func != NULL: - * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<< - * else: - * memoryview.assign_item_from_object(self, itemp, value) - */ - __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(1, 974, __pyx_L1_error) - - /* "View.MemoryView":973 - * - * cdef assign_item_from_object(self, char *itemp, object value): - * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<< - * self.to_dtype_func(itemp, value) - * else: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":976 - * self.to_dtype_func(itemp, value) - * else: - * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<< - * - * cdef _get_base(self): - */ - /*else*/ { - __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 976, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_L3:; - - /* "View.MemoryView":972 - * return memoryview.convert_item_to_object(self, itemp) - * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * if self.to_dtype_func != NULL: - * self.to_dtype_func(itemp, value) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":978 - * memoryview.assign_item_from_object(self, itemp, value) - * - * cdef _get_base(self): # <<<<<<<<<<<<<< - * return self.from_object - * - */ - -static PyObject *__pyx_memoryviewslice__get_base(struct __pyx_memoryviewslice_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_get_base", 1); - - /* "View.MemoryView":979 - * - * cdef _get_base(self): - * return self.from_object # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->from_object); - __pyx_r = __pyx_v_self->from_object; - goto __pyx_L0; - - /* "View.MemoryView":978 - * memoryview.assign_item_from_object(self, itemp, value) - * - * cdef _get_base(self): # <<<<<<<<<<<<<< - * return self.from_object - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryviewslice_1__reduce_cython__(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*/ -static PyObject *__pyx_pw___pyx_memoryviewslice_1__reduce_cython__(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 -) { - #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("__reduce_cython__ (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); - if (unlikely(__pyx_nargs > 0)) { - __Pyx_RaiseArgtupleInvalid("__reduce_cython__", 1, 0, 0, __pyx_nargs); return NULL;} - if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__reduce_cython__", 0))) return NULL; - __pyx_r = __pyx_pf___pyx_memoryviewslice___reduce_cython__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_memoryviewslice___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 1); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); - __PYX_ERR(1, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryviewslice_3__setstate_cython__(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*/ -static PyObject *__pyx_pw___pyx_memoryviewslice_3__setstate_cython__(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 -) { - CYTHON_UNUSED PyObject *__pyx_v___pyx_state = 0; - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[1] = {0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (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_pyx_state,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - 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_pyx_state)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 3, __pyx_L3_error) - else goto __pyx_L5_argtuple_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, "__setstate_cython__") < 0)) __PYX_ERR(1, 3, __pyx_L3_error) - } - } else if (unlikely(__pyx_nargs != 1)) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - } - __pyx_v___pyx_state = values[0]; - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__setstate_cython__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 3, __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("View.MemoryView._memoryviewslice.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf___pyx_memoryviewslice_2__setstate_cython__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self), __pyx_v___pyx_state); - - /* 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___pyx_memoryviewslice_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 1); - - /* "(tree fragment)":4 - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< - */ - __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); - __PYX_ERR(1, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":999 - * - * @cname('__pyx_memoryview_fromslice') - * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<< - * int ndim, - * object (*to_object_func)(char *), - */ - -static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) { - struct __pyx_memoryviewslice_obj *__pyx_v_result = 0; - Py_ssize_t __pyx_v_suboffset; - PyObject *__pyx_v_length = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - __Pyx_TypeInfo *__pyx_t_4; - Py_buffer __pyx_t_5; - Py_ssize_t *__pyx_t_6; - Py_ssize_t *__pyx_t_7; - Py_ssize_t *__pyx_t_8; - Py_ssize_t __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_fromslice", 1); - - /* "View.MemoryView":1007 - * cdef _memoryviewslice result - * - * if memviewslice.memview == Py_None: # <<<<<<<<<<<<<< - * return None - * - */ - __pyx_t_1 = (((PyObject *)__pyx_v_memviewslice.memview) == Py_None); - if (__pyx_t_1) { - - /* "View.MemoryView":1008 - * - * if memviewslice.memview == Py_None: - * return None # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - - /* "View.MemoryView":1007 - * cdef _memoryviewslice result - * - * if memviewslice.memview == Py_None: # <<<<<<<<<<<<<< - * return None - * - */ - } - - /* "View.MemoryView":1013 - * - * - * result = _memoryviewslice.__new__(_memoryviewslice, None, 0, dtype_is_object) # <<<<<<<<<<<<<< - * - * result.from_slice = memviewslice - */ - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1013, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 1013, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None)) __PYX_ERR(1, 1013, __pyx_L1_error); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0)) __PYX_ERR(1, 1013, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_2); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2)) __PYX_ERR(1, 1013, __pyx_L1_error); - __pyx_t_2 = 0; - __pyx_t_2 = ((PyObject *)__pyx_tp_new__memoryviewslice(((PyTypeObject *)__pyx_memoryviewslice_type), __pyx_t_3, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1013, __pyx_L1_error) - __Pyx_GOTREF((PyObject *)__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2); - __pyx_t_2 = 0; - - /* "View.MemoryView":1015 - * result = _memoryviewslice.__new__(_memoryviewslice, None, 0, dtype_is_object) - * - * result.from_slice = memviewslice # <<<<<<<<<<<<<< - * __PYX_INC_MEMVIEW(&memviewslice, 1) - * - */ - __pyx_v_result->from_slice = __pyx_v_memviewslice; - - /* "View.MemoryView":1016 - * - * result.from_slice = memviewslice - * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<< - * - * result.from_object = ( memviewslice.memview)._get_base() - */ - __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1); - - /* "View.MemoryView":1018 - * __PYX_INC_MEMVIEW(&memviewslice, 1) - * - * result.from_object = ( memviewslice.memview)._get_base() # <<<<<<<<<<<<<< - * result.typeinfo = memviewslice.memview.typeinfo - * - */ - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)((struct __pyx_memoryview_obj *)__pyx_v_memviewslice.memview)->__pyx_vtab)->_get_base(((struct __pyx_memoryview_obj *)__pyx_v_memviewslice.memview)); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1018, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_result->from_object); - __Pyx_DECREF(__pyx_v_result->from_object); - __pyx_v_result->from_object = __pyx_t_2; - __pyx_t_2 = 0; - - /* "View.MemoryView":1019 - * - * result.from_object = ( memviewslice.memview)._get_base() - * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<< - * - * result.view = memviewslice.memview.view - */ - __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo; - __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4; - - /* "View.MemoryView":1021 - * result.typeinfo = memviewslice.memview.typeinfo - * - * result.view = memviewslice.memview.view # <<<<<<<<<<<<<< - * result.view.buf = memviewslice.data - * result.view.ndim = ndim - */ - __pyx_t_5 = __pyx_v_memviewslice.memview->view; - __pyx_v_result->__pyx_base.view = __pyx_t_5; - - /* "View.MemoryView":1022 - * - * result.view = memviewslice.memview.view - * result.view.buf = memviewslice.data # <<<<<<<<<<<<<< - * result.view.ndim = ndim - * (<__pyx_buffer *> &result.view).obj = Py_None - */ - __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data); - - /* "View.MemoryView":1023 - * result.view = memviewslice.memview.view - * result.view.buf = memviewslice.data - * result.view.ndim = ndim # <<<<<<<<<<<<<< - * (<__pyx_buffer *> &result.view).obj = Py_None - * Py_INCREF(Py_None) - */ - __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim; - - /* "View.MemoryView":1024 - * result.view.buf = memviewslice.data - * result.view.ndim = ndim - * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<< - * Py_INCREF(Py_None) - * - */ - ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None; - - /* "View.MemoryView":1025 - * result.view.ndim = ndim - * (<__pyx_buffer *> &result.view).obj = Py_None - * Py_INCREF(Py_None) # <<<<<<<<<<<<<< - * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: - */ - Py_INCREF(Py_None); - - /* "View.MemoryView":1027 - * Py_INCREF(Py_None) - * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: # <<<<<<<<<<<<<< - * result.flags = PyBUF_RECORDS - * else: - */ - __pyx_t_1 = ((((struct __pyx_memoryview_obj *)__pyx_v_memviewslice.memview)->flags & PyBUF_WRITABLE) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":1028 - * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: - * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<< - * else: - * result.flags = PyBUF_RECORDS_RO - */ - __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS; - - /* "View.MemoryView":1027 - * Py_INCREF(Py_None) - * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: # <<<<<<<<<<<<<< - * result.flags = PyBUF_RECORDS - * else: - */ - goto __pyx_L4; - } - - /* "View.MemoryView":1030 - * result.flags = PyBUF_RECORDS - * else: - * result.flags = PyBUF_RECORDS_RO # <<<<<<<<<<<<<< - * - * result.view.shape = result.from_slice.shape - */ - /*else*/ { - __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS_RO; - } - __pyx_L4:; - - /* "View.MemoryView":1032 - * result.flags = PyBUF_RECORDS_RO - * - * result.view.shape = result.from_slice.shape # <<<<<<<<<<<<<< - * result.view.strides = result.from_slice.strides - * - */ - __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape); - - /* "View.MemoryView":1033 - * - * result.view.shape = result.from_slice.shape - * result.view.strides = result.from_slice.strides # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides); - - /* "View.MemoryView":1036 - * - * - * result.view.suboffsets = NULL # <<<<<<<<<<<<<< - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: - */ - __pyx_v_result->__pyx_base.view.suboffsets = NULL; - - /* "View.MemoryView":1037 - * - * result.view.suboffsets = NULL - * for suboffset in result.from_slice.suboffsets[:ndim]: # <<<<<<<<<<<<<< - * if suboffset >= 0: - * result.view.suboffsets = result.from_slice.suboffsets - */ - __pyx_t_7 = (__pyx_v_result->from_slice.suboffsets + __pyx_v_ndim); - for (__pyx_t_8 = __pyx_v_result->from_slice.suboffsets; __pyx_t_8 < __pyx_t_7; __pyx_t_8++) { - __pyx_t_6 = __pyx_t_8; - __pyx_v_suboffset = (__pyx_t_6[0]); - - /* "View.MemoryView":1038 - * result.view.suboffsets = NULL - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * result.view.suboffsets = result.from_slice.suboffsets - * break - */ - __pyx_t_1 = (__pyx_v_suboffset >= 0); - if (__pyx_t_1) { - - /* "View.MemoryView":1039 - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: - * result.view.suboffsets = result.from_slice.suboffsets # <<<<<<<<<<<<<< - * break - * - */ - __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets); - - /* "View.MemoryView":1040 - * if suboffset >= 0: - * result.view.suboffsets = result.from_slice.suboffsets - * break # <<<<<<<<<<<<<< - * - * result.view.len = result.view.itemsize - */ - goto __pyx_L6_break; - - /* "View.MemoryView":1038 - * result.view.suboffsets = NULL - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * result.view.suboffsets = result.from_slice.suboffsets - * break - */ - } - } - __pyx_L6_break:; - - /* "View.MemoryView":1042 - * break - * - * result.view.len = result.view.itemsize # <<<<<<<<<<<<<< - * for length in result.view.shape[:ndim]: - * result.view.len *= length - */ - __pyx_t_9 = __pyx_v_result->__pyx_base.view.itemsize; - __pyx_v_result->__pyx_base.view.len = __pyx_t_9; - - /* "View.MemoryView":1043 - * - * result.view.len = result.view.itemsize - * for length in result.view.shape[:ndim]: # <<<<<<<<<<<<<< - * result.view.len *= length - * - */ - __pyx_t_7 = (__pyx_v_result->__pyx_base.view.shape + __pyx_v_ndim); - for (__pyx_t_8 = __pyx_v_result->__pyx_base.view.shape; __pyx_t_8 < __pyx_t_7; __pyx_t_8++) { - __pyx_t_6 = __pyx_t_8; - __pyx_t_2 = PyInt_FromSsize_t((__pyx_t_6[0])); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1043, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_2); - __pyx_t_2 = 0; - - /* "View.MemoryView":1044 - * result.view.len = result.view.itemsize - * for length in result.view.shape[:ndim]: - * result.view.len *= length # <<<<<<<<<<<<<< - * - * result.to_object_func = to_object_func - */ - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_result->__pyx_base.view.len); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1044, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_t_2, __pyx_v_length); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 1044, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __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(1, 1044, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result->__pyx_base.view.len = __pyx_t_9; - } - - /* "View.MemoryView":1046 - * result.view.len *= length - * - * result.to_object_func = to_object_func # <<<<<<<<<<<<<< - * result.to_dtype_func = to_dtype_func - * - */ - __pyx_v_result->to_object_func = __pyx_v_to_object_func; - - /* "View.MemoryView":1047 - * - * result.to_object_func = to_object_func - * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<< - * - * return result - */ - __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func; - - /* "View.MemoryView":1049 - * result.to_dtype_func = to_dtype_func - * - * return result # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_get_slice_from_memoryview') - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF((PyObject *)__pyx_v_result); - __pyx_r = ((PyObject *)__pyx_v_result); - goto __pyx_L0; - - /* "View.MemoryView":999 - * - * @cname('__pyx_memoryview_fromslice') - * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<< - * int ndim, - * object (*to_object_func)(char *), - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XDECREF(__pyx_v_length); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":1052 - * - * @cname('__pyx_memoryview_get_slice_from_memoryview') - * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj - */ - -static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) { - struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0; - __Pyx_memviewslice *__pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_slice_from_memview", 1); - - /* "View.MemoryView":1055 - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * obj = memview - * return &obj.from_slice - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - if (__pyx_t_1) { - - /* "View.MemoryView":1056 - * cdef _memoryviewslice obj - * if isinstance(memview, _memoryviewslice): - * obj = memview # <<<<<<<<<<<<<< - * return &obj.from_slice - * else: - */ - if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) __PYX_ERR(1, 1056, __pyx_L1_error) - __pyx_t_2 = ((PyObject *)__pyx_v_memview); - __Pyx_INCREF(__pyx_t_2); - __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2); - __pyx_t_2 = 0; - - /* "View.MemoryView":1057 - * if isinstance(memview, _memoryviewslice): - * obj = memview - * return &obj.from_slice # <<<<<<<<<<<<<< - * else: - * slice_copy(memview, mslice) - */ - __pyx_r = (&__pyx_v_obj->from_slice); - goto __pyx_L0; - - /* "View.MemoryView":1055 - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * obj = memview - * return &obj.from_slice - */ - } - - /* "View.MemoryView":1059 - * return &obj.from_slice - * else: - * slice_copy(memview, mslice) # <<<<<<<<<<<<<< - * return mslice - * - */ - /*else*/ { - __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice); - - /* "View.MemoryView":1060 - * else: - * slice_copy(memview, mslice) - * return mslice # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_slice_copy') - */ - __pyx_r = __pyx_v_mslice; - goto __pyx_L0; - } - - /* "View.MemoryView":1052 - * - * @cname('__pyx_memoryview_get_slice_from_memoryview') - * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_obj); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":1063 - * - * @cname('__pyx_memoryview_slice_copy') - * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst) noexcept: # <<<<<<<<<<<<<< - * cdef int dim - * cdef (Py_ssize_t*) shape, strides, suboffsets - */ - -static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) { - int __pyx_v_dim; - Py_ssize_t *__pyx_v_shape; - Py_ssize_t *__pyx_v_strides; - Py_ssize_t *__pyx_v_suboffsets; - Py_ssize_t *__pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - Py_ssize_t __pyx_t_5; - int __pyx_t_6; - - /* "View.MemoryView":1067 - * cdef (Py_ssize_t*) shape, strides, suboffsets - * - * shape = memview.view.shape # <<<<<<<<<<<<<< - * strides = memview.view.strides - * suboffsets = memview.view.suboffsets - */ - __pyx_t_1 = __pyx_v_memview->view.shape; - __pyx_v_shape = __pyx_t_1; - - /* "View.MemoryView":1068 - * - * shape = memview.view.shape - * strides = memview.view.strides # <<<<<<<<<<<<<< - * suboffsets = memview.view.suboffsets - * - */ - __pyx_t_1 = __pyx_v_memview->view.strides; - __pyx_v_strides = __pyx_t_1; - - /* "View.MemoryView":1069 - * shape = memview.view.shape - * strides = memview.view.strides - * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<< - * - * dst.memview = <__pyx_memoryview *> memview - */ - __pyx_t_1 = __pyx_v_memview->view.suboffsets; - __pyx_v_suboffsets = __pyx_t_1; - - /* "View.MemoryView":1071 - * suboffsets = memview.view.suboffsets - * - * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<< - * dst.data = memview.view.buf - * - */ - __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview); - - /* "View.MemoryView":1072 - * - * dst.memview = <__pyx_memoryview *> memview - * dst.data = memview.view.buf # <<<<<<<<<<<<<< - * - * for dim in range(memview.view.ndim): - */ - __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf); - - /* "View.MemoryView":1074 - * dst.data = memview.view.buf - * - * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<< - * dst.shape[dim] = shape[dim] - * dst.strides[dim] = strides[dim] - */ - __pyx_t_2 = __pyx_v_memview->view.ndim; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_dim = __pyx_t_4; - - /* "View.MemoryView":1075 - * - * for dim in range(memview.view.ndim): - * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<< - * dst.strides[dim] = strides[dim] - * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 - */ - (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]); - - /* "View.MemoryView":1076 - * for dim in range(memview.view.ndim): - * dst.shape[dim] = shape[dim] - * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<< - * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 - * - */ - (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]); - - /* "View.MemoryView":1077 - * dst.shape[dim] = shape[dim] - * dst.strides[dim] = strides[dim] - * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_copy_object') - */ - __pyx_t_6 = (__pyx_v_suboffsets != 0); - if (__pyx_t_6) { - __pyx_t_5 = (__pyx_v_suboffsets[__pyx_v_dim]); - } else { - __pyx_t_5 = -1L; - } - (__pyx_v_dst->suboffsets[__pyx_v_dim]) = __pyx_t_5; - } - - /* "View.MemoryView":1063 - * - * @cname('__pyx_memoryview_slice_copy') - * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst) noexcept: # <<<<<<<<<<<<<< - * cdef int dim - * cdef (Py_ssize_t*) shape, strides, suboffsets - */ - - /* function exit code */ -} - -/* "View.MemoryView":1080 - * - * @cname('__pyx_memoryview_copy_object') - * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<< - * "Create a new memoryview object" - * cdef __Pyx_memviewslice memviewslice - */ - -static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) { - __Pyx_memviewslice __pyx_v_memviewslice; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_copy", 1); - - /* "View.MemoryView":1083 - * "Create a new memoryview object" - * cdef __Pyx_memviewslice memviewslice - * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<< - * return memoryview_copy_from_slice(memview, &memviewslice) - * - */ - __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice)); - - /* "View.MemoryView":1084 - * cdef __Pyx_memviewslice memviewslice - * slice_copy(memview, &memviewslice) - * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_copy_object_from_slice') - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1084, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":1080 - * - * @cname('__pyx_memoryview_copy_object') - * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<< - * "Create a new memoryview object" - * cdef __Pyx_memviewslice memviewslice - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":1087 - * - * @cname('__pyx_memoryview_copy_object_from_slice') - * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<< - * """ - * Create a new memoryview object from a given memoryview object and slice. - */ - -static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) { - PyObject *(*__pyx_v_to_object_func)(char *); - int (*__pyx_v_to_dtype_func)(char *, PyObject *); - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *(*__pyx_t_2)(char *); - int (*__pyx_t_3)(char *, PyObject *); - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 1); - - /* "View.MemoryView":1094 - * cdef int (*to_dtype_func)(char *, object) except 0 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * to_object_func = (<_memoryviewslice> memview).to_object_func - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - if (__pyx_t_1) { - - /* "View.MemoryView":1095 - * - * if isinstance(memview, _memoryviewslice): - * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<< - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func - * else: - */ - __pyx_t_2 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func; - __pyx_v_to_object_func = __pyx_t_2; - - /* "View.MemoryView":1096 - * if isinstance(memview, _memoryviewslice): - * to_object_func = (<_memoryviewslice> memview).to_object_func - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<< - * else: - * to_object_func = NULL - */ - __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func; - __pyx_v_to_dtype_func = __pyx_t_3; - - /* "View.MemoryView":1094 - * cdef int (*to_dtype_func)(char *, object) except 0 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * to_object_func = (<_memoryviewslice> memview).to_object_func - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1098 - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func - * else: - * to_object_func = NULL # <<<<<<<<<<<<<< - * to_dtype_func = NULL - * - */ - /*else*/ { - __pyx_v_to_object_func = NULL; - - /* "View.MemoryView":1099 - * else: - * to_object_func = NULL - * to_dtype_func = NULL # <<<<<<<<<<<<<< - * - * return memoryview_fromslice(memviewslice[0], memview.view.ndim, - */ - __pyx_v_to_dtype_func = NULL; - } - __pyx_L3:; - - /* "View.MemoryView":1101 - * to_dtype_func = NULL - * - * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<< - * to_object_func, to_dtype_func, - * memview.dtype_is_object) - */ - __Pyx_XDECREF(__pyx_r); - - /* "View.MemoryView":1103 - * return memoryview_fromslice(memviewslice[0], memview.view.ndim, - * to_object_func, to_dtype_func, - * memview.dtype_is_object) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_4 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 1101, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_r = __pyx_t_4; - __pyx_t_4 = 0; - goto __pyx_L0; - - /* "View.MemoryView":1087 - * - * @cname('__pyx_memoryview_copy_object_from_slice') - * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<< - * """ - * Create a new memoryview object from a given memoryview object and slice. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":1109 - * - * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) noexcept nogil: # <<<<<<<<<<<<<< - * return -arg if arg < 0 else arg - * - */ - -static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) { - Py_ssize_t __pyx_r; - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - - /* "View.MemoryView":1110 - * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) noexcept nogil: - * return -arg if arg < 0 else arg # <<<<<<<<<<<<<< - * - * @cname('__pyx_get_best_slice_order') - */ - __pyx_t_2 = (__pyx_v_arg < 0); - if (__pyx_t_2) { - __pyx_t_1 = (-__pyx_v_arg); - } else { - __pyx_t_1 = __pyx_v_arg; - } - __pyx_r = __pyx_t_1; - goto __pyx_L0; - - /* "View.MemoryView":1109 - * - * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) noexcept nogil: # <<<<<<<<<<<<<< - * return -arg if arg < 0 else arg - * - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1113 - * - * @cname('__pyx_get_best_slice_order') - * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) noexcept nogil: # <<<<<<<<<<<<<< - * """ - * Figure out the best memory access order for a given slice. - */ - -static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) { - int __pyx_v_i; - Py_ssize_t __pyx_v_c_stride; - Py_ssize_t __pyx_v_f_stride; - char __pyx_r; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - - /* "View.MemoryView":1118 - * """ - * cdef int i - * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<< - * cdef Py_ssize_t f_stride = 0 - * - */ - __pyx_v_c_stride = 0; - - /* "View.MemoryView":1119 - * cdef int i - * cdef Py_ssize_t c_stride = 0 - * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<< - * - * for i in range(ndim - 1, -1, -1): - */ - __pyx_v_f_stride = 0; - - /* "View.MemoryView":1121 - * cdef Py_ssize_t f_stride = 0 - * - * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< - * if mslice.shape[i] > 1: - * c_stride = mslice.strides[i] - */ - for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) { - __pyx_v_i = __pyx_t_1; - - /* "View.MemoryView":1122 - * - * for i in range(ndim - 1, -1, -1): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * c_stride = mslice.strides[i] - * break - */ - __pyx_t_2 = ((__pyx_v_mslice->shape[__pyx_v_i]) > 1); - if (__pyx_t_2) { - - /* "View.MemoryView":1123 - * for i in range(ndim - 1, -1, -1): - * if mslice.shape[i] > 1: - * c_stride = mslice.strides[i] # <<<<<<<<<<<<<< - * break - * - */ - __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]); - - /* "View.MemoryView":1124 - * if mslice.shape[i] > 1: - * c_stride = mslice.strides[i] - * break # <<<<<<<<<<<<<< - * - * for i in range(ndim): - */ - goto __pyx_L4_break; - - /* "View.MemoryView":1122 - * - * for i in range(ndim - 1, -1, -1): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * c_stride = mslice.strides[i] - * break - */ - } - } - __pyx_L4_break:; - - /* "View.MemoryView":1126 - * break - * - * for i in range(ndim): # <<<<<<<<<<<<<< - * if mslice.shape[i] > 1: - * f_stride = mslice.strides[i] - */ - __pyx_t_1 = __pyx_v_ndim; - __pyx_t_3 = __pyx_t_1; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; - - /* "View.MemoryView":1127 - * - * for i in range(ndim): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * f_stride = mslice.strides[i] - * break - */ - __pyx_t_2 = ((__pyx_v_mslice->shape[__pyx_v_i]) > 1); - if (__pyx_t_2) { - - /* "View.MemoryView":1128 - * for i in range(ndim): - * if mslice.shape[i] > 1: - * f_stride = mslice.strides[i] # <<<<<<<<<<<<<< - * break - * - */ - __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]); - - /* "View.MemoryView":1129 - * if mslice.shape[i] > 1: - * f_stride = mslice.strides[i] - * break # <<<<<<<<<<<<<< - * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): - */ - goto __pyx_L7_break; - - /* "View.MemoryView":1127 - * - * for i in range(ndim): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * f_stride = mslice.strides[i] - * break - */ - } - } - __pyx_L7_break:; - - /* "View.MemoryView":1131 - * break - * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<< - * return 'C' - * else: - */ - __pyx_t_2 = (abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)); - if (__pyx_t_2) { - - /* "View.MemoryView":1132 - * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): - * return 'C' # <<<<<<<<<<<<<< - * else: - * return 'F' - */ - __pyx_r = 'C'; - goto __pyx_L0; - - /* "View.MemoryView":1131 - * break - * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<< - * return 'C' - * else: - */ - } - - /* "View.MemoryView":1134 - * return 'C' - * else: - * return 'F' # <<<<<<<<<<<<<< - * - * @cython.cdivision(True) - */ - /*else*/ { - __pyx_r = 'F'; - goto __pyx_L0; - } - - /* "View.MemoryView":1113 - * - * @cname('__pyx_get_best_slice_order') - * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) noexcept nogil: # <<<<<<<<<<<<<< - * """ - * Figure out the best memory access order for a given slice. - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1137 - * - * @cython.cdivision(True) - * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<< - * char *dst_data, Py_ssize_t *dst_strides, - * Py_ssize_t *src_shape, Py_ssize_t *dst_shape, - */ - -static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) { - CYTHON_UNUSED Py_ssize_t __pyx_v_i; - CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent; - Py_ssize_t __pyx_v_dst_extent; - Py_ssize_t __pyx_v_src_stride; - Py_ssize_t __pyx_v_dst_stride; - int __pyx_t_1; - int __pyx_t_2; - Py_ssize_t __pyx_t_3; - Py_ssize_t __pyx_t_4; - Py_ssize_t __pyx_t_5; - - /* "View.MemoryView":1144 - * - * cdef Py_ssize_t i - * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t dst_extent = dst_shape[0] - * cdef Py_ssize_t src_stride = src_strides[0] - */ - __pyx_v_src_extent = (__pyx_v_src_shape[0]); - - /* "View.MemoryView":1145 - * cdef Py_ssize_t i - * cdef Py_ssize_t src_extent = src_shape[0] - * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t src_stride = src_strides[0] - * cdef Py_ssize_t dst_stride = dst_strides[0] - */ - __pyx_v_dst_extent = (__pyx_v_dst_shape[0]); - - /* "View.MemoryView":1146 - * cdef Py_ssize_t src_extent = src_shape[0] - * cdef Py_ssize_t dst_extent = dst_shape[0] - * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t dst_stride = dst_strides[0] - * - */ - __pyx_v_src_stride = (__pyx_v_src_strides[0]); - - /* "View.MemoryView":1147 - * cdef Py_ssize_t dst_extent = dst_shape[0] - * cdef Py_ssize_t src_stride = src_strides[0] - * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<< - * - * if ndim == 1: - */ - __pyx_v_dst_stride = (__pyx_v_dst_strides[0]); - - /* "View.MemoryView":1149 - * cdef Py_ssize_t dst_stride = dst_strides[0] - * - * if ndim == 1: # <<<<<<<<<<<<<< - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): - */ - __pyx_t_1 = (__pyx_v_ndim == 1); - if (__pyx_t_1) { - - /* "View.MemoryView":1150 - * - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) - */ - __pyx_t_2 = (__pyx_v_src_stride > 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L5_bool_binop_done; - } - __pyx_t_2 = (__pyx_v_dst_stride > 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L5_bool_binop_done; - } - - /* "View.MemoryView":1151 - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): # <<<<<<<<<<<<<< - * memcpy(dst_data, src_data, itemsize * dst_extent) - * else: - */ - __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize); - if (__pyx_t_2) { - __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride)); - } - __pyx_t_1 = __pyx_t_2; - __pyx_L5_bool_binop_done:; - - /* "View.MemoryView":1150 - * - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) - */ - if (__pyx_t_1) { - - /* "View.MemoryView":1152 - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<< - * else: - * for i in range(dst_extent): - */ - (void)(memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent))); - - /* "View.MemoryView":1150 - * - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) - */ - goto __pyx_L4; - } - - /* "View.MemoryView":1154 - * memcpy(dst_data, src_data, itemsize * dst_extent) - * else: - * for i in range(dst_extent): # <<<<<<<<<<<<<< - * memcpy(dst_data, src_data, itemsize) - * src_data += src_stride - */ - /*else*/ { - __pyx_t_3 = __pyx_v_dst_extent; - __pyx_t_4 = __pyx_t_3; - for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { - __pyx_v_i = __pyx_t_5; - - /* "View.MemoryView":1155 - * else: - * for i in range(dst_extent): - * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<< - * src_data += src_stride - * dst_data += dst_stride - */ - (void)(memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize)); - - /* "View.MemoryView":1156 - * for i in range(dst_extent): - * memcpy(dst_data, src_data, itemsize) - * src_data += src_stride # <<<<<<<<<<<<<< - * dst_data += dst_stride - * else: - */ - __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride); - - /* "View.MemoryView":1157 - * memcpy(dst_data, src_data, itemsize) - * src_data += src_stride - * dst_data += dst_stride # <<<<<<<<<<<<<< - * else: - * for i in range(dst_extent): - */ - __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride); - } - } - __pyx_L4:; - - /* "View.MemoryView":1149 - * cdef Py_ssize_t dst_stride = dst_strides[0] - * - * if ndim == 1: # <<<<<<<<<<<<<< - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1159 - * dst_data += dst_stride - * else: - * for i in range(dst_extent): # <<<<<<<<<<<<<< - * _copy_strided_to_strided(src_data, src_strides + 1, - * dst_data, dst_strides + 1, - */ - /*else*/ { - __pyx_t_3 = __pyx_v_dst_extent; - __pyx_t_4 = __pyx_t_3; - for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { - __pyx_v_i = __pyx_t_5; - - /* "View.MemoryView":1160 - * else: - * for i in range(dst_extent): - * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<< - * dst_data, dst_strides + 1, - * src_shape + 1, dst_shape + 1, - */ - _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize); - - /* "View.MemoryView":1164 - * src_shape + 1, dst_shape + 1, - * ndim - 1, itemsize) - * src_data += src_stride # <<<<<<<<<<<<<< - * dst_data += dst_stride - * - */ - __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride); - - /* "View.MemoryView":1165 - * ndim - 1, itemsize) - * src_data += src_stride - * dst_data += dst_stride # <<<<<<<<<<<<<< - * - * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, - */ - __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride); - } - } - __pyx_L3:; - - /* "View.MemoryView":1137 - * - * @cython.cdivision(True) - * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<< - * char *dst_data, Py_ssize_t *dst_strides, - * Py_ssize_t *src_shape, Py_ssize_t *dst_shape, - */ - - /* function exit code */ -} - -/* "View.MemoryView":1167 - * dst_data += dst_stride - * - * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * int ndim, size_t itemsize) noexcept nogil: - */ - -static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) { - - /* "View.MemoryView":1170 - * __Pyx_memviewslice *dst, - * int ndim, size_t itemsize) noexcept nogil: - * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<< - * src.shape, dst.shape, ndim, itemsize) - * - */ - _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize); - - /* "View.MemoryView":1167 - * dst_data += dst_stride - * - * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * int ndim, size_t itemsize) noexcept nogil: - */ - - /* function exit code */ -} - -/* "View.MemoryView":1174 - * - * @cname('__pyx_memoryview_slice_get_size') - * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) noexcept nogil: # <<<<<<<<<<<<<< - * "Return the size of the memory occupied by the slice in number of bytes" - * cdef Py_ssize_t shape, size = src.memview.view.itemsize - */ - -static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) { - Py_ssize_t __pyx_v_shape; - Py_ssize_t __pyx_v_size; - Py_ssize_t __pyx_r; - Py_ssize_t __pyx_t_1; - Py_ssize_t *__pyx_t_2; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - - /* "View.MemoryView":1176 - * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) noexcept nogil: - * "Return the size of the memory occupied by the slice in number of bytes" - * cdef Py_ssize_t shape, size = src.memview.view.itemsize # <<<<<<<<<<<<<< - * - * for shape in src.shape[:ndim]: - */ - __pyx_t_1 = __pyx_v_src->memview->view.itemsize; - __pyx_v_size = __pyx_t_1; - - /* "View.MemoryView":1178 - * cdef Py_ssize_t shape, size = src.memview.view.itemsize - * - * for shape in src.shape[:ndim]: # <<<<<<<<<<<<<< - * size *= shape - * - */ - __pyx_t_3 = (__pyx_v_src->shape + __pyx_v_ndim); - for (__pyx_t_4 = __pyx_v_src->shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { - __pyx_t_2 = __pyx_t_4; - __pyx_v_shape = (__pyx_t_2[0]); - - /* "View.MemoryView":1179 - * - * for shape in src.shape[:ndim]: - * size *= shape # <<<<<<<<<<<<<< - * - * return size - */ - __pyx_v_size = (__pyx_v_size * __pyx_v_shape); - } - - /* "View.MemoryView":1181 - * size *= shape - * - * return size # <<<<<<<<<<<<<< - * - * @cname('__pyx_fill_contig_strides_array') - */ - __pyx_r = __pyx_v_size; - goto __pyx_L0; - - /* "View.MemoryView":1174 - * - * @cname('__pyx_memoryview_slice_get_size') - * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) noexcept nogil: # <<<<<<<<<<<<<< - * "Return the size of the memory occupied by the slice in number of bytes" - * cdef Py_ssize_t shape, size = src.memview.view.itemsize - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1184 - * - * @cname('__pyx_fill_contig_strides_array') - * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<< - * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, - * int ndim, char order) noexcept nogil: - */ - -static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) { - int __pyx_v_idx; - Py_ssize_t __pyx_r; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - - /* "View.MemoryView":1193 - * cdef int idx - * - * if order == 'F': # <<<<<<<<<<<<<< - * for idx in range(ndim): - * strides[idx] = stride - */ - __pyx_t_1 = (__pyx_v_order == 'F'); - if (__pyx_t_1) { - - /* "View.MemoryView":1194 - * - * if order == 'F': - * for idx in range(ndim): # <<<<<<<<<<<<<< - * strides[idx] = stride - * stride *= shape[idx] - */ - __pyx_t_2 = __pyx_v_ndim; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_idx = __pyx_t_4; - - /* "View.MemoryView":1195 - * if order == 'F': - * for idx in range(ndim): - * strides[idx] = stride # <<<<<<<<<<<<<< - * stride *= shape[idx] - * else: - */ - (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride; - - /* "View.MemoryView":1196 - * for idx in range(ndim): - * strides[idx] = stride - * stride *= shape[idx] # <<<<<<<<<<<<<< - * else: - * for idx in range(ndim - 1, -1, -1): - */ - __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx])); - } - - /* "View.MemoryView":1193 - * cdef int idx - * - * if order == 'F': # <<<<<<<<<<<<<< - * for idx in range(ndim): - * strides[idx] = stride - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1198 - * stride *= shape[idx] - * else: - * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< - * strides[idx] = stride - * stride *= shape[idx] - */ - /*else*/ { - for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) { - __pyx_v_idx = __pyx_t_2; - - /* "View.MemoryView":1199 - * else: - * for idx in range(ndim - 1, -1, -1): - * strides[idx] = stride # <<<<<<<<<<<<<< - * stride *= shape[idx] - * - */ - (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride; - - /* "View.MemoryView":1200 - * for idx in range(ndim - 1, -1, -1): - * strides[idx] = stride - * stride *= shape[idx] # <<<<<<<<<<<<<< - * - * return stride - */ - __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx])); - } - } - __pyx_L3:; - - /* "View.MemoryView":1202 - * stride *= shape[idx] - * - * return stride # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_copy_data_to_temp') - */ - __pyx_r = __pyx_v_stride; - goto __pyx_L0; - - /* "View.MemoryView":1184 - * - * @cname('__pyx_fill_contig_strides_array') - * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<< - * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, - * int ndim, char order) noexcept nogil: - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1205 - * - * @cname('__pyx_memoryview_copy_data_to_temp') - * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *tmpslice, - * char order, - */ - -static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) { - int __pyx_v_i; - void *__pyx_v_result; - size_t __pyx_v_itemsize; - size_t __pyx_v_size; - void *__pyx_r; - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - struct __pyx_memoryview_obj *__pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save; - #endif - - /* "View.MemoryView":1216 - * cdef void *result - * - * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<< - * cdef size_t size = slice_get_size(src, ndim) - * - */ - __pyx_t_1 = __pyx_v_src->memview->view.itemsize; - __pyx_v_itemsize = __pyx_t_1; - - /* "View.MemoryView":1217 - * - * cdef size_t itemsize = src.memview.view.itemsize - * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<< - * - * result = malloc(size) - */ - __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim); - - /* "View.MemoryView":1219 - * cdef size_t size = slice_get_size(src, ndim) - * - * result = malloc(size) # <<<<<<<<<<<<<< - * if not result: - * _err_no_memory() - */ - __pyx_v_result = malloc(__pyx_v_size); - - /* "View.MemoryView":1220 - * - * result = malloc(size) - * if not result: # <<<<<<<<<<<<<< - * _err_no_memory() - * - */ - __pyx_t_2 = (!(__pyx_v_result != 0)); - if (__pyx_t_2) { - - /* "View.MemoryView":1221 - * result = malloc(size) - * if not result: - * _err_no_memory() # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __pyx_memoryview_err_no_memory(); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(1, 1221, __pyx_L1_error) - - /* "View.MemoryView":1220 - * - * result = malloc(size) - * if not result: # <<<<<<<<<<<<<< - * _err_no_memory() - * - */ - } - - /* "View.MemoryView":1224 - * - * - * tmpslice.data = result # <<<<<<<<<<<<<< - * tmpslice.memview = src.memview - * for i in range(ndim): - */ - __pyx_v_tmpslice->data = ((char *)__pyx_v_result); - - /* "View.MemoryView":1225 - * - * tmpslice.data = result - * tmpslice.memview = src.memview # <<<<<<<<<<<<<< - * for i in range(ndim): - * tmpslice.shape[i] = src.shape[i] - */ - __pyx_t_4 = __pyx_v_src->memview; - __pyx_v_tmpslice->memview = __pyx_t_4; - - /* "View.MemoryView":1226 - * tmpslice.data = result - * tmpslice.memview = src.memview - * for i in range(ndim): # <<<<<<<<<<<<<< - * tmpslice.shape[i] = src.shape[i] - * tmpslice.suboffsets[i] = -1 - */ - __pyx_t_3 = __pyx_v_ndim; - __pyx_t_5 = __pyx_t_3; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "View.MemoryView":1227 - * tmpslice.memview = src.memview - * for i in range(ndim): - * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<< - * tmpslice.suboffsets[i] = -1 - * - */ - (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]); - - /* "View.MemoryView":1228 - * for i in range(ndim): - * tmpslice.shape[i] = src.shape[i] - * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<< - * - * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, ndim, order) - */ - (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1L; - } - - /* "View.MemoryView":1230 - * tmpslice.suboffsets[i] = -1 - * - * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, ndim, order) # <<<<<<<<<<<<<< - * - * - */ - (void)(__pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order)); - - /* "View.MemoryView":1233 - * - * - * for i in range(ndim): # <<<<<<<<<<<<<< - * if tmpslice.shape[i] == 1: - * tmpslice.strides[i] = 0 - */ - __pyx_t_3 = __pyx_v_ndim; - __pyx_t_5 = __pyx_t_3; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "View.MemoryView":1234 - * - * for i in range(ndim): - * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<< - * tmpslice.strides[i] = 0 - * - */ - __pyx_t_2 = ((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1); - if (__pyx_t_2) { - - /* "View.MemoryView":1235 - * for i in range(ndim): - * if tmpslice.shape[i] == 1: - * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<< - * - * if slice_is_contig(src[0], order, ndim): - */ - (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0; - - /* "View.MemoryView":1234 - * - * for i in range(ndim): - * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<< - * tmpslice.strides[i] = 0 - * - */ - } - } - - /* "View.MemoryView":1237 - * tmpslice.strides[i] = 0 - * - * if slice_is_contig(src[0], order, ndim): # <<<<<<<<<<<<<< - * memcpy(result, src.data, size) - * else: - */ - __pyx_t_2 = __pyx_memviewslice_is_contig((__pyx_v_src[0]), __pyx_v_order, __pyx_v_ndim); - if (__pyx_t_2) { - - /* "View.MemoryView":1238 - * - * if slice_is_contig(src[0], order, ndim): - * memcpy(result, src.data, size) # <<<<<<<<<<<<<< - * else: - * copy_strided_to_strided(src, tmpslice, ndim, itemsize) - */ - (void)(memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size)); - - /* "View.MemoryView":1237 - * tmpslice.strides[i] = 0 - * - * if slice_is_contig(src[0], order, ndim): # <<<<<<<<<<<<<< - * memcpy(result, src.data, size) - * else: - */ - goto __pyx_L9; - } - - /* "View.MemoryView":1240 - * memcpy(result, src.data, size) - * else: - * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<< - * - * return result - */ - /*else*/ { - copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize); - } - __pyx_L9:; - - /* "View.MemoryView":1242 - * copy_strided_to_strided(src, tmpslice, ndim, itemsize) - * - * return result # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_result; - goto __pyx_L0; - - /* "View.MemoryView":1205 - * - * @cname('__pyx_memoryview_copy_data_to_temp') - * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *tmpslice, - * char order, - */ - - /* function exit code */ - __pyx_L1_error:; - #ifdef WITH_THREAD - __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1247 - * - * @cname('__pyx_memoryview_err_extents') - * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<< - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError, f"got differing extents in dimension {i} (got {extent1} and {extent2})" - */ - -static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - Py_UCS4 __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("_err_extents", 0); - - /* "View.MemoryView":1249 - * cdef int _err_extents(int i, Py_ssize_t extent1, - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError, f"got differing extents in dimension {i} (got {extent1} and {extent2})" # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_err_dim') - */ - __pyx_t_1 = PyTuple_New(7); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = 0; - __pyx_t_3 = 127; - __Pyx_INCREF(__pyx_kp_u_got_differing_extents_in_dimensi); - __pyx_t_2 += 35; - __Pyx_GIVEREF(__pyx_kp_u_got_differing_extents_in_dimensi); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_got_differing_extents_in_dimensi); - __pyx_t_4 = __Pyx_PyUnicode_From_int(__pyx_v_i, 0, ' ', 'd'); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 1249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4); - __pyx_t_4 = 0; - __Pyx_INCREF(__pyx_kp_u_got); - __pyx_t_2 += 6; - __Pyx_GIVEREF(__pyx_kp_u_got); - PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_got); - __pyx_t_4 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_extent1, 0, ' ', 'd'); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 1249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_4); - __pyx_t_4 = 0; - __Pyx_INCREF(__pyx_kp_u_and); - __pyx_t_2 += 5; - __Pyx_GIVEREF(__pyx_kp_u_and); - PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u_and); - __pyx_t_4 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_extent2, 0, ' ', 'd'); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 1249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_t_4); - __pyx_t_4 = 0; - __Pyx_INCREF(__pyx_kp_u__7); - __pyx_t_2 += 1; - __Pyx_GIVEREF(__pyx_kp_u__7); - PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_kp_u__7); - __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_1, 7, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 1249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_Raise(__pyx_builtin_ValueError, __pyx_t_4, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(1, 1249, __pyx_L1_error) - - /* "View.MemoryView":1247 - * - * @cname('__pyx_memoryview_err_extents') - * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<< - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError, f"got differing extents in dimension {i} (got {extent1} and {extent2})" - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __Pyx_RefNannyFinishContext(); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - return __pyx_r; -} - -/* "View.MemoryView":1252 - * - * @cname('__pyx_memoryview_err_dim') - * cdef int _err_dim(PyObject *error, str msg, int dim) except -1 with gil: # <<<<<<<<<<<<<< - * raise error, msg % dim - * - */ - -static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, PyObject *__pyx_v_msg, int __pyx_v_dim) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("_err_dim", 0); - __Pyx_INCREF(__pyx_v_msg); - - /* "View.MemoryView":1253 - * @cname('__pyx_memoryview_err_dim') - * cdef int _err_dim(PyObject *error, str msg, int dim) except -1 with gil: - * raise error, msg % dim # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_err') - */ - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1253, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyString_FormatSafe(__pyx_v_msg, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1253, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_Raise(((PyObject *)__pyx_v_error), __pyx_t_2, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(1, 1253, __pyx_L1_error) - - /* "View.MemoryView":1252 - * - * @cname('__pyx_memoryview_err_dim') - * cdef int _err_dim(PyObject *error, str msg, int dim) except -1 with gil: # <<<<<<<<<<<<<< - * raise error, msg % dim - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __Pyx_XDECREF(__pyx_v_msg); - __Pyx_RefNannyFinishContext(); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - return __pyx_r; -} - -/* "View.MemoryView":1256 - * - * @cname('__pyx_memoryview_err') - * cdef int _err(PyObject *error, str msg) except -1 with gil: # <<<<<<<<<<<<<< - * raise error, msg - * - */ - -static int __pyx_memoryview_err(PyObject *__pyx_v_error, PyObject *__pyx_v_msg) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("_err", 0); - __Pyx_INCREF(__pyx_v_msg); - - /* "View.MemoryView":1257 - * @cname('__pyx_memoryview_err') - * cdef int _err(PyObject *error, str msg) except -1 with gil: - * raise error, msg # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_err_no_memory') - */ - __Pyx_Raise(((PyObject *)__pyx_v_error), __pyx_v_msg, 0, 0); - __PYX_ERR(1, 1257, __pyx_L1_error) - - /* "View.MemoryView":1256 - * - * @cname('__pyx_memoryview_err') - * cdef int _err(PyObject *error, str msg) except -1 with gil: # <<<<<<<<<<<<<< - * raise error, msg - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __Pyx_XDECREF(__pyx_v_msg); - __Pyx_RefNannyFinishContext(); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - return __pyx_r; -} - -/* "View.MemoryView":1260 - * - * @cname('__pyx_memoryview_err_no_memory') - * cdef int _err_no_memory() except -1 with gil: # <<<<<<<<<<<<<< - * raise MemoryError - * - */ - -static int __pyx_memoryview_err_no_memory(void) { - int __pyx_r; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - - /* "View.MemoryView":1261 - * @cname('__pyx_memoryview_err_no_memory') - * cdef int _err_no_memory() except -1 with gil: - * raise MemoryError # <<<<<<<<<<<<<< - * - * - */ - PyErr_NoMemory(); __PYX_ERR(1, 1261, __pyx_L1_error) - - /* "View.MemoryView":1260 - * - * @cname('__pyx_memoryview_err_no_memory') - * cdef int _err_no_memory() except -1 with gil: # <<<<<<<<<<<<<< - * raise MemoryError - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView._err_no_memory", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - return __pyx_r; -} - -/* "View.MemoryView":1265 - * - * @cname('__pyx_memoryview_copy_contents') - * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice dst, - * int src_ndim, int dst_ndim, - */ - -static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) { - void *__pyx_v_tmpdata; - size_t __pyx_v_itemsize; - int __pyx_v_i; - char __pyx_v_order; - int __pyx_v_broadcasting; - int __pyx_v_direct_copy; - __Pyx_memviewslice __pyx_v_tmp; - int __pyx_v_ndim; - int __pyx_r; - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - void *__pyx_t_7; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save; - #endif - - /* "View.MemoryView":1273 - * Check for overlapping memory and verify the shapes. - * """ - * cdef void *tmpdata = NULL # <<<<<<<<<<<<<< - * cdef size_t itemsize = src.memview.view.itemsize - * cdef int i - */ - __pyx_v_tmpdata = NULL; - - /* "View.MemoryView":1274 - * """ - * cdef void *tmpdata = NULL - * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<< - * cdef int i - * cdef char order = get_best_order(&src, src_ndim) - */ - __pyx_t_1 = __pyx_v_src.memview->view.itemsize; - __pyx_v_itemsize = __pyx_t_1; - - /* "View.MemoryView":1276 - * cdef size_t itemsize = src.memview.view.itemsize - * cdef int i - * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<< - * cdef bint broadcasting = False - * cdef bint direct_copy = False - */ - __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim); - - /* "View.MemoryView":1277 - * cdef int i - * cdef char order = get_best_order(&src, src_ndim) - * cdef bint broadcasting = False # <<<<<<<<<<<<<< - * cdef bint direct_copy = False - * cdef __Pyx_memviewslice tmp - */ - __pyx_v_broadcasting = 0; - - /* "View.MemoryView":1278 - * cdef char order = get_best_order(&src, src_ndim) - * cdef bint broadcasting = False - * cdef bint direct_copy = False # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice tmp - * - */ - __pyx_v_direct_copy = 0; - - /* "View.MemoryView":1281 - * cdef __Pyx_memviewslice tmp - * - * if src_ndim < dst_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: - */ - __pyx_t_2 = (__pyx_v_src_ndim < __pyx_v_dst_ndim); - if (__pyx_t_2) { - - /* "View.MemoryView":1282 - * - * if src_ndim < dst_ndim: - * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<< - * elif dst_ndim < src_ndim: - * broadcast_leading(&dst, dst_ndim, src_ndim) - */ - __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim); - - /* "View.MemoryView":1281 - * cdef __Pyx_memviewslice tmp - * - * if src_ndim < dst_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1283 - * if src_ndim < dst_ndim: - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&dst, dst_ndim, src_ndim) - * - */ - __pyx_t_2 = (__pyx_v_dst_ndim < __pyx_v_src_ndim); - if (__pyx_t_2) { - - /* "View.MemoryView":1284 - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: - * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<< - * - * cdef int ndim = max(src_ndim, dst_ndim) - */ - __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim); - - /* "View.MemoryView":1283 - * if src_ndim < dst_ndim: - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&dst, dst_ndim, src_ndim) - * - */ - } - __pyx_L3:; - - /* "View.MemoryView":1286 - * broadcast_leading(&dst, dst_ndim, src_ndim) - * - * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<< - * - * for i in range(ndim): - */ - __pyx_t_3 = __pyx_v_dst_ndim; - __pyx_t_4 = __pyx_v_src_ndim; - __pyx_t_2 = (__pyx_t_3 > __pyx_t_4); - if (__pyx_t_2) { - __pyx_t_5 = __pyx_t_3; - } else { - __pyx_t_5 = __pyx_t_4; - } - __pyx_v_ndim = __pyx_t_5; - - /* "View.MemoryView":1288 - * cdef int ndim = max(src_ndim, dst_ndim) - * - * for i in range(ndim): # <<<<<<<<<<<<<< - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: - */ - __pyx_t_5 = __pyx_v_ndim; - __pyx_t_3 = __pyx_t_5; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; - - /* "View.MemoryView":1289 - * - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<< - * if src.shape[i] == 1: - * broadcasting = True - */ - __pyx_t_2 = ((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])); - if (__pyx_t_2) { - - /* "View.MemoryView":1290 - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: # <<<<<<<<<<<<<< - * broadcasting = True - * src.strides[i] = 0 - */ - __pyx_t_2 = ((__pyx_v_src.shape[__pyx_v_i]) == 1); - if (__pyx_t_2) { - - /* "View.MemoryView":1291 - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: - * broadcasting = True # <<<<<<<<<<<<<< - * src.strides[i] = 0 - * else: - */ - __pyx_v_broadcasting = 1; - - /* "View.MemoryView":1292 - * if src.shape[i] == 1: - * broadcasting = True - * src.strides[i] = 0 # <<<<<<<<<<<<<< - * else: - * _err_extents(i, dst.shape[i], src.shape[i]) - */ - (__pyx_v_src.strides[__pyx_v_i]) = 0; - - /* "View.MemoryView":1290 - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: # <<<<<<<<<<<<<< - * broadcasting = True - * src.strides[i] = 0 - */ - goto __pyx_L7; - } - - /* "View.MemoryView":1294 - * src.strides[i] = 0 - * else: - * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<< - * - * if src.suboffsets[i] >= 0: - */ - /*else*/ { - __pyx_t_6 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(1, 1294, __pyx_L1_error) - } - __pyx_L7:; - - /* "View.MemoryView":1289 - * - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<< - * if src.shape[i] == 1: - * broadcasting = True - */ - } - - /* "View.MemoryView":1296 - * _err_extents(i, dst.shape[i], src.shape[i]) - * - * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<< - * _err_dim(PyExc_ValueError, "Dimension %d is not direct", i) - * - */ - __pyx_t_2 = ((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1297 - * - * if src.suboffsets[i] >= 0: - * _err_dim(PyExc_ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<< - * - * if slices_overlap(&src, &dst, ndim, itemsize): - */ - __pyx_t_6 = __pyx_memoryview_err_dim(PyExc_ValueError, __pyx_kp_s_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(1, 1297, __pyx_L1_error) - - /* "View.MemoryView":1296 - * _err_extents(i, dst.shape[i], src.shape[i]) - * - * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<< - * _err_dim(PyExc_ValueError, "Dimension %d is not direct", i) - * - */ - } - } - - /* "View.MemoryView":1299 - * _err_dim(PyExc_ValueError, "Dimension %d is not direct", i) - * - * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<< - * - * if not slice_is_contig(src, order, ndim): - */ - __pyx_t_2 = __pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize); - if (__pyx_t_2) { - - /* "View.MemoryView":1301 - * if slices_overlap(&src, &dst, ndim, itemsize): - * - * if not slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<< - * order = get_best_order(&dst, ndim) - * - */ - __pyx_t_2 = (!__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim)); - if (__pyx_t_2) { - - /* "View.MemoryView":1302 - * - * if not slice_is_contig(src, order, ndim): - * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<< - * - * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) - */ - __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim); - - /* "View.MemoryView":1301 - * if slices_overlap(&src, &dst, ndim, itemsize): - * - * if not slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<< - * order = get_best_order(&dst, ndim) - * - */ - } - - /* "View.MemoryView":1304 - * order = get_best_order(&dst, ndim) - * - * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<< - * src = tmp - * - */ - __pyx_t_7 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_7 == ((void *)NULL))) __PYX_ERR(1, 1304, __pyx_L1_error) - __pyx_v_tmpdata = __pyx_t_7; - - /* "View.MemoryView":1305 - * - * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) - * src = tmp # <<<<<<<<<<<<<< - * - * if not broadcasting: - */ - __pyx_v_src = __pyx_v_tmp; - - /* "View.MemoryView":1299 - * _err_dim(PyExc_ValueError, "Dimension %d is not direct", i) - * - * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<< - * - * if not slice_is_contig(src, order, ndim): - */ - } - - /* "View.MemoryView":1307 - * src = tmp - * - * if not broadcasting: # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = (!__pyx_v_broadcasting); - if (__pyx_t_2) { - - /* "View.MemoryView":1310 - * - * - * if slice_is_contig(src, 'C', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): - */ - __pyx_t_2 = __pyx_memviewslice_is_contig(__pyx_v_src, 'C', __pyx_v_ndim); - if (__pyx_t_2) { - - /* "View.MemoryView":1311 - * - * if slice_is_contig(src, 'C', ndim): - * direct_copy = slice_is_contig(dst, 'C', ndim) # <<<<<<<<<<<<<< - * elif slice_is_contig(src, 'F', ndim): - * direct_copy = slice_is_contig(dst, 'F', ndim) - */ - __pyx_v_direct_copy = __pyx_memviewslice_is_contig(__pyx_v_dst, 'C', __pyx_v_ndim); - - /* "View.MemoryView":1310 - * - * - * if slice_is_contig(src, 'C', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): - */ - goto __pyx_L12; - } - - /* "View.MemoryView":1312 - * if slice_is_contig(src, 'C', ndim): - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'F', ndim) - * - */ - __pyx_t_2 = __pyx_memviewslice_is_contig(__pyx_v_src, 'F', __pyx_v_ndim); - if (__pyx_t_2) { - - /* "View.MemoryView":1313 - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): - * direct_copy = slice_is_contig(dst, 'F', ndim) # <<<<<<<<<<<<<< - * - * if direct_copy: - */ - __pyx_v_direct_copy = __pyx_memviewslice_is_contig(__pyx_v_dst, 'F', __pyx_v_ndim); - - /* "View.MemoryView":1312 - * if slice_is_contig(src, 'C', ndim): - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'F', ndim) - * - */ - } - __pyx_L12:; - - /* "View.MemoryView":1315 - * direct_copy = slice_is_contig(dst, 'F', ndim) - * - * if direct_copy: # <<<<<<<<<<<<<< - * - * refcount_copying(&dst, dtype_is_object, ndim, inc=False) - */ - if (__pyx_v_direct_copy) { - - /* "View.MemoryView":1317 - * if direct_copy: - * - * refcount_copying(&dst, dtype_is_object, ndim, inc=False) # <<<<<<<<<<<<<< - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) - * refcount_copying(&dst, dtype_is_object, ndim, inc=True) - */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0); - - /* "View.MemoryView":1318 - * - * refcount_copying(&dst, dtype_is_object, ndim, inc=False) - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<< - * refcount_copying(&dst, dtype_is_object, ndim, inc=True) - * free(tmpdata) - */ - (void)(memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim))); - - /* "View.MemoryView":1319 - * refcount_copying(&dst, dtype_is_object, ndim, inc=False) - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) - * refcount_copying(&dst, dtype_is_object, ndim, inc=True) # <<<<<<<<<<<<<< - * free(tmpdata) - * return 0 - */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1); - - /* "View.MemoryView":1320 - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) - * refcount_copying(&dst, dtype_is_object, ndim, inc=True) - * free(tmpdata) # <<<<<<<<<<<<<< - * return 0 - * - */ - free(__pyx_v_tmpdata); - - /* "View.MemoryView":1321 - * refcount_copying(&dst, dtype_is_object, ndim, inc=True) - * free(tmpdata) - * return 0 # <<<<<<<<<<<<<< - * - * if order == 'F' == get_best_order(&dst, ndim): - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":1315 - * direct_copy = slice_is_contig(dst, 'F', ndim) - * - * if direct_copy: # <<<<<<<<<<<<<< - * - * refcount_copying(&dst, dtype_is_object, ndim, inc=False) - */ - } - - /* "View.MemoryView":1307 - * src = tmp - * - * if not broadcasting: # <<<<<<<<<<<<<< - * - * - */ - } - - /* "View.MemoryView":1323 - * return 0 - * - * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = (__pyx_v_order == 'F'); - if (__pyx_t_2) { - __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim)); - } - if (__pyx_t_2) { - - /* "View.MemoryView":1326 - * - * - * transpose_memslice(&src) # <<<<<<<<<<<<<< - * transpose_memslice(&dst) - * - */ - __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(1, 1326, __pyx_L1_error) - - /* "View.MemoryView":1327 - * - * transpose_memslice(&src) - * transpose_memslice(&dst) # <<<<<<<<<<<<<< - * - * refcount_copying(&dst, dtype_is_object, ndim, inc=False) - */ - __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(1, 1327, __pyx_L1_error) - - /* "View.MemoryView":1323 - * return 0 - * - * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<< - * - * - */ - } - - /* "View.MemoryView":1329 - * transpose_memslice(&dst) - * - * refcount_copying(&dst, dtype_is_object, ndim, inc=False) # <<<<<<<<<<<<<< - * copy_strided_to_strided(&src, &dst, ndim, itemsize) - * refcount_copying(&dst, dtype_is_object, ndim, inc=True) - */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0); - - /* "View.MemoryView":1330 - * - * refcount_copying(&dst, dtype_is_object, ndim, inc=False) - * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<< - * refcount_copying(&dst, dtype_is_object, ndim, inc=True) - * - */ - copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize); - - /* "View.MemoryView":1331 - * refcount_copying(&dst, dtype_is_object, ndim, inc=False) - * copy_strided_to_strided(&src, &dst, ndim, itemsize) - * refcount_copying(&dst, dtype_is_object, ndim, inc=True) # <<<<<<<<<<<<<< - * - * free(tmpdata) - */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1); - - /* "View.MemoryView":1333 - * refcount_copying(&dst, dtype_is_object, ndim, inc=True) - * - * free(tmpdata) # <<<<<<<<<<<<<< - * return 0 - * - */ - free(__pyx_v_tmpdata); - - /* "View.MemoryView":1334 - * - * free(tmpdata) - * return 0 # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_broadcast_leading') - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":1265 - * - * @cname('__pyx_memoryview_copy_contents') - * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice dst, - * int src_ndim, int dst_ndim, - */ - - /* function exit code */ - __pyx_L1_error:; - #ifdef WITH_THREAD - __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1337 - * - * @cname('__pyx_memoryview_broadcast_leading') - * cdef void broadcast_leading(__Pyx_memviewslice *mslice, # <<<<<<<<<<<<<< - * int ndim, - * int ndim_other) noexcept nogil: - */ - -static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim, int __pyx_v_ndim_other) { - int __pyx_v_i; - int __pyx_v_offset; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - - /* "View.MemoryView":1341 - * int ndim_other) noexcept nogil: - * cdef int i - * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<< - * - * for i in range(ndim - 1, -1, -1): - */ - __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim); - - /* "View.MemoryView":1343 - * cdef int offset = ndim_other - ndim - * - * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< - * mslice.shape[i + offset] = mslice.shape[i] - * mslice.strides[i + offset] = mslice.strides[i] - */ - for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) { - __pyx_v_i = __pyx_t_1; - - /* "View.MemoryView":1344 - * - * for i in range(ndim - 1, -1, -1): - * mslice.shape[i + offset] = mslice.shape[i] # <<<<<<<<<<<<<< - * mslice.strides[i + offset] = mslice.strides[i] - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] - */ - (__pyx_v_mslice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->shape[__pyx_v_i]); - - /* "View.MemoryView":1345 - * for i in range(ndim - 1, -1, -1): - * mslice.shape[i + offset] = mslice.shape[i] - * mslice.strides[i + offset] = mslice.strides[i] # <<<<<<<<<<<<<< - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] - * - */ - (__pyx_v_mslice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->strides[__pyx_v_i]); - - /* "View.MemoryView":1346 - * mslice.shape[i + offset] = mslice.shape[i] - * mslice.strides[i + offset] = mslice.strides[i] - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] # <<<<<<<<<<<<<< - * - * for i in range(offset): - */ - (__pyx_v_mslice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->suboffsets[__pyx_v_i]); - } - - /* "View.MemoryView":1348 - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] - * - * for i in range(offset): # <<<<<<<<<<<<<< - * mslice.shape[i] = 1 - * mslice.strides[i] = mslice.strides[0] - */ - __pyx_t_1 = __pyx_v_offset; - __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; - - /* "View.MemoryView":1349 - * - * for i in range(offset): - * mslice.shape[i] = 1 # <<<<<<<<<<<<<< - * mslice.strides[i] = mslice.strides[0] - * mslice.suboffsets[i] = -1 - */ - (__pyx_v_mslice->shape[__pyx_v_i]) = 1; - - /* "View.MemoryView":1350 - * for i in range(offset): - * mslice.shape[i] = 1 - * mslice.strides[i] = mslice.strides[0] # <<<<<<<<<<<<<< - * mslice.suboffsets[i] = -1 - * - */ - (__pyx_v_mslice->strides[__pyx_v_i]) = (__pyx_v_mslice->strides[0]); - - /* "View.MemoryView":1351 - * mslice.shape[i] = 1 - * mslice.strides[i] = mslice.strides[0] - * mslice.suboffsets[i] = -1 # <<<<<<<<<<<<<< - * - * - */ - (__pyx_v_mslice->suboffsets[__pyx_v_i]) = -1L; - } - - /* "View.MemoryView":1337 - * - * @cname('__pyx_memoryview_broadcast_leading') - * cdef void broadcast_leading(__Pyx_memviewslice *mslice, # <<<<<<<<<<<<<< - * int ndim, - * int ndim_other) noexcept nogil: - */ - - /* function exit code */ -} - -/* "View.MemoryView":1359 - * - * @cname('__pyx_memoryview_refcount_copying') - * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, int ndim, bint inc) noexcept nogil: # <<<<<<<<<<<<<< - * - * if dtype_is_object: - */ - -static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) { - - /* "View.MemoryView":1361 - * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, int ndim, bint inc) noexcept nogil: - * - * if dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice_with_gil(dst.data, dst.shape, dst.strides, ndim, inc) - * - */ - if (__pyx_v_dtype_is_object) { - - /* "View.MemoryView":1362 - * - * if dtype_is_object: - * refcount_objects_in_slice_with_gil(dst.data, dst.shape, dst.strides, ndim, inc) # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') - */ - __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc); - - /* "View.MemoryView":1361 - * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, int ndim, bint inc) noexcept nogil: - * - * if dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice_with_gil(dst.data, dst.shape, dst.strides, ndim, inc) - * - */ - } - - /* "View.MemoryView":1359 - * - * @cname('__pyx_memoryview_refcount_copying') - * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, int ndim, bint inc) noexcept nogil: # <<<<<<<<<<<<<< - * - * if dtype_is_object: - */ - - /* function exit code */ -} - -/* "View.MemoryView":1365 - * - * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') - * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * bint inc) noexcept with gil: - */ - -static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) { - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - - /* "View.MemoryView":1368 - * Py_ssize_t *strides, int ndim, - * bint inc) noexcept with gil: - * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_refcount_objects_in_slice') - */ - __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc); - - /* "View.MemoryView":1365 - * - * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') - * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * bint inc) noexcept with gil: - */ - - /* function exit code */ - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif -} - -/* "View.MemoryView":1371 - * - * @cname('__pyx_memoryview_refcount_objects_in_slice') - * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, bint inc) noexcept: - * cdef Py_ssize_t i - */ - -static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) { - CYTHON_UNUSED Py_ssize_t __pyx_v_i; - Py_ssize_t __pyx_v_stride; - Py_ssize_t __pyx_t_1; - Py_ssize_t __pyx_t_2; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - - /* "View.MemoryView":1374 - * Py_ssize_t *strides, int ndim, bint inc) noexcept: - * cdef Py_ssize_t i - * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<< - * - * for i in range(shape[0]): - */ - __pyx_v_stride = (__pyx_v_strides[0]); - - /* "View.MemoryView":1376 - * cdef Py_ssize_t stride = strides[0] - * - * for i in range(shape[0]): # <<<<<<<<<<<<<< - * if ndim == 1: - * if inc: - */ - __pyx_t_1 = (__pyx_v_shape[0]); - __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; - - /* "View.MemoryView":1377 - * - * for i in range(shape[0]): - * if ndim == 1: # <<<<<<<<<<<<<< - * if inc: - * Py_INCREF(( data)[0]) - */ - __pyx_t_4 = (__pyx_v_ndim == 1); - if (__pyx_t_4) { - - /* "View.MemoryView":1378 - * for i in range(shape[0]): - * if ndim == 1: - * if inc: # <<<<<<<<<<<<<< - * Py_INCREF(( data)[0]) - * else: - */ - if (__pyx_v_inc) { - - /* "View.MemoryView":1379 - * if ndim == 1: - * if inc: - * Py_INCREF(( data)[0]) # <<<<<<<<<<<<<< - * else: - * Py_DECREF(( data)[0]) - */ - Py_INCREF((((PyObject **)__pyx_v_data)[0])); - - /* "View.MemoryView":1378 - * for i in range(shape[0]): - * if ndim == 1: - * if inc: # <<<<<<<<<<<<<< - * Py_INCREF(( data)[0]) - * else: - */ - goto __pyx_L6; - } - - /* "View.MemoryView":1381 - * Py_INCREF(( data)[0]) - * else: - * Py_DECREF(( data)[0]) # <<<<<<<<<<<<<< - * else: - * refcount_objects_in_slice(data, shape + 1, strides + 1, ndim - 1, inc) - */ - /*else*/ { - Py_DECREF((((PyObject **)__pyx_v_data)[0])); - } - __pyx_L6:; - - /* "View.MemoryView":1377 - * - * for i in range(shape[0]): - * if ndim == 1: # <<<<<<<<<<<<<< - * if inc: - * Py_INCREF(( data)[0]) - */ - goto __pyx_L5; - } - - /* "View.MemoryView":1383 - * Py_DECREF(( data)[0]) - * else: - * refcount_objects_in_slice(data, shape + 1, strides + 1, ndim - 1, inc) # <<<<<<<<<<<<<< - * - * data += stride - */ - /*else*/ { - __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc); - } - __pyx_L5:; - - /* "View.MemoryView":1385 - * refcount_objects_in_slice(data, shape + 1, strides + 1, ndim - 1, inc) - * - * data += stride # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_data = (__pyx_v_data + __pyx_v_stride); - } - - /* "View.MemoryView":1371 - * - * @cname('__pyx_memoryview_refcount_objects_in_slice') - * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, bint inc) noexcept: - * cdef Py_ssize_t i - */ - - /* function exit code */ -} - -/* "View.MemoryView":1391 - * - * @cname('__pyx_memoryview_slice_assign_scalar') - * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<< - * size_t itemsize, void *item, - * bint dtype_is_object) noexcept nogil: - */ - -static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) { - - /* "View.MemoryView":1394 - * size_t itemsize, void *item, - * bint dtype_is_object) noexcept nogil: - * refcount_copying(dst, dtype_is_object, ndim, inc=False) # <<<<<<<<<<<<<< - * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, itemsize, item) - * refcount_copying(dst, dtype_is_object, ndim, inc=True) - */ - __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0); - - /* "View.MemoryView":1395 - * bint dtype_is_object) noexcept nogil: - * refcount_copying(dst, dtype_is_object, ndim, inc=False) - * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, itemsize, item) # <<<<<<<<<<<<<< - * refcount_copying(dst, dtype_is_object, ndim, inc=True) - * - */ - __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item); - - /* "View.MemoryView":1396 - * refcount_copying(dst, dtype_is_object, ndim, inc=False) - * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, itemsize, item) - * refcount_copying(dst, dtype_is_object, ndim, inc=True) # <<<<<<<<<<<<<< - * - * - */ - __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1); - - /* "View.MemoryView":1391 - * - * @cname('__pyx_memoryview_slice_assign_scalar') - * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<< - * size_t itemsize, void *item, - * bint dtype_is_object) noexcept nogil: - */ - - /* function exit code */ -} - -/* "View.MemoryView":1400 - * - * @cname('__pyx_memoryview__slice_assign_scalar') - * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * size_t itemsize, void *item) noexcept nogil: - */ - -static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) { - CYTHON_UNUSED Py_ssize_t __pyx_v_i; - Py_ssize_t __pyx_v_stride; - Py_ssize_t __pyx_v_extent; - int __pyx_t_1; - Py_ssize_t __pyx_t_2; - Py_ssize_t __pyx_t_3; - Py_ssize_t __pyx_t_4; - - /* "View.MemoryView":1404 - * size_t itemsize, void *item) noexcept nogil: - * cdef Py_ssize_t i - * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t extent = shape[0] - * - */ - __pyx_v_stride = (__pyx_v_strides[0]); - - /* "View.MemoryView":1405 - * cdef Py_ssize_t i - * cdef Py_ssize_t stride = strides[0] - * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<< - * - * if ndim == 1: - */ - __pyx_v_extent = (__pyx_v_shape[0]); - - /* "View.MemoryView":1407 - * cdef Py_ssize_t extent = shape[0] - * - * if ndim == 1: # <<<<<<<<<<<<<< - * for i in range(extent): - * memcpy(data, item, itemsize) - */ - __pyx_t_1 = (__pyx_v_ndim == 1); - if (__pyx_t_1) { - - /* "View.MemoryView":1408 - * - * if ndim == 1: - * for i in range(extent): # <<<<<<<<<<<<<< - * memcpy(data, item, itemsize) - * data += stride - */ - __pyx_t_2 = __pyx_v_extent; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; - - /* "View.MemoryView":1409 - * if ndim == 1: - * for i in range(extent): - * memcpy(data, item, itemsize) # <<<<<<<<<<<<<< - * data += stride - * else: - */ - (void)(memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize)); - - /* "View.MemoryView":1410 - * for i in range(extent): - * memcpy(data, item, itemsize) - * data += stride # <<<<<<<<<<<<<< - * else: - * for i in range(extent): - */ - __pyx_v_data = (__pyx_v_data + __pyx_v_stride); - } - - /* "View.MemoryView":1407 - * cdef Py_ssize_t extent = shape[0] - * - * if ndim == 1: # <<<<<<<<<<<<<< - * for i in range(extent): - * memcpy(data, item, itemsize) - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1412 - * data += stride - * else: - * for i in range(extent): # <<<<<<<<<<<<<< - * _slice_assign_scalar(data, shape + 1, strides + 1, ndim - 1, itemsize, item) - * data += stride - */ - /*else*/ { - __pyx_t_2 = __pyx_v_extent; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; - - /* "View.MemoryView":1413 - * else: - * for i in range(extent): - * _slice_assign_scalar(data, shape + 1, strides + 1, ndim - 1, itemsize, item) # <<<<<<<<<<<<<< - * data += stride - * - */ - __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item); - - /* "View.MemoryView":1414 - * for i in range(extent): - * _slice_assign_scalar(data, shape + 1, strides + 1, ndim - 1, itemsize, item) - * data += stride # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_data = (__pyx_v_data + __pyx_v_stride); - } - } - __pyx_L3:; - - /* "View.MemoryView":1400 - * - * @cname('__pyx_memoryview__slice_assign_scalar') - * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * size_t itemsize, void *item) noexcept nogil: - */ - - /* function exit code */ -} - -/* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum(PyObject *__pyx_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*/ -static PyMethodDef __pyx_mdef_15View_dot_MemoryView_1__pyx_unpickle_Enum = {"__pyx_unpickle_Enum", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; -static PyObject *__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum(PyObject *__pyx_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___pyx_type = 0; - long __pyx_v___pyx_checksum; - PyObject *__pyx_v___pyx_state = 0; - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[3] = {0,0,0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__pyx_unpickle_Enum (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_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); - CYTHON_FALLTHROUGH; - 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_pyx_type)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 1, __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_pyx_checksum)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, 1); __PYX_ERR(1, 1, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pyx_state)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, 2); __PYX_ERR(1, 1, __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, "__pyx_unpickle_Enum") < 0)) __PYX_ERR(1, 1, __pyx_L3_error) - } - } else if (unlikely(__pyx_nargs != 3)) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); - values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); - } - __pyx_v___pyx_type = values[0]; - __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) - __pyx_v___pyx_state = values[2]; - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, __pyx_nargs); __PYX_ERR(1, 1, __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("View.MemoryView.__pyx_unpickle_Enum", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_15View_dot_MemoryView___pyx_unpickle_Enum(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); - - /* 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_15View_dot_MemoryView___pyx_unpickle_Enum(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = 0; - PyObject *__pyx_v___pyx_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_Enum", 1); - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum not in (0x82a3537, 0x6ae9995, 0xb068931): # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum - */ - __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_t_1, __pyx_tuple__8, Py_NE)); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (__pyx_t_2) { - - /* "(tree fragment)":5 - * cdef object __pyx_result - * if __pyx_checksum not in (0x82a3537, 0x6ae9995, 0xb068931): - * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< - * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum - * __pyx_result = Enum.__new__(__pyx_type) - */ - __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_s_PickleError); - __Pyx_GIVEREF(__pyx_n_s_PickleError); - if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_PickleError)) __PYX_ERR(1, 5, __pyx_L1_error); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_t_1); - __pyx_v___pyx_PickleError = __pyx_t_1; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":6 - * if __pyx_checksum not in (0x82a3537, 0x6ae9995, 0xb068931): - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum # <<<<<<<<<<<<<< - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: - */ - __pyx_t_3 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_0x_x_vs_0, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_v___pyx_PickleError, __pyx_t_1, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(1, 6, __pyx_L1_error) - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum not in (0x82a3537, 0x6ae9995, 0xb068931): # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum - */ - } - - /* "(tree fragment)":7 - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum - * __pyx_result = Enum.__new__(__pyx_type) # <<<<<<<<<<<<<< - * if __pyx_state is not None: - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_MemviewEnum_type), __pyx_n_s_new); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = NULL; - __pyx_t_5 = 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_5 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v___pyx_type}; - __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_v___pyx_result = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - __pyx_t_2 = (__pyx_v___pyx_state != Py_None); - if (__pyx_t_2) { - - /* "(tree fragment)":9 - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None) || __Pyx_RaiseUnexpectedTypeError("tuple", __pyx_v___pyx_state))) __PYX_ERR(1, 9, __pyx_L1_error) - __pyx_t_1 = __pyx_unpickle_Enum__set_state(((struct __pyx_MemviewEnum_obj *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - } - - /* "(tree fragment)":10 - * if __pyx_state is not None: - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result # <<<<<<<<<<<<<< - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v___pyx_result); - __pyx_r = __pyx_v___pyx_result; - goto __pyx_L0; - - /* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView.__pyx_unpickle_Enum", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v___pyx_PickleError); - __Pyx_XDECREF(__pyx_v___pyx_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":11 - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - */ - -static PyObject *__pyx_unpickle_Enum__set_state(struct __pyx_MemviewEnum_obj *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_Enum__set_state", 1); - - /* "(tree fragment)":12 - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] # <<<<<<<<<<<<<< - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[1]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->name); - __Pyx_DECREF(__pyx_v___pyx_result->name); - __pyx_v___pyx_result->name = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[1]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(1, 13, __pyx_L1_error) - } - __pyx_t_3 = __Pyx_PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) - __pyx_t_4 = (__pyx_t_3 > 1); - if (__pyx_t_4) { - } else { - __pyx_t_2 = __pyx_t_4; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) - __pyx_t_2 = __pyx_t_4; - __pyx_L4_bool_binop_done:; - if (__pyx_t_2) { - - /* "(tree fragment)":14 - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[1]) # <<<<<<<<<<<<<< - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_update); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 14, __pyx_L1_error) - } - __pyx_t_5 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_7 = NULL; - __pyx_t_8 = 0; - #if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(__pyx_t_6))) { - __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6); - if (likely(__pyx_t_7)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); - __Pyx_INCREF(__pyx_t_7); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_6, function); - __pyx_t_8 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[2] = {__pyx_t_7, __pyx_t_5}; - __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_8, 1+__pyx_t_8); - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[1]) - */ - } - - /* "(tree fragment)":11 - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("View.MemoryView.__pyx_unpickle_Enum__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":286 - * - * @property - * cdef inline npy_intp itemsize(self) noexcept nogil: # <<<<<<<<<<<<<< - * return PyDataType_ELSIZE(self) - * - */ - -static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_8itemsize_itemsize(PyArray_Descr *__pyx_v_self) { - npy_intp __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":287 - * @property - * cdef inline npy_intp itemsize(self) noexcept nogil: - * return PyDataType_ELSIZE(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyDataType_ELSIZE(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":286 - * - * @property - * cdef inline npy_intp itemsize(self) noexcept nogil: # <<<<<<<<<<<<<< - * return PyDataType_ELSIZE(self) - * - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":290 - * - * @property - * cdef inline npy_intp alignment(self) noexcept nogil: # <<<<<<<<<<<<<< - * return PyDataType_ALIGNMENT(self) - * - */ - -static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_9alignment_alignment(PyArray_Descr *__pyx_v_self) { - npy_intp __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":291 - * @property - * cdef inline npy_intp alignment(self) noexcept nogil: - * return PyDataType_ALIGNMENT(self) # <<<<<<<<<<<<<< - * - * # Use fields/names with care as they may be NULL. You must check - */ - __pyx_r = PyDataType_ALIGNMENT(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":290 - * - * @property - * cdef inline npy_intp alignment(self) noexcept nogil: # <<<<<<<<<<<<<< - * return PyDataType_ALIGNMENT(self) - * - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":296 - * # for this using PyDataType_HASFIELDS. - * @property - * cdef inline object fields(self): # <<<<<<<<<<<<<< - * return PyDataType_FIELDS(self) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_6fields_fields(PyArray_Descr *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1; - __Pyx_RefNannySetupContext("fields", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":297 - * @property - * cdef inline object fields(self): - * return PyDataType_FIELDS(self) # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyDataType_FIELDS(__pyx_v_self); - __Pyx_INCREF(((PyObject *)__pyx_t_1)); - __pyx_r = ((PyObject *)__pyx_t_1); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":296 - * # for this using PyDataType_HASFIELDS. - * @property - * cdef inline object fields(self): # <<<<<<<<<<<<<< - * return PyDataType_FIELDS(self) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":300 - * - * @property - * cdef inline tuple names(self): # <<<<<<<<<<<<<< - * return PyDataType_NAMES(self) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_5names_names(PyArray_Descr *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1; - __Pyx_RefNannySetupContext("names", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":301 - * @property - * cdef inline tuple names(self): - * return PyDataType_NAMES(self) # <<<<<<<<<<<<<< - * - * # Use PyDataType_HASSUBARRAY to test whether this field is - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyDataType_NAMES(__pyx_v_self); - __Pyx_INCREF(((PyObject*)__pyx_t_1)); - __pyx_r = ((PyObject*)__pyx_t_1); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":300 - * - * @property - * cdef inline tuple names(self): # <<<<<<<<<<<<<< - * return PyDataType_NAMES(self) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":307 - * # this field via the inline helper method PyDataType_SHAPE. - * @property - * cdef inline PyArray_ArrayDescr* subarray(self) noexcept nogil: # <<<<<<<<<<<<<< - * return PyDataType_SUBARRAY(self) - * - */ - -static CYTHON_INLINE PyArray_ArrayDescr *__pyx_f_5numpy_5dtype_8subarray_subarray(PyArray_Descr *__pyx_v_self) { - PyArray_ArrayDescr *__pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":308 - * @property - * cdef inline PyArray_ArrayDescr* subarray(self) noexcept nogil: - * return PyDataType_SUBARRAY(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyDataType_SUBARRAY(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":307 - * # this field via the inline helper method PyDataType_SHAPE. - * @property - * cdef inline PyArray_ArrayDescr* subarray(self) noexcept nogil: # <<<<<<<<<<<<<< - * return PyDataType_SUBARRAY(self) - * - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":311 - * - * @property - * cdef inline npy_uint64 flags(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The data types flags.""" - * return PyDataType_FLAGS(self) - */ - -static CYTHON_INLINE npy_uint64 __pyx_f_5numpy_5dtype_5flags_flags(PyArray_Descr *__pyx_v_self) { - npy_uint64 __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":313 - * cdef inline npy_uint64 flags(self) noexcept nogil: - * """The data types flags.""" - * return PyDataType_FLAGS(self) # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = PyDataType_FLAGS(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":311 - * - * @property - * cdef inline npy_uint64 flags(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The data types flags.""" - * return PyDataType_FLAGS(self) - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":323 - * - * @property - * cdef inline int numiter(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The number of arrays that need to be broadcast to the same shape.""" - * return PyArray_MultiIter_NUMITER(self) - */ - -static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_7numiter_numiter(PyArrayMultiIterObject *__pyx_v_self) { - int __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":325 - * cdef inline int numiter(self) noexcept nogil: - * """The number of arrays that need to be broadcast to the same shape.""" - * return PyArray_MultiIter_NUMITER(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyArray_MultiIter_NUMITER(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":323 - * - * @property - * cdef inline int numiter(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The number of arrays that need to be broadcast to the same shape.""" - * return PyArray_MultiIter_NUMITER(self) - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":328 - * - * @property - * cdef inline npy_intp size(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The total broadcasted size.""" - * return PyArray_MultiIter_SIZE(self) - */ - -static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_4size_size(PyArrayMultiIterObject *__pyx_v_self) { - npy_intp __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":330 - * cdef inline npy_intp size(self) noexcept nogil: - * """The total broadcasted size.""" - * return PyArray_MultiIter_SIZE(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyArray_MultiIter_SIZE(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":328 - * - * @property - * cdef inline npy_intp size(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The total broadcasted size.""" - * return PyArray_MultiIter_SIZE(self) - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":333 - * - * @property - * cdef inline npy_intp index(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The current (1-d) index into the broadcasted result.""" - * return PyArray_MultiIter_INDEX(self) - */ - -static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_5index_index(PyArrayMultiIterObject *__pyx_v_self) { - npy_intp __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":335 - * cdef inline npy_intp index(self) noexcept nogil: - * """The current (1-d) index into the broadcasted result.""" - * return PyArray_MultiIter_INDEX(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyArray_MultiIter_INDEX(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":333 - * - * @property - * cdef inline npy_intp index(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The current (1-d) index into the broadcasted result.""" - * return PyArray_MultiIter_INDEX(self) - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":338 - * - * @property - * cdef inline int nd(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The number of dimensions in the broadcasted result.""" - * return PyArray_MultiIter_NDIM(self) - */ - -static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_2nd_nd(PyArrayMultiIterObject *__pyx_v_self) { - int __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":340 - * cdef inline int nd(self) noexcept nogil: - * """The number of dimensions in the broadcasted result.""" - * return PyArray_MultiIter_NDIM(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyArray_MultiIter_NDIM(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":338 - * - * @property - * cdef inline int nd(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The number of dimensions in the broadcasted result.""" - * return PyArray_MultiIter_NDIM(self) - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":343 - * - * @property - * cdef inline npy_intp* dimensions(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The shape of the broadcasted result.""" - * return PyArray_MultiIter_DIMS(self) - */ - -static CYTHON_INLINE npy_intp *__pyx_f_5numpy_9broadcast_10dimensions_dimensions(PyArrayMultiIterObject *__pyx_v_self) { - npy_intp *__pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":345 - * cdef inline npy_intp* dimensions(self) noexcept nogil: - * """The shape of the broadcasted result.""" - * return PyArray_MultiIter_DIMS(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyArray_MultiIter_DIMS(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":343 - * - * @property - * cdef inline npy_intp* dimensions(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The shape of the broadcasted result.""" - * return PyArray_MultiIter_DIMS(self) - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":348 - * - * @property - * cdef inline void** iters(self) noexcept nogil: # <<<<<<<<<<<<<< - * """An array of iterator objects that holds the iterators for the arrays to be broadcast together. - * On return, the iterators are adjusted for broadcasting.""" - */ - -static CYTHON_INLINE void **__pyx_f_5numpy_9broadcast_5iters_iters(PyArrayMultiIterObject *__pyx_v_self) { - void **__pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":351 - * """An array of iterator objects that holds the iterators for the arrays to be broadcast together. - * On return, the iterators are adjusted for broadcasting.""" - * return PyArray_MultiIter_ITERS(self) # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = PyArray_MultiIter_ITERS(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":348 - * - * @property - * cdef inline void** iters(self) noexcept nogil: # <<<<<<<<<<<<<< - * """An array of iterator objects that holds the iterators for the arrays to be broadcast together. - * On return, the iterators are adjusted for broadcasting.""" - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":366 - * - * @property - * cdef inline PyObject* base(self) noexcept nogil: # <<<<<<<<<<<<<< - * """Returns a borrowed reference to the object owning the data/memory. - * """ - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject *__pyx_v_self) { - PyObject *__pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":369 - * """Returns a borrowed reference to the object owning the data/memory. - * """ - * return PyArray_BASE(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyArray_BASE(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":366 - * - * @property - * cdef inline PyObject* base(self) noexcept nogil: # <<<<<<<<<<<<<< - * """Returns a borrowed reference to the object owning the data/memory. - * """ - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":372 - * - * @property - * cdef inline dtype descr(self): # <<<<<<<<<<<<<< - * """Returns an owned reference to the dtype of the array. - * """ - */ - -static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArrayObject *__pyx_v_self) { - PyArray_Descr *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyArray_Descr *__pyx_t_1; - __Pyx_RefNannySetupContext("descr", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":375 - * """Returns an owned reference to the dtype of the array. - * """ - * return PyArray_DESCR(self) # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF((PyObject *)__pyx_r); - __pyx_t_1 = PyArray_DESCR(__pyx_v_self); - __Pyx_INCREF((PyObject *)((PyArray_Descr *)__pyx_t_1)); - __pyx_r = ((PyArray_Descr *)__pyx_t_1); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":372 - * - * @property - * cdef inline dtype descr(self): # <<<<<<<<<<<<<< - * """Returns an owned reference to the dtype of the array. - * """ - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF((PyObject *)__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":378 - * - * @property - * cdef inline int ndim(self) noexcept nogil: # <<<<<<<<<<<<<< - * """Returns the number of dimensions in the array. - * """ - */ - -static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx_v_self) { - int __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":381 - * """Returns the number of dimensions in the array. - * """ - * return PyArray_NDIM(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyArray_NDIM(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":378 - * - * @property - * cdef inline int ndim(self) noexcept nogil: # <<<<<<<<<<<<<< - * """Returns the number of dimensions in the array. - * """ - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":384 - * - * @property - * cdef inline npy_intp *shape(self) noexcept nogil: # <<<<<<<<<<<<<< - * """Returns a pointer to the dimensions/shape of the array. - * The number of elements matches the number of dimensions of the array (ndim). - */ - -static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObject *__pyx_v_self) { - npy_intp *__pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":389 - * Can return NULL for 0-dimensional arrays. - * """ - * return PyArray_DIMS(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyArray_DIMS(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":384 - * - * @property - * cdef inline npy_intp *shape(self) noexcept nogil: # <<<<<<<<<<<<<< - * """Returns a pointer to the dimensions/shape of the array. - * The number of elements matches the number of dimensions of the array (ndim). - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":392 - * - * @property - * cdef inline npy_intp *strides(self) noexcept nogil: # <<<<<<<<<<<<<< - * """Returns a pointer to the strides of the array. - * The number of elements matches the number of dimensions of the array (ndim). - */ - -static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayObject *__pyx_v_self) { - npy_intp *__pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":396 - * The number of elements matches the number of dimensions of the array (ndim). - * """ - * return PyArray_STRIDES(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyArray_STRIDES(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":392 - * - * @property - * cdef inline npy_intp *strides(self) noexcept nogil: # <<<<<<<<<<<<<< - * """Returns a pointer to the strides of the array. - * The number of elements matches the number of dimensions of the array (ndim). - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":399 - * - * @property - * cdef inline npy_intp size(self) noexcept nogil: # <<<<<<<<<<<<<< - * """Returns the total size (in number of elements) of the array. - * """ - */ - -static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject *__pyx_v_self) { - npy_intp __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":402 - * """Returns the total size (in number of elements) of the array. - * """ - * return PyArray_SIZE(self) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_r = PyArray_SIZE(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":399 - * - * @property - * cdef inline npy_intp size(self) noexcept nogil: # <<<<<<<<<<<<<< - * """Returns the total size (in number of elements) of the array. - * """ - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":405 - * - * @property - * cdef inline char* data(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The pointer to the data buffer as a char*. - * This is provided for legacy reasons to avoid direct struct field access. - */ - -static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__pyx_v_self) { - char *__pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":411 - * of `PyArray_DATA()` instead, which returns a 'void*'. - * """ - * return PyArray_BYTES(self) # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = PyArray_BYTES(__pyx_v_self); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":405 - * - * @property - * cdef inline char* data(self) noexcept nogil: # <<<<<<<<<<<<<< - * """The pointer to the data buffer as a char*. - * This is provided for legacy reasons to avoid direct struct field access. - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":807 - * ctypedef long double complex clongdouble_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":808 - * - * cdef inline object PyArray_MultiIterNew1(a): - * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew2(a, b): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 808, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":807 - * ctypedef long double complex clongdouble_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":810 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":811 - * - * cdef inline object PyArray_MultiIterNew2(a, b): - * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 811, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":810 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":813 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":814 - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): - * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 814, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":813 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":816 - * return PyArray_MultiIterNew(3, a, b, c) - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(4, a, b, c, d) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":817 - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): - * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 817, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":816 - * return PyArray_MultiIterNew(3, a, b, c) - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(4, a, b, c, d) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":819 - * return PyArray_MultiIterNew(4, a, b, c, d) - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":820 - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): - * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 820, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":819 - * return PyArray_MultiIterNew(4, a, b, c, d) - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":822 - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__pyx_v_d) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2; - __Pyx_RefNannySetupContext("PyDataType_SHAPE", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":823 - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< - * return d.subarray.shape - * else: - */ - __pyx_t_1 = PyDataType_HASSUBARRAY(__pyx_v_d); - if (__pyx_t_1) { - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":824 - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape # <<<<<<<<<<<<<< - * else: - * return () - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_f_5numpy_5dtype_8subarray_subarray(__pyx_v_d)->shape; - __Pyx_INCREF(((PyObject*)__pyx_t_2)); - __pyx_r = ((PyObject*)__pyx_t_2); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":823 - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< - * return d.subarray.shape - * else: - */ - } - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":826 - * return d.subarray.shape - * else: - * return () # <<<<<<<<<<<<<< - * - * - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_empty_tuple); - __pyx_r = __pyx_empty_tuple; - goto __pyx_L0; - } - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":822 - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1010 - * int _import_umath() except -1 - * - * cdef inline void set_array_base(ndarray arr, object base) except *: # <<<<<<<<<<<<<< - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) - */ - -static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { - int __pyx_t_1; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1011 - * - * cdef inline void set_array_base(ndarray arr, object base) except *: - * Py_INCREF(base) # important to do this before stealing the reference below! # <<<<<<<<<<<<<< - * PyArray_SetBaseObject(arr, base) - * - */ - Py_INCREF(__pyx_v_base); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1012 - * cdef inline void set_array_base(ndarray arr, object base) except *: - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) # <<<<<<<<<<<<<< - * - * cdef inline object get_array_base(ndarray arr): - */ - __pyx_t_1 = PyArray_SetBaseObject(__pyx_v_arr, __pyx_v_base); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(2, 1012, __pyx_L1_error) - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1010 - * int _import_umath() except -1 - * - * cdef inline void set_array_base(ndarray arr, object base) except *: # <<<<<<<<<<<<<< - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) - */ - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_AddTraceback("numpy.set_array_base", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_L0:; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1014 - * PyArray_SetBaseObject(arr, base) - * - * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< - * base = PyArray_BASE(arr) - * if base is NULL: - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { - PyObject *__pyx_v_base; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("get_array_base", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1015 - * - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) # <<<<<<<<<<<<<< - * if base is NULL: - * return None - */ - __pyx_v_base = PyArray_BASE(__pyx_v_arr); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1016 - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) - * if base is NULL: # <<<<<<<<<<<<<< - * return None - * return base - */ - __pyx_t_1 = (__pyx_v_base == NULL); - if (__pyx_t_1) { - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1017 - * base = PyArray_BASE(arr) - * if base is NULL: - * return None # <<<<<<<<<<<<<< - * return base - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1016 - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) - * if base is NULL: # <<<<<<<<<<<<<< - * return None - * return base - */ - } - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1018 - * if base is NULL: - * return None - * return base # <<<<<<<<<<<<<< - * - * # Versions of the import_* functions which are more suitable for - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_base)); - __pyx_r = ((PyObject *)__pyx_v_base); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1014 - * PyArray_SetBaseObject(arr, base) - * - * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< - * base = PyArray_BASE(arr) - * if base is NULL: - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1022 - * # Versions of the import_* functions which are more suitable for - * # Cython code. - * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< - * try: - * __pyx_import_array() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("import_array", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1023 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * __pyx_import_array() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1024 - * cdef inline int import_array() except -1: - * try: - * __pyx_import_array() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy._core.multiarray failed to import") - */ - __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1024, __pyx_L3_error) - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1023 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * __pyx_import_array() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1025 - * try: - * __pyx_import_array() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy._core.multiarray failed to import") - * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1025, __pyx_L5_except_error) - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1026 - * __pyx_import_array() - * except Exception: - * raise ImportError("numpy._core.multiarray failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_umath() except -1: - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1026, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(2, 1026, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1023 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * __pyx_import_array() - * except Exception: - */ - __pyx_L5_except_error:; - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1022 - * # Versions of the import_* functions which are more suitable for - * # Cython code. - * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< - * try: - * __pyx_import_array() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1028 - * raise ImportError("numpy._core.multiarray failed to import") - * - * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("import_umath", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1029 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1030 - * cdef inline int import_umath() except -1: - * try: - * _import_umath() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy._core.umath failed to import") - */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1030, __pyx_L3_error) - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1029 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1031 - * try: - * _import_umath() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy._core.umath failed to import") - * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1031, __pyx_L5_except_error) - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1032 - * _import_umath() - * except Exception: - * raise ImportError("numpy._core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_ufunc() except -1: - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1032, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(2, 1032, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1029 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - __pyx_L5_except_error:; - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1028 - * raise ImportError("numpy._core.multiarray failed to import") - * - * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1034 - * raise ImportError("numpy._core.umath failed to import") - * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("import_ufunc", 1); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1035 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1036 - * cdef inline int import_ufunc() except -1: - * try: - * _import_umath() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy._core.umath failed to import") - */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1036, __pyx_L3_error) - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1035 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1037 - * try: - * _import_umath() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy._core.umath failed to import") - * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1037, __pyx_L5_except_error) - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1038 - * _import_umath() - * except Exception: - * raise ImportError("numpy._core.umath failed to import") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1038, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(2, 1038, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1035 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - __pyx_L5_except_error:; - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1034 - * raise ImportError("numpy._core.umath failed to import") - * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1041 - * - * - * cdef inline bint is_timedelta64_object(object obj) noexcept: # <<<<<<<<<<<<<< - * """ - * Cython equivalent of `isinstance(obj, np.timedelta64)` - */ - -static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_obj) { - int __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1053 - * bool - * """ - * return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type) # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyTimedeltaArrType_Type)); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1041 - * - * - * cdef inline bint is_timedelta64_object(object obj) noexcept: # <<<<<<<<<<<<<< - * """ - * Cython equivalent of `isinstance(obj, np.timedelta64)` - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1056 - * - * - * cdef inline bint is_datetime64_object(object obj) noexcept: # <<<<<<<<<<<<<< - * """ - * Cython equivalent of `isinstance(obj, np.datetime64)` - */ - -static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_obj) { - int __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1068 - * bool - * """ - * return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type) # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyDatetimeArrType_Type)); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1056 - * - * - * cdef inline bint is_datetime64_object(object obj) noexcept: # <<<<<<<<<<<<<< - * """ - * Cython equivalent of `isinstance(obj, np.datetime64)` - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1071 - * - * - * cdef inline npy_datetime get_datetime64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< - * """ - * returns the int64 value underlying scalar numpy datetime64 object - */ - -static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject *__pyx_v_obj) { - npy_datetime __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1078 - * also needed. That can be found using `get_datetime64_unit`. - * """ - * return (obj).obval # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = ((PyDatetimeScalarObject *)__pyx_v_obj)->obval; - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1071 - * - * - * cdef inline npy_datetime get_datetime64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< - * """ - * returns the int64 value underlying scalar numpy datetime64 object - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1081 - * - * - * cdef inline npy_timedelta get_timedelta64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< - * """ - * returns the int64 value underlying scalar numpy timedelta64 object - */ - -static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject *__pyx_v_obj) { - npy_timedelta __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1085 - * returns the int64 value underlying scalar numpy timedelta64 object - * """ - * return (obj).obval # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = ((PyTimedeltaScalarObject *)__pyx_v_obj)->obval; - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1081 - * - * - * cdef inline npy_timedelta get_timedelta64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< - * """ - * returns the int64 value underlying scalar numpy timedelta64 object - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1088 - * - * - * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) noexcept nogil: # <<<<<<<<<<<<<< - * """ - * returns the unit part of the dtype for a numpy datetime64 object. - */ - -static CYTHON_INLINE NPY_DATETIMEUNIT __pyx_f_5numpy_get_datetime64_unit(PyObject *__pyx_v_obj) { - NPY_DATETIMEUNIT __pyx_r; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1092 - * returns the unit part of the dtype for a numpy datetime64 object. - * """ - * return (obj).obmeta.base # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = ((NPY_DATETIMEUNIT)((PyDatetimeScalarObject *)__pyx_v_obj)->obmeta.base); - goto __pyx_L0; - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1088 - * - * - * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) noexcept nogil: # <<<<<<<<<<<<<< - * """ - * returns the unit part of the dtype for a numpy datetime64 object. - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "pygom/model/_tau_leap.pyx":8 - * cimport cython - * - * @cython.boundscheck(False) # Deactivate bounds checking # <<<<<<<<<<<<<< - * @cython.wraparound(False) # Deactivate negative indexing. - * @cython.cdivision(True) # Deactivate the div 0 error checking - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety(PyObject *__pyx_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_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety, "\n Additional safety test on :math:`\\tau`-leap, decrease the step size if\n the original is not small enough. Decrease a couple of times and then\n bail out because we don't want to spend too long decreasing the\n step size until we find a suitable one.\n "); -static PyMethodDef __pyx_mdef_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety = {"_cy_test_tau_leap_safety", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety}; -static PyObject *__pyx_pw_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety(PyObject *__pyx_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 -) { - PyArrayObject *__pyx_v_x = 0; - PyArrayObject *__pyx_v_reactant_mat = 0; - PyArrayObject *__pyx_v_rates = 0; - double __pyx_v_tau_scale; - double __pyx_v_epsilon; - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[5] = {0,0,0,0,0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_cy_test_tau_leap_safety (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_reactant_mat,&__pyx_n_s_rates,&__pyx_n_s_tau_scale,&__pyx_n_s_epsilon,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); - CYTHON_FALLTHROUGH; - 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, 8, __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_reactant_mat)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 8, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 1); __PYX_ERR(0, 8, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_rates)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 8, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 2); __PYX_ERR(0, 8, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_tau_scale)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 8, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 3); __PYX_ERR(0, 8, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 4: - if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_epsilon)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 8, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, 4); __PYX_ERR(0, 8, __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, "_cy_test_tau_leap_safety") < 0)) __PYX_ERR(0, 8, __pyx_L3_error) - } - } else if (unlikely(__pyx_nargs != 5)) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); - values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); - values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); - values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); - } - __pyx_v_x = ((PyArrayObject *)values[0]); - __pyx_v_reactant_mat = ((PyArrayObject *)values[1]); - __pyx_v_rates = ((PyArrayObject *)values[2]); - __pyx_v_tau_scale = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_tau_scale == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error) - __pyx_v_epsilon = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_epsilon == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 15, __pyx_L3_error) - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("_cy_test_tau_leap_safety", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 8, __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("pygom.model._tau_leap._cy_test_tau_leap_safety", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_x), __pyx_ptype_5numpy_ndarray, 1, "x", 0))) __PYX_ERR(0, 11, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_reactant_mat), __pyx_ptype_5numpy_ndarray, 1, "reactant_mat", 0))) __PYX_ERR(0, 12, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rates), __pyx_ptype_5numpy_ndarray, 1, "rates", 0))) __PYX_ERR(0, 13, __pyx_L1_error) - __pyx_r = __pyx_pf_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(__pyx_self, __pyx_v_x, __pyx_v_reactant_mat, __pyx_v_rates, __pyx_v_tau_scale, __pyx_v_epsilon); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - { - 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_5pygom_5model_9_tau_leap__cy_test_tau_leap_safety(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_x, PyArrayObject *__pyx_v_reactant_mat, PyArrayObject *__pyx_v_rates, double __pyx_v_tau_scale, double __pyx_v_epsilon) { - __Pyx_memviewslice __pyx_v_rates_view = { 0, 0, { 0 }, { 0 }, { 0 } }; - __pyx_t_5numpy_int64_t __pyx_v_n_rates; - __Pyx_memviewslice __pyx_v_x_view = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_reactant_mat_view = { 0, 0, { 0 }, { 0 }, { 0 } }; - __pyx_t_5numpy_int64_t __pyx_v_n_reactants; - double __pyx_v_mu; - double __pyx_v_max_cdf; - double __pyx_v_new_cdf; - CYTHON_UNUSED double __pyx_v_total_rate; - int __pyx_v_safe; - int __pyx_v_count; - double __pyx_v_cdf_val; - __pyx_t_5numpy_int64_t __pyx_v_i; - __pyx_t_5numpy_int64_t __pyx_v_j; - __Pyx_LocalBuf_ND __pyx_pybuffernd_rates; - __Pyx_Buffer __pyx_pybuffer_rates; - __Pyx_LocalBuf_ND __pyx_pybuffernd_reactant_mat; - __Pyx_Buffer __pyx_pybuffer_reactant_mat; - __Pyx_LocalBuf_ND __pyx_pybuffernd_x; - __Pyx_Buffer __pyx_pybuffer_x; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice __pyx_t_1 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_t_2 = { 0, 0, { 0 }, { 0 }, { 0 } }; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - double __pyx_t_7; - int __pyx_t_8; - __pyx_t_5numpy_int64_t __pyx_t_9; - __pyx_t_5numpy_int64_t __pyx_t_10; - __pyx_t_5numpy_int64_t __pyx_t_11; - __pyx_t_5numpy_int64_t __pyx_t_12; - __pyx_t_5numpy_int64_t __pyx_t_13; - __pyx_t_5numpy_int64_t __pyx_t_14; - __pyx_t_5numpy_int64_t __pyx_t_15; - __pyx_t_5numpy_int64_t __pyx_t_16; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_cy_test_tau_leap_safety", 1); - __pyx_pybuffer_x.pybuffer.buf = NULL; - __pyx_pybuffer_x.refcount = 0; - __pyx_pybuffernd_x.data = NULL; - __pyx_pybuffernd_x.rcbuffer = &__pyx_pybuffer_x; - __pyx_pybuffer_reactant_mat.pybuffer.buf = NULL; - __pyx_pybuffer_reactant_mat.refcount = 0; - __pyx_pybuffernd_reactant_mat.data = NULL; - __pyx_pybuffernd_reactant_mat.rcbuffer = &__pyx_pybuffer_reactant_mat; - __pyx_pybuffer_rates.pybuffer.buf = NULL; - __pyx_pybuffer_rates.refcount = 0; - __pyx_pybuffernd_rates.data = NULL; - __pyx_pybuffernd_rates.rcbuffer = &__pyx_pybuffer_rates; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x.rcbuffer->pybuffer, (PyObject*)__pyx_v_x, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 8, __pyx_L1_error) - } - __pyx_pybuffernd_x.diminfo[0].strides = __pyx_pybuffernd_x.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x.diminfo[0].shape = __pyx_pybuffernd_x.rcbuffer->pybuffer.shape[0]; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer, (PyObject*)__pyx_v_reactant_mat, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 8, __pyx_L1_error) - } - __pyx_pybuffernd_reactant_mat.diminfo[0].strides = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_reactant_mat.diminfo[0].shape = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_reactant_mat.diminfo[1].strides = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_reactant_mat.diminfo[1].shape = __pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer.shape[1]; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_rates.rcbuffer->pybuffer, (PyObject*)__pyx_v_rates, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 8, __pyx_L1_error) - } - __pyx_pybuffernd_rates.diminfo[0].strides = __pyx_pybuffernd_rates.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_rates.diminfo[0].shape = __pyx_pybuffernd_rates.rcbuffer->pybuffer.shape[0]; - - /* "pygom/model/_tau_leap.pyx":23 - * """ - * #view on arrays - * cdef double[:] rates_view = rates # <<<<<<<<<<<<<< - * cdef np.int64_t n_rates = rates.shape[0] - * cdef double[:] x_view = x - */ - __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_rates), PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 23, __pyx_L1_error) - __pyx_v_rates_view = __pyx_t_1; - __pyx_t_1.memview = NULL; - __pyx_t_1.data = NULL; - - /* "pygom/model/_tau_leap.pyx":24 - * #view on arrays - * cdef double[:] rates_view = rates - * cdef np.int64_t n_rates = rates.shape[0] # <<<<<<<<<<<<<< - * cdef double[:] x_view = x - * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat - */ - __pyx_v_n_rates = (__pyx_f_5numpy_7ndarray_5shape_shape(((PyArrayObject *)__pyx_v_rates))[0]); - - /* "pygom/model/_tau_leap.pyx":25 - * cdef double[:] rates_view = rates - * cdef np.int64_t n_rates = rates.shape[0] - * cdef double[:] x_view = x # <<<<<<<<<<<<<< - * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat - * cdef np.int64_t n_reactants = reactant_mat.shape[0] - */ - __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_x), PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 25, __pyx_L1_error) - __pyx_v_x_view = __pyx_t_1; - __pyx_t_1.memview = NULL; - __pyx_t_1.data = NULL; - - /* "pygom/model/_tau_leap.pyx":26 - * cdef np.int64_t n_rates = rates.shape[0] - * cdef double[:] x_view = x - * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat # <<<<<<<<<<<<<< - * cdef np.int64_t n_reactants = reactant_mat.shape[0] - * - */ - __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int64_t(((PyObject *)__pyx_v_reactant_mat), PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 26, __pyx_L1_error) - __pyx_v_reactant_mat_view = __pyx_t_2; - __pyx_t_2.memview = NULL; - __pyx_t_2.data = NULL; - - /* "pygom/model/_tau_leap.pyx":27 - * cdef double[:] x_view = x - * cdef np.int64_t[:, :] reactant_mat_view = reactant_mat - * cdef np.int64_t n_reactants = reactant_mat.shape[0] # <<<<<<<<<<<<<< - * - * cdef double mu, max_cdf, new_cdf - */ - __pyx_v_n_reactants = (__pyx_f_5numpy_7ndarray_5shape_shape(((PyArrayObject *)__pyx_v_reactant_mat))[0]); - - /* "pygom/model/_tau_leap.pyx":30 - * - * cdef double mu, max_cdf, new_cdf - * cdef double total_rate = np.sum(rates) # <<<<<<<<<<<<<< - * safe = False # when True, indicates that tau_scale is sufficiently small - * cdef int count = 0 # number of attempts to find acceptable tau_scale - */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_sum); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = NULL; - __pyx_t_6 = 0; - #if CYTHON_UNPACK_METHODS - if (unlikely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - __pyx_t_6 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[2] = {__pyx_t_4, ((PyObject *)__pyx_v_rates)}; - __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_total_rate = __pyx_t_7; - - /* "pygom/model/_tau_leap.pyx":31 - * cdef double mu, max_cdf, new_cdf - * cdef double total_rate = np.sum(rates) - * safe = False # when True, indicates that tau_scale is sufficiently small # <<<<<<<<<<<<<< - * cdef int count = 0 # number of attempts to find acceptable tau_scale - * while safe is False: - */ - __pyx_v_safe = 0; - - /* "pygom/model/_tau_leap.pyx":32 - * cdef double total_rate = np.sum(rates) - * safe = False # when True, indicates that tau_scale is sufficiently small - * cdef int count = 0 # number of attempts to find acceptable tau_scale # <<<<<<<<<<<<<< - * while safe is False: - * # print(count) - */ - __pyx_v_count = 0; - - /* "pygom/model/_tau_leap.pyx":33 - * safe = False # when True, indicates that tau_scale is sufficiently small - * cdef int count = 0 # number of attempts to find acceptable tau_scale - * while safe is False: # <<<<<<<<<<<<<< - * # print(count) - * # print(tau_scale) - */ - while (1) { - __pyx_t_8 = (__pyx_v_safe == 0); - if (!__pyx_t_8) break; - - /* "pygom/model/_tau_leap.pyx":36 - * # print(count) - * # print(tau_scale) - * cdf_val = 1.0 # <<<<<<<<<<<<<< - * for i in range(n_rates): # loop over transitions, i - * for j in range(n_reactants): # loop over states, j - */ - __pyx_v_cdf_val = 1.0; - - /* "pygom/model/_tau_leap.pyx":37 - * # print(tau_scale) - * cdf_val = 1.0 - * for i in range(n_rates): # loop over transitions, i # <<<<<<<<<<<<<< - * for j in range(n_reactants): # loop over states, j - * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? - */ - __pyx_t_9 = __pyx_v_n_rates; - __pyx_t_10 = __pyx_t_9; - for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { - __pyx_v_i = __pyx_t_11; - - /* "pygom/model/_tau_leap.pyx":38 - * cdf_val = 1.0 - * for i in range(n_rates): # loop over transitions, i - * for j in range(n_reactants): # loop over states, j # <<<<<<<<<<<<<< - * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? - * mu = rates_view[i] * tau_scale # expected number of events for transition i - */ - __pyx_t_12 = __pyx_v_n_reactants; - __pyx_t_13 = __pyx_t_12; - for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { - __pyx_v_j = __pyx_t_14; - - /* "pygom/model/_tau_leap.pyx":39 - * for i in range(n_rates): # loop over transitions, i - * for j in range(n_reactants): # loop over states, j - * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? # <<<<<<<<<<<<<< - * mu = rates_view[i] * tau_scale # expected number of events for transition i - * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop - */ - __pyx_t_15 = __pyx_v_j; - __pyx_t_16 = __pyx_v_i; - __pyx_t_8 = ((*((__pyx_t_5numpy_int64_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_reactant_mat_view.data + __pyx_t_15 * __pyx_v_reactant_mat_view.strides[0]) ) + __pyx_t_16 * __pyx_v_reactant_mat_view.strides[1]) ))) == 1); - if (__pyx_t_8) { - - /* "pygom/model/_tau_leap.pyx":40 - * for j in range(n_reactants): # loop over states, j - * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? - * mu = rates_view[i] * tau_scale # expected number of events for transition i # <<<<<<<<<<<<<< - * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop - * if new_cdf < cdf_val: - */ - __pyx_t_16 = __pyx_v_i; - __pyx_v_mu = ((*((double *) ( /* dim=0 */ (__pyx_v_rates_view.data + __pyx_t_16 * __pyx_v_rates_view.strides[0]) ))) * __pyx_v_tau_scale); - - /* "pygom/model/_tau_leap.pyx":41 - * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? - * mu = rates_view[i] * tau_scale # expected number of events for transition i - * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop # <<<<<<<<<<<<<< - * if new_cdf < cdf_val: - * cdf_val = new_cdf - */ - __pyx_t_16 = __pyx_v_j; - __pyx_v_new_cdf = __pyx_f_5scipy_7special_14cython_special_pdtr(floor((*((double *) ( /* dim=0 */ (__pyx_v_x_view.data + __pyx_t_16 * __pyx_v_x_view.strides[0]) )))), __pyx_v_mu, 0); - - /* "pygom/model/_tau_leap.pyx":42 - * mu = rates_view[i] * tau_scale # expected number of events for transition i - * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop - * if new_cdf < cdf_val: # <<<<<<<<<<<<<< - * cdf_val = new_cdf - * # if new_cdf < cdf_val: # think this extra condition is redundant - */ - __pyx_t_8 = (__pyx_v_new_cdf < __pyx_v_cdf_val); - if (__pyx_t_8) { - - /* "pygom/model/_tau_leap.pyx":43 - * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop - * if new_cdf < cdf_val: - * cdf_val = new_cdf # <<<<<<<<<<<<<< - * # if new_cdf < cdf_val: # think this extra condition is redundant - * # cdf_val = new_cdf - */ - __pyx_v_cdf_val = __pyx_v_new_cdf; - - /* "pygom/model/_tau_leap.pyx":42 - * mu = rates_view[i] * tau_scale # expected number of events for transition i - * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop - * if new_cdf < cdf_val: # <<<<<<<<<<<<<< - * cdf_val = new_cdf - * # if new_cdf < cdf_val: # think this extra condition is redundant - */ - } - - /* "pygom/model/_tau_leap.pyx":39 - * for i in range(n_rates): # loop over transitions, i - * for j in range(n_reactants): # loop over states, j - * if reactant_mat_view[j, i] == 1: # is state j involved in transition i? # <<<<<<<<<<<<<< - * mu = rates_view[i] * tau_scale # expected number of events for transition i - * new_cdf = csc.pdtr(floor(x_view[j]), mu) # prob transitions of order state pop - */ - } - } - } - - /* "pygom/model/_tau_leap.pyx":49 - * - * # the expected probability that our jump will exceed the value - * max_cdf = 1.0 - cdf_val # <<<<<<<<<<<<<< - * # print(max_cdf) - * # cannot allow it to exceed out epsilon - */ - __pyx_v_max_cdf = (1.0 - __pyx_v_cdf_val); - - /* "pygom/model/_tau_leap.pyx":52 - * # print(max_cdf) - * # cannot allow it to exceed out epsilon - * if max_cdf > epsilon: # <<<<<<<<<<<<<< - * tau_scale /= (max_cdf / epsilon) - * else: - */ - __pyx_t_8 = (__pyx_v_max_cdf > __pyx_v_epsilon); - if (__pyx_t_8) { - - /* "pygom/model/_tau_leap.pyx":53 - * # cannot allow it to exceed out epsilon - * if max_cdf > epsilon: - * tau_scale /= (max_cdf / epsilon) # <<<<<<<<<<<<<< - * else: - * safe = True - */ - __pyx_v_tau_scale = (__pyx_v_tau_scale / (__pyx_v_max_cdf / __pyx_v_epsilon)); - - /* "pygom/model/_tau_leap.pyx":52 - * # print(max_cdf) - * # cannot allow it to exceed out epsilon - * if max_cdf > epsilon: # <<<<<<<<<<<<<< - * tau_scale /= (max_cdf / epsilon) - * else: - */ - goto __pyx_L11; - } - - /* "pygom/model/_tau_leap.pyx":55 - * tau_scale /= (max_cdf / epsilon) - * else: - * safe = True # <<<<<<<<<<<<<< - * - * if count > 256: - */ - /*else*/ { - __pyx_v_safe = 1; - } - __pyx_L11:; - - /* "pygom/model/_tau_leap.pyx":57 - * safe = True - * - * if count > 256: # <<<<<<<<<<<<<< - * print("count error") - * return False - */ - __pyx_t_8 = (__pyx_v_count > 0x100); - if (__pyx_t_8) { - - /* "pygom/model/_tau_leap.pyx":58 - * - * if count > 256: - * print("count error") # <<<<<<<<<<<<<< - * return False - * - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 58, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "pygom/model/_tau_leap.pyx":59 - * if count > 256: - * print("count error") - * return False # <<<<<<<<<<<<<< - * - * # if tau_scale*total_rate <= 1.0: # leave out Gillespie regime catch for now - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(Py_False); - __pyx_r = Py_False; - goto __pyx_L0; - - /* "pygom/model/_tau_leap.pyx":57 - * safe = True - * - * if count > 256: # <<<<<<<<<<<<<< - * print("count error") - * return False - */ - } - - /* "pygom/model/_tau_leap.pyx":64 - * # print("scale error") - * # return False - * count += 1 # <<<<<<<<<<<<<< - * - * return tau_scale, True - */ - __pyx_v_count = (__pyx_v_count + 1); - } - - /* "pygom/model/_tau_leap.pyx":66 - * count += 1 - * - * return tau_scale, True # <<<<<<<<<<<<<< - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = PyFloat_FromDouble(__pyx_v_tau_scale); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 66, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 66, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3)) __PYX_ERR(0, 66, __pyx_L1_error); - __Pyx_INCREF(Py_True); - __Pyx_GIVEREF(Py_True); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, Py_True)) __PYX_ERR(0, 66, __pyx_L1_error); - __pyx_t_3 = 0; - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; - goto __pyx_L0; - - /* "pygom/model/_tau_leap.pyx":8 - * cimport cython - * - * @cython.boundscheck(False) # Deactivate bounds checking # <<<<<<<<<<<<<< - * @cython.wraparound(False) # Deactivate negative indexing. - * @cython.cdivision(True) # Deactivate the div 0 error checking - */ - - /* function exit code */ - __pyx_L1_error:; - __PYX_XCLEAR_MEMVIEW(&__pyx_t_1, 1); - __PYX_XCLEAR_MEMVIEW(&__pyx_t_2, 1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_rates.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); - __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("pygom.model._tau_leap._cy_test_tau_leap_safety", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - goto __pyx_L2; - __pyx_L0:; - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_rates.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_reactant_mat.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); - __pyx_L2:; - __PYX_XCLEAR_MEMVIEW(&__pyx_v_rates_view, 1); - __PYX_XCLEAR_MEMVIEW(&__pyx_v_x_view, 1); - __PYX_XCLEAR_MEMVIEW(&__pyx_v_reactant_mat_view, 1); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} -static struct __pyx_vtabstruct_array __pyx_vtable_array; - -static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_array_obj *p; - PyObject *o; - #if CYTHON_COMPILING_IN_LIMITED_API - allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); - o = alloc_func(t, 0); - #else - if (likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - #endif - p = ((struct __pyx_array_obj *)o); - p->__pyx_vtab = __pyx_vtabptr_array; - p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None); - if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_array(PyObject *o) { - struct __pyx_array_obj *p = (struct __pyx_array_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && (!PyType_IS_GC(Py_TYPE(o)) || !__Pyx_PyObject_GC_IsFinalized(o))) { - if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_array) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - } - #endif - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_array___dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - Py_CLEAR(p->mode); - Py_CLEAR(p->_format); - #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY - (*Py_TYPE(o)->tp_free)(o); - #else - { - freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); - if (tp_free) tp_free(o); - } - #endif -} -static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) { - PyObject *r; - PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; - r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); - Py_DECREF(x); - return r; -} - -static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) { - if (v) { - return __pyx_array___setitem__(o, i, v); - } - else { - __Pyx_TypeName o_type_name; - o_type_name = __Pyx_PyType_GetName(Py_TYPE(o)); - PyErr_Format(PyExc_NotImplementedError, - "Subscript deletion not supported by " __Pyx_FMT_TYPENAME, o_type_name); - __Pyx_DECREF_TypeName(o_type_name); - return -1; - } -} - -static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) { - PyObject *v = __Pyx_PyObject_GenericGetAttr(o, n); - if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - v = __pyx_array___getattr__(o, n); - } - return v; -} - -static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(o); -} - -static PyMethodDef __pyx_methods_array[] = { - {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0}, - {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_array_1__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_array_3__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_array[] = { - {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; -#if CYTHON_USE_TYPE_SPECS -#if !CYTHON_COMPILING_IN_LIMITED_API - -static PyBufferProcs __pyx_tp_as_buffer_array = { - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getreadbuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getwritebuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getsegcount*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getcharbuffer*/ - #endif - __pyx_array_getbuffer, /*bf_getbuffer*/ - 0, /*bf_releasebuffer*/ -}; -#endif -static PyType_Slot __pyx_type___pyx_array_slots[] = { - {Py_tp_dealloc, (void *)__pyx_tp_dealloc_array}, - {Py_sq_length, (void *)__pyx_array___len__}, - {Py_sq_item, (void *)__pyx_sq_item_array}, - {Py_mp_length, (void *)__pyx_array___len__}, - {Py_mp_subscript, (void *)__pyx_array___getitem__}, - {Py_mp_ass_subscript, (void *)__pyx_mp_ass_subscript_array}, - {Py_tp_getattro, (void *)__pyx_tp_getattro_array}, - #if defined(Py_bf_getbuffer) - {Py_bf_getbuffer, (void *)__pyx_array_getbuffer}, - #endif - {Py_tp_methods, (void *)__pyx_methods_array}, - {Py_tp_getset, (void *)__pyx_getsets_array}, - {Py_tp_new, (void *)__pyx_tp_new_array}, - {0, 0}, -}; -static PyType_Spec __pyx_type___pyx_array_spec = { - "pygom.model._tau_leap.array", - sizeof(struct __pyx_array_obj), - 0, - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_SEQUENCE, - __pyx_type___pyx_array_slots, -}; -#else - -static PySequenceMethods __pyx_tp_as_sequence_array = { - __pyx_array___len__, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - __pyx_sq_item_array, /*sq_item*/ - 0, /*sq_slice*/ - 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - 0, /*sq_contains*/ - 0, /*sq_inplace_concat*/ - 0, /*sq_inplace_repeat*/ -}; - -static PyMappingMethods __pyx_tp_as_mapping_array = { - __pyx_array___len__, /*mp_length*/ - __pyx_array___getitem__, /*mp_subscript*/ - __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/ -}; - -static PyBufferProcs __pyx_tp_as_buffer_array = { - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getreadbuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getwritebuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getsegcount*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getcharbuffer*/ - #endif - __pyx_array_getbuffer, /*bf_getbuffer*/ - 0, /*bf_releasebuffer*/ -}; - -static PyTypeObject __pyx_type___pyx_array = { - PyVarObject_HEAD_INIT(0, 0) - "pygom.model._tau_leap.""array", /*tp_name*/ - sizeof(struct __pyx_array_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_array, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - &__pyx_tp_as_sequence_array, /*tp_as_sequence*/ - &__pyx_tp_as_mapping_array, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - __pyx_tp_getattro_array, /*tp_getattro*/ - 0, /*tp_setattro*/ - &__pyx_tp_as_buffer_array, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_SEQUENCE, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_array, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_array, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - #if !CYTHON_USE_TYPE_SPECS - 0, /*tp_dictoffset*/ - #endif - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_array, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - #if CYTHON_USE_TP_FINALIZE - 0, /*tp_finalize*/ - #else - NULL, /*tp_finalize*/ - #endif - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if __PYX_NEED_TP_PRINT_SLOT == 1 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030C0000 - 0, /*tp_watched*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 - 0, /*tp_pypy_flags*/ - #endif -}; -#endif - -static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - struct __pyx_MemviewEnum_obj *p; - PyObject *o; - #if CYTHON_COMPILING_IN_LIMITED_API - allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); - o = alloc_func(t, 0); - #else - if (likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - #endif - p = ((struct __pyx_MemviewEnum_obj *)o); - p->name = Py_None; Py_INCREF(Py_None); - return o; -} - -static void __pyx_tp_dealloc_Enum(PyObject *o) { - struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { - if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_Enum) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - } - #endif - PyObject_GC_UnTrack(o); - Py_CLEAR(p->name); - #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY - (*Py_TYPE(o)->tp_free)(o); - #else - { - freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); - if (tp_free) tp_free(o); - } - #endif -} - -static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; - if (p->name) { - e = (*v)(p->name, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_Enum(PyObject *o) { - PyObject* tmp; - struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; - tmp = ((PyObject*)p->name); - p->name = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} - -static PyObject *__pyx_specialmethod___pyx_MemviewEnum___repr__(PyObject *self, CYTHON_UNUSED PyObject *arg) { - return __pyx_MemviewEnum___repr__(self); -} - -static PyMethodDef __pyx_methods_Enum[] = { - {"__repr__", (PyCFunction)__pyx_specialmethod___pyx_MemviewEnum___repr__, METH_NOARGS|METH_COEXIST, 0}, - {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_MemviewEnum_1__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_MemviewEnum_3__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {0, 0, 0, 0} -}; -#if CYTHON_USE_TYPE_SPECS -static PyType_Slot __pyx_type___pyx_MemviewEnum_slots[] = { - {Py_tp_dealloc, (void *)__pyx_tp_dealloc_Enum}, - {Py_tp_repr, (void *)__pyx_MemviewEnum___repr__}, - {Py_tp_traverse, (void *)__pyx_tp_traverse_Enum}, - {Py_tp_clear, (void *)__pyx_tp_clear_Enum}, - {Py_tp_methods, (void *)__pyx_methods_Enum}, - {Py_tp_init, (void *)__pyx_MemviewEnum___init__}, - {Py_tp_new, (void *)__pyx_tp_new_Enum}, - {0, 0}, -}; -static PyType_Spec __pyx_type___pyx_MemviewEnum_spec = { - "pygom.model._tau_leap.Enum", - sizeof(struct __pyx_MemviewEnum_obj), - 0, - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, - __pyx_type___pyx_MemviewEnum_slots, -}; -#else - -static PyTypeObject __pyx_type___pyx_MemviewEnum = { - PyVarObject_HEAD_INIT(0, 0) - "pygom.model._tau_leap.""Enum", /*tp_name*/ - sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_Enum, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - __pyx_MemviewEnum___repr__, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_Enum, /*tp_traverse*/ - __pyx_tp_clear_Enum, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_Enum, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - #if !CYTHON_USE_TYPE_SPECS - 0, /*tp_dictoffset*/ - #endif - __pyx_MemviewEnum___init__, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_Enum, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - #if CYTHON_USE_TP_FINALIZE - 0, /*tp_finalize*/ - #else - NULL, /*tp_finalize*/ - #endif - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if __PYX_NEED_TP_PRINT_SLOT == 1 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030C0000 - 0, /*tp_watched*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 - 0, /*tp_pypy_flags*/ - #endif -}; -#endif -static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview; - -static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_memoryview_obj *p; - PyObject *o; - #if CYTHON_COMPILING_IN_LIMITED_API - allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); - o = alloc_func(t, 0); - #else - if (likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - #endif - p = ((struct __pyx_memoryview_obj *)o); - p->__pyx_vtab = __pyx_vtabptr_memoryview; - p->obj = Py_None; Py_INCREF(Py_None); - p->_size = Py_None; Py_INCREF(Py_None); - p->_array_interface = Py_None; Py_INCREF(Py_None); - p->view.obj = NULL; - if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_memoryview(PyObject *o) { - struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { - if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_memoryview) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - } - #endif - PyObject_GC_UnTrack(o); - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_memoryview___dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - Py_CLEAR(p->obj); - Py_CLEAR(p->_size); - Py_CLEAR(p->_array_interface); - #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY - (*Py_TYPE(o)->tp_free)(o); - #else - { - freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); - if (tp_free) tp_free(o); - } - #endif -} - -static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; - if (p->obj) { - e = (*v)(p->obj, a); if (e) return e; - } - if (p->_size) { - e = (*v)(p->_size, a); if (e) return e; - } - if (p->_array_interface) { - e = (*v)(p->_array_interface, a); if (e) return e; - } - if (p->view.obj) { - e = (*v)(p->view.obj, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_memoryview(PyObject *o) { - PyObject* tmp; - struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; - tmp = ((PyObject*)p->obj); - p->obj = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_size); - p->_size = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_array_interface); - p->_array_interface = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - Py_CLEAR(p->view.obj); - return 0; -} -static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) { - PyObject *r; - PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; - r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); - Py_DECREF(x); - return r; -} - -static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) { - if (v) { - return __pyx_memoryview___setitem__(o, i, v); - } - else { - __Pyx_TypeName o_type_name; - o_type_name = __Pyx_PyType_GetName(Py_TYPE(o)); - PyErr_Format(PyExc_NotImplementedError, - "Subscript deletion not supported by " __Pyx_FMT_TYPENAME, o_type_name); - __Pyx_DECREF_TypeName(o_type_name); - return -1; - } -} - -static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(o); -} - -static PyObject *__pyx_specialmethod___pyx_memoryview___repr__(PyObject *self, CYTHON_UNUSED PyObject *arg) { - return __pyx_memoryview___repr__(self); -} - -static PyMethodDef __pyx_methods_memoryview[] = { - {"__repr__", (PyCFunction)__pyx_specialmethod___pyx_memoryview___repr__, METH_NOARGS|METH_COEXIST, 0}, - {"is_c_contig", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_memoryview_is_c_contig, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {"is_f_contig", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_memoryview_is_f_contig, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {"copy", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_memoryview_copy, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {"copy_fortran", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_memoryview_copy_fortran, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_memoryview_1__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_memoryview_3__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_memoryview[] = { - {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, (char *)0, 0}, - {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, (char *)0, 0}, - {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, (char *)0, 0}, - {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, (char *)0, 0}, - {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, (char *)0, 0}, - {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, (char *)0, 0}, - {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, (char *)0, 0}, - {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, (char *)0, 0}, - {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; -#if CYTHON_USE_TYPE_SPECS -#if !CYTHON_COMPILING_IN_LIMITED_API - -static PyBufferProcs __pyx_tp_as_buffer_memoryview = { - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getreadbuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getwritebuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getsegcount*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getcharbuffer*/ - #endif - __pyx_memoryview_getbuffer, /*bf_getbuffer*/ - 0, /*bf_releasebuffer*/ -}; -#endif -static PyType_Slot __pyx_type___pyx_memoryview_slots[] = { - {Py_tp_dealloc, (void *)__pyx_tp_dealloc_memoryview}, - {Py_tp_repr, (void *)__pyx_memoryview___repr__}, - {Py_sq_length, (void *)__pyx_memoryview___len__}, - {Py_sq_item, (void *)__pyx_sq_item_memoryview}, - {Py_mp_length, (void *)__pyx_memoryview___len__}, - {Py_mp_subscript, (void *)__pyx_memoryview___getitem__}, - {Py_mp_ass_subscript, (void *)__pyx_mp_ass_subscript_memoryview}, - {Py_tp_str, (void *)__pyx_memoryview___str__}, - #if defined(Py_bf_getbuffer) - {Py_bf_getbuffer, (void *)__pyx_memoryview_getbuffer}, - #endif - {Py_tp_traverse, (void *)__pyx_tp_traverse_memoryview}, - {Py_tp_clear, (void *)__pyx_tp_clear_memoryview}, - {Py_tp_methods, (void *)__pyx_methods_memoryview}, - {Py_tp_getset, (void *)__pyx_getsets_memoryview}, - {Py_tp_new, (void *)__pyx_tp_new_memoryview}, - {0, 0}, -}; -static PyType_Spec __pyx_type___pyx_memoryview_spec = { - "pygom.model._tau_leap.memoryview", - sizeof(struct __pyx_memoryview_obj), - 0, - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, - __pyx_type___pyx_memoryview_slots, -}; -#else - -static PySequenceMethods __pyx_tp_as_sequence_memoryview = { - __pyx_memoryview___len__, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - __pyx_sq_item_memoryview, /*sq_item*/ - 0, /*sq_slice*/ - 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - 0, /*sq_contains*/ - 0, /*sq_inplace_concat*/ - 0, /*sq_inplace_repeat*/ -}; - -static PyMappingMethods __pyx_tp_as_mapping_memoryview = { - __pyx_memoryview___len__, /*mp_length*/ - __pyx_memoryview___getitem__, /*mp_subscript*/ - __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/ -}; - -static PyBufferProcs __pyx_tp_as_buffer_memoryview = { - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getreadbuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getwritebuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getsegcount*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getcharbuffer*/ - #endif - __pyx_memoryview_getbuffer, /*bf_getbuffer*/ - 0, /*bf_releasebuffer*/ -}; - -static PyTypeObject __pyx_type___pyx_memoryview = { - PyVarObject_HEAD_INIT(0, 0) - "pygom.model._tau_leap.""memoryview", /*tp_name*/ - sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_memoryview, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - __pyx_memoryview___repr__, /*tp_repr*/ - 0, /*tp_as_number*/ - &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/ - &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - __pyx_memoryview___str__, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_memoryview, /*tp_traverse*/ - __pyx_tp_clear_memoryview, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_memoryview, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_memoryview, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - #if !CYTHON_USE_TYPE_SPECS - 0, /*tp_dictoffset*/ - #endif - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_memoryview, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - #if CYTHON_USE_TP_FINALIZE - 0, /*tp_finalize*/ - #else - NULL, /*tp_finalize*/ - #endif - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if __PYX_NEED_TP_PRINT_SLOT == 1 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030C0000 - 0, /*tp_watched*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 - 0, /*tp_pypy_flags*/ - #endif -}; -#endif -static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice; - -static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_memoryviewslice_obj *p; - PyObject *o = __pyx_tp_new_memoryview(t, a, k); - if (unlikely(!o)) return 0; - p = ((struct __pyx_memoryviewslice_obj *)o); - p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice; - p->from_object = Py_None; Py_INCREF(Py_None); - p->from_slice.memview = NULL; - return o; -} - -static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) { - struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { - if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc__memoryviewslice) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - } - #endif - PyObject_GC_UnTrack(o); - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_memoryviewslice___dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - Py_CLEAR(p->from_object); - PyObject_GC_Track(o); - __pyx_tp_dealloc_memoryview(o); -} - -static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; - e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e; - if (p->from_object) { - e = (*v)(p->from_object, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear__memoryviewslice(PyObject *o) { - PyObject* tmp; - struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; - __pyx_tp_clear_memoryview(o); - tmp = ((PyObject*)p->from_object); - p->from_object = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - __PYX_XCLEAR_MEMVIEW(&p->from_slice, 1); - return 0; -} - -static PyMethodDef __pyx_methods__memoryviewslice[] = { - {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_memoryviewslice_1__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw___pyx_memoryviewslice_3__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}, - {0, 0, 0, 0} -}; -#if CYTHON_USE_TYPE_SPECS -static PyType_Slot __pyx_type___pyx_memoryviewslice_slots[] = { - {Py_tp_dealloc, (void *)__pyx_tp_dealloc__memoryviewslice}, - {Py_tp_doc, (void *)PyDoc_STR("Internal class for passing memoryview slices to Python")}, - {Py_tp_traverse, (void *)__pyx_tp_traverse__memoryviewslice}, - {Py_tp_clear, (void *)__pyx_tp_clear__memoryviewslice}, - {Py_tp_methods, (void *)__pyx_methods__memoryviewslice}, - {Py_tp_new, (void *)__pyx_tp_new__memoryviewslice}, - {0, 0}, -}; -static PyType_Spec __pyx_type___pyx_memoryviewslice_spec = { - "pygom.model._tau_leap._memoryviewslice", - sizeof(struct __pyx_memoryviewslice_obj), - 0, - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_SEQUENCE, - __pyx_type___pyx_memoryviewslice_slots, -}; -#else - -static PyTypeObject __pyx_type___pyx_memoryviewslice = { - PyVarObject_HEAD_INIT(0, 0) - "pygom.model._tau_leap.""_memoryviewslice", /*tp_name*/ - sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - #if CYTHON_COMPILING_IN_PYPY || 0 - __pyx_memoryview___repr__, /*tp_repr*/ - #else - 0, /*tp_repr*/ - #endif - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - #if CYTHON_COMPILING_IN_PYPY || 0 - __pyx_memoryview___str__, /*tp_str*/ - #else - 0, /*tp_str*/ - #endif - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_SEQUENCE, /*tp_flags*/ - PyDoc_STR("Internal class for passing memoryview slices to Python"), /*tp_doc*/ - __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/ - __pyx_tp_clear__memoryviewslice, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods__memoryviewslice, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - #if !CYTHON_USE_TYPE_SPECS - 0, /*tp_dictoffset*/ - #endif - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new__memoryviewslice, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - #if CYTHON_USE_TP_FINALIZE - 0, /*tp_finalize*/ - #else - NULL, /*tp_finalize*/ - #endif - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if __PYX_NEED_TP_PRINT_SLOT == 1 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030C0000 - 0, /*tp_watched*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 - 0, /*tp_pypy_flags*/ - #endif -}; -#endif - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif -/* #### Code section: pystring_table ### */ - -static int __Pyx_CreateStringTabAndInitStrings(void) { - __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_u_, __pyx_k_, sizeof(__pyx_k_), 0, 1, 0, 0}, - {&__pyx_n_s_ASCII, __pyx_k_ASCII, sizeof(__pyx_k_ASCII), 0, 0, 1, 1}, - {&__pyx_kp_s_All_dimensions_preceding_dimensi, __pyx_k_All_dimensions_preceding_dimensi, sizeof(__pyx_k_All_dimensions_preceding_dimensi), 0, 0, 1, 0}, - {&__pyx_n_s_AssertionError, __pyx_k_AssertionError, sizeof(__pyx_k_AssertionError), 0, 0, 1, 1}, - {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0}, - {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0}, - {&__pyx_kp_s_Cannot_assign_to_read_only_memor, __pyx_k_Cannot_assign_to_read_only_memor, sizeof(__pyx_k_Cannot_assign_to_read_only_memor), 0, 0, 1, 0}, - {&__pyx_kp_s_Cannot_create_writable_memory_vi, __pyx_k_Cannot_create_writable_memory_vi, sizeof(__pyx_k_Cannot_create_writable_memory_vi), 0, 0, 1, 0}, - {&__pyx_kp_u_Cannot_index_with_type, __pyx_k_Cannot_index_with_type, sizeof(__pyx_k_Cannot_index_with_type), 0, 1, 0, 0}, - {&__pyx_kp_s_Cannot_transpose_memoryview_with, __pyx_k_Cannot_transpose_memoryview_with, sizeof(__pyx_k_Cannot_transpose_memoryview_with), 0, 0, 1, 0}, - {&__pyx_kp_s_Dimension_d_is_not_direct, __pyx_k_Dimension_d_is_not_direct, sizeof(__pyx_k_Dimension_d_is_not_direct), 0, 0, 1, 0}, - {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1}, - {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0}, - {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, - {&__pyx_kp_s_Incompatible_checksums_0x_x_vs_0, __pyx_k_Incompatible_checksums_0x_x_vs_0, sizeof(__pyx_k_Incompatible_checksums_0x_x_vs_0), 0, 0, 1, 0}, - {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1}, - {&__pyx_kp_s_Index_out_of_bounds_axis_d, __pyx_k_Index_out_of_bounds_axis_d, sizeof(__pyx_k_Index_out_of_bounds_axis_d), 0, 0, 1, 0}, - {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0}, - {&__pyx_kp_u_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 1, 0, 0}, - {&__pyx_kp_u_Invalid_shape_in_axis, __pyx_k_Invalid_shape_in_axis, sizeof(__pyx_k_Invalid_shape_in_axis), 0, 1, 0, 0}, - {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1}, - {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0}, - {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0}, - {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1}, - {&__pyx_kp_u_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 1, 0, 0}, - {&__pyx_n_s_PickleError, __pyx_k_PickleError, sizeof(__pyx_k_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_Sequence, __pyx_k_Sequence, sizeof(__pyx_k_Sequence), 0, 0, 1, 1}, - {&__pyx_kp_s_Step_may_not_be_zero_axis_d, __pyx_k_Step_may_not_be_zero_axis_d, sizeof(__pyx_k_Step_may_not_be_zero_axis_d), 0, 0, 1, 0}, - {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, - {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0}, - {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, - {&__pyx_n_s_View_MemoryView, __pyx_k_View_MemoryView, sizeof(__pyx_k_View_MemoryView), 0, 0, 1, 1}, - {&__pyx_kp_u__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 1, 0, 0}, - {&__pyx_n_s__25, __pyx_k__25, sizeof(__pyx_k__25), 0, 0, 1, 1}, - {&__pyx_n_s__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 0, 1, 1}, - {&__pyx_kp_u__6, __pyx_k__6, sizeof(__pyx_k__6), 0, 1, 0, 0}, - {&__pyx_kp_u__7, __pyx_k__7, sizeof(__pyx_k__7), 0, 1, 0, 0}, - {&__pyx_n_s_abc, __pyx_k_abc, sizeof(__pyx_k_abc), 0, 0, 1, 1}, - {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1}, - {&__pyx_kp_u_and, __pyx_k_and, sizeof(__pyx_k_and), 0, 1, 0, 0}, - {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1}, - {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1}, - {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1}, - {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1}, - {&__pyx_n_s_cdf_val, __pyx_k_cdf_val, sizeof(__pyx_k_cdf_val), 0, 0, 1, 1}, - {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1}, - {&__pyx_n_s_class_getitem, __pyx_k_class_getitem, sizeof(__pyx_k_class_getitem), 0, 0, 1, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_collections, __pyx_k_collections, sizeof(__pyx_k_collections), 0, 0, 1, 1}, - {&__pyx_kp_s_collections_abc, __pyx_k_collections_abc, sizeof(__pyx_k_collections_abc), 0, 0, 1, 0}, - {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0}, - {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0}, - {&__pyx_n_s_count, __pyx_k_count, sizeof(__pyx_k_count), 0, 0, 1, 1}, - {&__pyx_kp_s_count_error, __pyx_k_count_error, sizeof(__pyx_k_count_error), 0, 0, 1, 0}, - {&__pyx_n_s_cy_test_tau_leap_safety, __pyx_k_cy_test_tau_leap_safety, sizeof(__pyx_k_cy_test_tau_leap_safety), 0, 0, 1, 1}, - {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, - {&__pyx_kp_u_disable, __pyx_k_disable, sizeof(__pyx_k_disable), 0, 1, 0, 0}, - {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1}, - {&__pyx_kp_u_enable, __pyx_k_enable, sizeof(__pyx_k_enable), 0, 1, 0, 0}, - {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1}, - {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1}, - {&__pyx_n_s_epsilon, __pyx_k_epsilon, sizeof(__pyx_k_epsilon), 0, 0, 1, 1}, - {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1}, - {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1}, - {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, - {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1}, - {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1}, - {&__pyx_kp_u_gc, __pyx_k_gc, sizeof(__pyx_k_gc), 0, 1, 0, 0}, - {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, - {&__pyx_kp_u_got, __pyx_k_got, sizeof(__pyx_k_got), 0, 1, 0, 0}, - {&__pyx_kp_u_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 1, 0, 0}, - {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, - {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1}, - {&__pyx_n_s_initializing, __pyx_k_initializing, sizeof(__pyx_k_initializing), 0, 0, 1, 1}, - {&__pyx_n_s_is_coroutine, __pyx_k_is_coroutine, sizeof(__pyx_k_is_coroutine), 0, 0, 1, 1}, - {&__pyx_kp_u_isenabled, __pyx_k_isenabled, sizeof(__pyx_k_isenabled), 0, 1, 0, 0}, - {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1}, - {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0}, - {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_max_cdf, __pyx_k_max_cdf, sizeof(__pyx_k_max_cdf), 0, 0, 1, 1}, - {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1}, - {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1}, - {&__pyx_n_s_mu, __pyx_k_mu, sizeof(__pyx_k_mu), 0, 0, 1, 1}, - {&__pyx_n_s_n_rates, __pyx_k_n_rates, sizeof(__pyx_k_n_rates), 0, 0, 1, 1}, - {&__pyx_n_s_n_reactants, __pyx_k_n_reactants, sizeof(__pyx_k_n_reactants), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1}, - {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1}, - {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, - {&__pyx_n_s_new_cdf, __pyx_k_new_cdf, sizeof(__pyx_k_new_cdf), 0, 0, 1, 1}, - {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, - {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, - {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, - {&__pyx_kp_s_numpy__core_multiarray_failed_to, __pyx_k_numpy__core_multiarray_failed_to, sizeof(__pyx_k_numpy__core_multiarray_failed_to), 0, 0, 1, 0}, - {&__pyx_kp_s_numpy__core_umath_failed_to_impo, __pyx_k_numpy__core_umath_failed_to_impo, sizeof(__pyx_k_numpy__core_umath_failed_to_impo), 0, 0, 1, 0}, - {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1}, - {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1}, - {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, - {&__pyx_n_s_print, __pyx_k_print, sizeof(__pyx_k_print), 0, 0, 1, 1}, - {&__pyx_n_s_pygom_model__tau_leap, __pyx_k_pygom_model__tau_leap, sizeof(__pyx_k_pygom_model__tau_leap), 0, 0, 1, 1}, - {&__pyx_kp_s_pygom_model__tau_leap_pyx, __pyx_k_pygom_model__tau_leap_pyx, sizeof(__pyx_k_pygom_model__tau_leap_pyx), 0, 0, 1, 0}, - {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_checksum, __pyx_k_pyx_checksum, sizeof(__pyx_k_pyx_checksum), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_result, __pyx_k_pyx_result, sizeof(__pyx_k_pyx_result), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_type, __pyx_k_pyx_type, sizeof(__pyx_k_pyx_type), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_unpickle_Enum, __pyx_k_pyx_unpickle_Enum, sizeof(__pyx_k_pyx_unpickle_Enum), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, - {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, - {&__pyx_n_s_rates, __pyx_k_rates, sizeof(__pyx_k_rates), 0, 0, 1, 1}, - {&__pyx_n_s_rates_view, __pyx_k_rates_view, sizeof(__pyx_k_rates_view), 0, 0, 1, 1}, - {&__pyx_n_s_reactant_mat, __pyx_k_reactant_mat, sizeof(__pyx_k_reactant_mat), 0, 0, 1, 1}, - {&__pyx_n_s_reactant_mat_view, __pyx_k_reactant_mat_view, sizeof(__pyx_k_reactant_mat_view), 0, 0, 1, 1}, - {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, - {&__pyx_n_s_register, __pyx_k_register, sizeof(__pyx_k_register), 0, 0, 1, 1}, - {&__pyx_n_s_safe, __pyx_k_safe, sizeof(__pyx_k_safe), 0, 0, 1, 1}, - {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, - {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, - {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1}, - {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1}, - {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1}, - {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1}, - {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1}, - {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1}, - {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0}, - {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0}, - {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0}, - {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, - {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1}, - {&__pyx_n_s_sum, __pyx_k_sum, sizeof(__pyx_k_sum), 0, 0, 1, 1}, - {&__pyx_n_s_sys, __pyx_k_sys, sizeof(__pyx_k_sys), 0, 0, 1, 1}, - {&__pyx_n_s_tau_scale, __pyx_k_tau_scale, sizeof(__pyx_k_tau_scale), 0, 0, 1, 1}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_total_rate, __pyx_k_total_rate, sizeof(__pyx_k_total_rate), 0, 0, 1, 1}, - {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0}, - {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0}, - {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1}, - {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, - {&__pyx_n_s_version_info, __pyx_k_version_info, sizeof(__pyx_k_version_info), 0, 0, 1, 1}, - {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1}, - {&__pyx_n_s_x_view, __pyx_k_x_view, sizeof(__pyx_k_x_view), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} - }; - return __Pyx_InitStrings(__pyx_string_tab); -} -/* #### Code section: cached_builtins ### */ -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 37, __pyx_L1_error) - __pyx_builtin_print = __Pyx_GetBuiltinName(__pyx_n_s_print); if (!__pyx_builtin_print) __PYX_ERR(0, 58, __pyx_L1_error) - __pyx_builtin___import__ = __Pyx_GetBuiltinName(__pyx_n_s_import); if (!__pyx_builtin___import__) __PYX_ERR(1, 100, __pyx_L1_error) - __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 141, __pyx_L1_error) - __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(1, 156, __pyx_L1_error) - __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) __PYX_ERR(1, 159, __pyx_L1_error) - __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(1, 2, __pyx_L1_error) - __pyx_builtin_AssertionError = __Pyx_GetBuiltinName(__pyx_n_s_AssertionError); if (!__pyx_builtin_AssertionError) __PYX_ERR(1, 373, __pyx_L1_error) - __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) __PYX_ERR(1, 408, __pyx_L1_error) - __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(1, 618, __pyx_L1_error) - __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(1, 914, __pyx_L1_error) - __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(2, 1026, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} -/* #### Code section: cached_constants ### */ - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "View.MemoryView":582 - * def suboffsets(self): - * if self.view.suboffsets == NULL: - * return (-1,) * self.view.ndim # <<<<<<<<<<<<<< - * - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) - */ - __pyx_tuple__4 = PyTuple_New(1); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 582, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__4); - __Pyx_INCREF(__pyx_int_neg_1); - __Pyx_GIVEREF(__pyx_int_neg_1); - if (__Pyx_PyTuple_SET_ITEM(__pyx_tuple__4, 0, __pyx_int_neg_1)) __PYX_ERR(1, 582, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_tuple__4); - - /* "View.MemoryView":679 - * tup = index if isinstance(index, tuple) else (index,) - * - * result = [slice(None)] * ndim # <<<<<<<<<<<<<< - * have_slices = False - * seen_ellipsis = False - */ - __pyx_slice__5 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__5)) __PYX_ERR(1, 679, __pyx_L1_error) - __Pyx_GOTREF(__pyx_slice__5); - __Pyx_GIVEREF(__pyx_slice__5); - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum not in (0x82a3537, 0x6ae9995, 0xb068931): # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError, "Incompatible checksums (0x%x vs (0x82a3537, 0x6ae9995, 0xb068931) = (name))" % __pyx_checksum - */ - __pyx_tuple__8 = PyTuple_Pack(3, __pyx_int_136983863, __pyx_int_112105877, __pyx_int_184977713); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(1, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__8); - __Pyx_GIVEREF(__pyx_tuple__8); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1026 - * __pyx_import_array() - * except Exception: - * raise ImportError("numpy._core.multiarray failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_umath() except -1: - */ - __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_numpy__core_multiarray_failed_to); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(2, 1026, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__9); - __Pyx_GIVEREF(__pyx_tuple__9); - - /* ".eggs/numpy-2.0.0-py3.9-win-amd64.egg/numpy/__init__.cython-30.pxd":1032 - * _import_umath() - * except Exception: - * raise ImportError("numpy._core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_ufunc() except -1: - */ - __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_numpy__core_umath_failed_to_impo); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(2, 1032, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__10); - __Pyx_GIVEREF(__pyx_tuple__10); - - /* "pygom/model/_tau_leap.pyx":58 - * - * if count > 256: - * print("count error") # <<<<<<<<<<<<<< - * return False - * - */ - __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_count_error); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(0, 58, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__11); - __Pyx_GIVEREF(__pyx_tuple__11); - - /* "View.MemoryView":100 - * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" - * try: - * if __import__("sys").version_info >= (3, 3): # <<<<<<<<<<<<<< - * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence - * else: - */ - __pyx_tuple__12 = PyTuple_Pack(1, __pyx_n_s_sys); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(1, 100, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__12); - __Pyx_GIVEREF(__pyx_tuple__12); - __pyx_tuple__13 = PyTuple_Pack(2, __pyx_int_3, __pyx_int_3); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(1, 100, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__13); - __Pyx_GIVEREF(__pyx_tuple__13); - - /* "View.MemoryView":101 - * try: - * if __import__("sys").version_info >= (3, 3): - * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence # <<<<<<<<<<<<<< - * else: - * __pyx_collections_abc_Sequence = __import__("collections").Sequence - */ - __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_collections_abc); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(1, 101, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__14); - __Pyx_GIVEREF(__pyx_tuple__14); - - /* "View.MemoryView":103 - * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence - * else: - * __pyx_collections_abc_Sequence = __import__("collections").Sequence # <<<<<<<<<<<<<< - * except: - * - */ - __pyx_tuple__15 = PyTuple_Pack(1, __pyx_n_s_collections); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(1, 103, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__15); - __Pyx_GIVEREF(__pyx_tuple__15); - - /* "View.MemoryView":309 - * return self.name - * - * cdef generic = Enum("") # <<<<<<<<<<<<<< - * cdef strided = Enum("") # default - * cdef indirect = Enum("") - */ - __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(1, 309, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__16); - __Pyx_GIVEREF(__pyx_tuple__16); - - /* "View.MemoryView":310 - * - * cdef generic = Enum("") - * cdef strided = Enum("") # default # <<<<<<<<<<<<<< - * cdef indirect = Enum("") - * - */ - __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(1, 310, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__17); - __Pyx_GIVEREF(__pyx_tuple__17); - - /* "View.MemoryView":311 - * cdef generic = Enum("") - * cdef strided = Enum("") # default - * cdef indirect = Enum("") # <<<<<<<<<<<<<< - * - * - */ - __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(1, 311, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__18); - __Pyx_GIVEREF(__pyx_tuple__18); - - /* "View.MemoryView":314 - * - * - * cdef contiguous = Enum("") # <<<<<<<<<<<<<< - * cdef indirect_contiguous = Enum("") - * - */ - __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(1, 314, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__19); - __Pyx_GIVEREF(__pyx_tuple__19); - - /* "View.MemoryView":315 - * - * cdef contiguous = Enum("") - * cdef indirect_contiguous = Enum("") # <<<<<<<<<<<<<< - * - * - */ - __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(1, 315, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__20); - __Pyx_GIVEREF(__pyx_tuple__20); - - /* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_tuple__21 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__21); - __Pyx_GIVEREF(__pyx_tuple__21); - __pyx_codeobj__22 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__21, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_Enum, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__22)) __PYX_ERR(1, 1, __pyx_L1_error) - - /* "pygom/model/_tau_leap.pyx":8 - * cimport cython - * - * @cython.boundscheck(False) # Deactivate bounds checking # <<<<<<<<<<<<<< - * @cython.wraparound(False) # Deactivate negative indexing. - * @cython.cdivision(True) # Deactivate the div 0 error checking - */ - __pyx_tuple__23 = PyTuple_Pack(19, __pyx_n_s_x, __pyx_n_s_reactant_mat, __pyx_n_s_rates, __pyx_n_s_tau_scale, __pyx_n_s_epsilon, __pyx_n_s_rates_view, __pyx_n_s_n_rates, __pyx_n_s_x_view, __pyx_n_s_reactant_mat_view, __pyx_n_s_n_reactants, __pyx_n_s_mu, __pyx_n_s_max_cdf, __pyx_n_s_new_cdf, __pyx_n_s_total_rate, __pyx_n_s_safe, __pyx_n_s_count, __pyx_n_s_cdf_val, __pyx_n_s_i, __pyx_n_s_j); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__23); - __Pyx_GIVEREF(__pyx_tuple__23); - __pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pygom_model__tau_leap_pyx, __pyx_n_s_cy_test_tau_leap_safety, 8, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} -/* #### Code section: init_constants ### */ - -static CYTHON_SMALL_CODE int __Pyx_InitConstants(void) { - if (__Pyx_CreateStringTabAndInitStrings() < 0) __PYX_ERR(0, 1, __pyx_L1_error); - __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_112105877 = PyInt_FromLong(112105877L); if (unlikely(!__pyx_int_112105877)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_136983863 = PyInt_FromLong(136983863L); if (unlikely(!__pyx_int_136983863)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_184977713 = PyInt_FromLong(184977713L); if (unlikely(!__pyx_int_184977713)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) __PYX_ERR(0, 1, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} -/* #### Code section: init_globals ### */ - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - /* AssertionsEnabled.init */ - if (likely(__Pyx_init_assertions_enabled() == 0)); else - -if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) - - /* NumpyImportArray.init */ - /* - * Cython has automatically inserted a call to _import_array since - * you didn't include one when you cimported numpy. To disable this - * add the line - * numpy._import_array - */ -#ifdef NPY_FEATURE_VERSION -#ifndef NO_IMPORT_ARRAY -if (unlikely(_import_array() == -1)) { - PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import " - "(auto-generated because you didn't call 'numpy.import_array()' after cimporting numpy; " - "use 'numpy._import_array' to disable if you are certain you don't need it)."); -} -#endif -#endif - -if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) - - return 0; - __pyx_L1_error:; - return -1; -} -/* #### Code section: init_module ### */ - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - __pyx_collections_abc_Sequence = Py_None; Py_INCREF(Py_None); - generic = Py_None; Py_INCREF(Py_None); - strided = Py_None; Py_INCREF(Py_None); - indirect = Py_None; Py_INCREF(Py_None); - contiguous = Py_None; Py_INCREF(Py_None); - indirect_contiguous = Py_None; Py_INCREF(Py_None); - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - __pyx_vtabptr_array = &__pyx_vtable_array; - __pyx_vtable_array.get_memview = (PyObject *(*)(struct __pyx_array_obj *))__pyx_array_get_memview; - #if CYTHON_USE_TYPE_SPECS - __pyx_array_type = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type___pyx_array_spec, NULL); if (unlikely(!__pyx_array_type)) __PYX_ERR(1, 114, __pyx_L1_error) - #if !CYTHON_COMPILING_IN_LIMITED_API - __pyx_array_type->tp_as_buffer = &__pyx_tp_as_buffer_array; - if (!__pyx_array_type->tp_as_buffer->bf_releasebuffer && __pyx_array_type->tp_base->tp_as_buffer && __pyx_array_type->tp_base->tp_as_buffer->bf_releasebuffer) { - __pyx_array_type->tp_as_buffer->bf_releasebuffer = __pyx_array_type->tp_base->tp_as_buffer->bf_releasebuffer; - } - #elif defined(Py_bf_getbuffer) && defined(Py_bf_releasebuffer) - /* PY_VERSION_HEX >= 0x03090000 || Py_LIMITED_API >= 0x030B0000 */ - #elif defined(_MSC_VER) - #pragma message ("The buffer protocol is not supported in the Limited C-API < 3.11.") - #else - #warning "The buffer protocol is not supported in the Limited C-API < 3.11." - #endif - if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type___pyx_array_spec, __pyx_array_type) < 0) __PYX_ERR(1, 114, __pyx_L1_error) - #else - __pyx_array_type = &__pyx_type___pyx_array; - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - #endif - #if !CYTHON_USE_TYPE_SPECS - if (__Pyx_PyType_Ready(__pyx_array_type) < 0) __PYX_ERR(1, 114, __pyx_L1_error) - #endif - #if PY_MAJOR_VERSION < 3 - __pyx_array_type->tp_print = 0; - #endif - if (__Pyx_SetVtable(__pyx_array_type, __pyx_vtabptr_array) < 0) __PYX_ERR(1, 114, __pyx_L1_error) - #if !CYTHON_COMPILING_IN_LIMITED_API - if (__Pyx_MergeVtables(__pyx_array_type) < 0) __PYX_ERR(1, 114, __pyx_L1_error) - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - if (__Pyx_setup_reduce((PyObject *) __pyx_array_type) < 0) __PYX_ERR(1, 114, __pyx_L1_error) - #endif - #if CYTHON_USE_TYPE_SPECS - __pyx_MemviewEnum_type = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type___pyx_MemviewEnum_spec, NULL); if (unlikely(!__pyx_MemviewEnum_type)) __PYX_ERR(1, 302, __pyx_L1_error) - if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type___pyx_MemviewEnum_spec, __pyx_MemviewEnum_type) < 0) __PYX_ERR(1, 302, __pyx_L1_error) - #else - __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum; - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - #endif - #if !CYTHON_USE_TYPE_SPECS - if (__Pyx_PyType_Ready(__pyx_MemviewEnum_type) < 0) __PYX_ERR(1, 302, __pyx_L1_error) - #endif - #if PY_MAJOR_VERSION < 3 - __pyx_MemviewEnum_type->tp_print = 0; - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_MemviewEnum_type->tp_dictoffset && __pyx_MemviewEnum_type->tp_getattro == PyObject_GenericGetAttr)) { - __pyx_MemviewEnum_type->tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - if (__Pyx_setup_reduce((PyObject *) __pyx_MemviewEnum_type) < 0) __PYX_ERR(1, 302, __pyx_L1_error) - #endif - __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview; - __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer; - __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice; - __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment; - __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar; - __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed; - __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object; - __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object; - __pyx_vtable_memoryview._get_base = (PyObject *(*)(struct __pyx_memoryview_obj *))__pyx_memoryview__get_base; - #if CYTHON_USE_TYPE_SPECS - __pyx_memoryview_type = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type___pyx_memoryview_spec, NULL); if (unlikely(!__pyx_memoryview_type)) __PYX_ERR(1, 337, __pyx_L1_error) - #if !CYTHON_COMPILING_IN_LIMITED_API - __pyx_memoryview_type->tp_as_buffer = &__pyx_tp_as_buffer_memoryview; - if (!__pyx_memoryview_type->tp_as_buffer->bf_releasebuffer && __pyx_memoryview_type->tp_base->tp_as_buffer && __pyx_memoryview_type->tp_base->tp_as_buffer->bf_releasebuffer) { - __pyx_memoryview_type->tp_as_buffer->bf_releasebuffer = __pyx_memoryview_type->tp_base->tp_as_buffer->bf_releasebuffer; - } - #elif defined(Py_bf_getbuffer) && defined(Py_bf_releasebuffer) - /* PY_VERSION_HEX >= 0x03090000 || Py_LIMITED_API >= 0x030B0000 */ - #elif defined(_MSC_VER) - #pragma message ("The buffer protocol is not supported in the Limited C-API < 3.11.") - #else - #warning "The buffer protocol is not supported in the Limited C-API < 3.11." - #endif - if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type___pyx_memoryview_spec, __pyx_memoryview_type) < 0) __PYX_ERR(1, 337, __pyx_L1_error) - #else - __pyx_memoryview_type = &__pyx_type___pyx_memoryview; - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - #endif - #if !CYTHON_USE_TYPE_SPECS - if (__Pyx_PyType_Ready(__pyx_memoryview_type) < 0) __PYX_ERR(1, 337, __pyx_L1_error) - #endif - #if PY_MAJOR_VERSION < 3 - __pyx_memoryview_type->tp_print = 0; - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_memoryview_type->tp_dictoffset && __pyx_memoryview_type->tp_getattro == PyObject_GenericGetAttr)) { - __pyx_memoryview_type->tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - #endif - if (__Pyx_SetVtable(__pyx_memoryview_type, __pyx_vtabptr_memoryview) < 0) __PYX_ERR(1, 337, __pyx_L1_error) - #if !CYTHON_COMPILING_IN_LIMITED_API - if (__Pyx_MergeVtables(__pyx_memoryview_type) < 0) __PYX_ERR(1, 337, __pyx_L1_error) - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - if (__Pyx_setup_reduce((PyObject *) __pyx_memoryview_type) < 0) __PYX_ERR(1, 337, __pyx_L1_error) - #endif - __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice; - __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview; - __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object; - __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object; - __pyx_vtable__memoryviewslice.__pyx_base._get_base = (PyObject *(*)(struct __pyx_memoryview_obj *))__pyx_memoryviewslice__get_base; - #if CYTHON_USE_TYPE_SPECS - __pyx_t_1 = PyTuple_Pack(1, (PyObject *)__pyx_memoryview_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 952, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_memoryviewslice_type = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type___pyx_memoryviewslice_spec, __pyx_t_1); - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - if (unlikely(!__pyx_memoryviewslice_type)) __PYX_ERR(1, 952, __pyx_L1_error) - if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type___pyx_memoryviewslice_spec, __pyx_memoryviewslice_type) < 0) __PYX_ERR(1, 952, __pyx_L1_error) - #else - __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice; - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - __pyx_memoryviewslice_type->tp_base = __pyx_memoryview_type; - #endif - #if !CYTHON_USE_TYPE_SPECS - if (__Pyx_PyType_Ready(__pyx_memoryviewslice_type) < 0) __PYX_ERR(1, 952, __pyx_L1_error) - #endif - #if PY_MAJOR_VERSION < 3 - __pyx_memoryviewslice_type->tp_print = 0; - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_memoryviewslice_type->tp_dictoffset && __pyx_memoryviewslice_type->tp_getattro == PyObject_GenericGetAttr)) { - __pyx_memoryviewslice_type->tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - #endif - if (__Pyx_SetVtable(__pyx_memoryviewslice_type, __pyx_vtabptr__memoryviewslice) < 0) __PYX_ERR(1, 952, __pyx_L1_error) - #if !CYTHON_COMPILING_IN_LIMITED_API - if (__Pyx_MergeVtables(__pyx_memoryviewslice_type) < 0) __PYX_ERR(1, 952, __pyx_L1_error) - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - if (__Pyx_setup_reduce((PyObject *) __pyx_memoryviewslice_type) < 0) __PYX_ERR(1, 952, __pyx_L1_error) - #endif - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType_3_0_10(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", - #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyTypeObject), - #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyTypeObject), - #else - sizeof(PyHeapTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyHeapTypeObject), - #endif - __Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(3, 9, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule("numpy"); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 271, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_5numpy_dtype = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "dtype", sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArray_Descr),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_dtype) __PYX_ERR(2, 271, __pyx_L1_error) - __pyx_ptype_5numpy_flatiter = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "flatiter", sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayIterObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_flatiter) __PYX_ERR(2, 316, __pyx_L1_error) - __pyx_ptype_5numpy_broadcast = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "broadcast", sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayMultiIterObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_broadcast) __PYX_ERR(2, 320, __pyx_L1_error) - __pyx_ptype_5numpy_ndarray = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "ndarray", sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyArrayObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_ndarray) __PYX_ERR(2, 359, __pyx_L1_error) - __pyx_ptype_5numpy_generic = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "generic", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_generic) __PYX_ERR(2, 848, __pyx_L1_error) - __pyx_ptype_5numpy_number = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "number", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_number) __PYX_ERR(2, 850, __pyx_L1_error) - __pyx_ptype_5numpy_integer = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "integer", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_integer) __PYX_ERR(2, 852, __pyx_L1_error) - __pyx_ptype_5numpy_signedinteger = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "signedinteger", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_signedinteger) __PYX_ERR(2, 854, __pyx_L1_error) - __pyx_ptype_5numpy_unsignedinteger = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "unsignedinteger", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_unsignedinteger) __PYX_ERR(2, 856, __pyx_L1_error) - __pyx_ptype_5numpy_inexact = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "inexact", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_inexact) __PYX_ERR(2, 858, __pyx_L1_error) - __pyx_ptype_5numpy_floating = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "floating", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_floating) __PYX_ERR(2, 860, __pyx_L1_error) - __pyx_ptype_5numpy_complexfloating = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "complexfloating", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_complexfloating) __PYX_ERR(2, 862, __pyx_L1_error) - __pyx_ptype_5numpy_flexible = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "flexible", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_flexible) __PYX_ERR(2, 864, __pyx_L1_error) - __pyx_ptype_5numpy_character = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "character", sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyObject),__Pyx_ImportType_CheckSize_Warn_3_0_10); if (!__pyx_ptype_5numpy_character) __PYX_ERR(2, 866, __pyx_L1_error) - __pyx_ptype_5numpy_ufunc = __Pyx_ImportType_3_0_10(__pyx_t_1, "numpy", "ufunc", sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_0_10(PyUFuncObject),__Pyx_ImportType_CheckSize_Ignore_3_0_10); if (!__pyx_ptype_5numpy_ufunc) __PYX_ERR(2, 930, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __pyx_t_1 = PyImport_ImportModule("scipy.special.cython_special"); if (!__pyx_t_1) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (__Pyx_ImportFunction_3_0_10(__pyx_t_1, "pdtr", (void (**)(void))&__pyx_f_5scipy_7special_14cython_special_pdtr, "double (double, double, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; -} - - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec__tau_leap(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec__tau_leap}, - {0, NULL} -}; -#endif - -#ifdef __cplusplus -namespace { - struct PyModuleDef __pyx_moduledef = - #else - static struct PyModuleDef __pyx_moduledef = - #endif - { - PyModuleDef_HEAD_INIT, - "_tau_leap", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #elif CYTHON_USE_MODULE_STATE - sizeof(__pyx_mstate), /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - #if CYTHON_USE_MODULE_STATE - __pyx_m_traverse, /* m_traverse */ - __pyx_m_clear, /* m_clear */ - NULL /* m_free */ - #else - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ - #endif - }; - #ifdef __cplusplus -} /* anonymous namespace */ -#endif -#endif - -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif -#else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC init_tau_leap(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC init_tau_leap(void) -#else -__Pyx_PyMODINIT_FUNC PyInit__tau_leap(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit__tau_leap(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -#if CYTHON_COMPILING_IN_LIMITED_API -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none) -#else -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) -#endif -{ - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { -#if CYTHON_COMPILING_IN_LIMITED_API - result = PyModule_AddObject(module, to_name, value); -#else - result = PyDict_SetItemString(moddict, to_name, value); -#endif - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - CYTHON_UNUSED_VAR(def); - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; -#if CYTHON_COMPILING_IN_LIMITED_API - moddict = module; -#else - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; -#endif - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec__tau_leap(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - int stringtab_initialized = 0; - #if CYTHON_USE_MODULE_STATE - int pystate_addmodule_run = 0; - #endif - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - static PyThread_type_lock __pyx_t_8[8]; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module '_tau_leap' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("_tau_leap", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #elif CYTHON_USE_MODULE_STATE - __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - { - int add_module_result = PyState_AddModule(__pyx_t_1, &__pyx_moduledef); - __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "_tau_leap" pseudovariable */ - if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) - pystate_addmodule_run = 1; - } - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #endif - CYTHON_UNUSED_VAR(__pyx_t_1); - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_cython_runtime = __Pyx_PyImport_AddModuleRef((const char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__tau_leap(void)", 0); - if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - PyEval_InitThreads(); - #endif - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - stringtab_initialized = 1; - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_pygom__model___tau_leap) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name_2, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "pygom.model._tau_leap")) { - if (unlikely((PyDict_SetItemString(modules, "pygom.model._tau_leap", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - if (unlikely((__Pyx_modinit_type_init_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) - if (unlikely((__Pyx_modinit_type_import_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) - (void)__Pyx_modinit_variable_import_code(); - if (unlikely((__Pyx_modinit_function_import_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "View.MemoryView":99 - * - * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" - * try: # <<<<<<<<<<<<<< - * if __import__("sys").version_info >= (3, 3): - * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "View.MemoryView":100 - * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" - * try: - * if __import__("sys").version_info >= (3, 3): # <<<<<<<<<<<<<< - * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence - * else: - */ - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 100, __pyx_L2_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_version_info); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 100, __pyx_L2_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_tuple__13, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 100, __pyx_L2_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(1, 100, __pyx_L2_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - - /* "View.MemoryView":101 - * try: - * if __import__("sys").version_info >= (3, 3): - * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence # <<<<<<<<<<<<<< - * else: - * __pyx_collections_abc_Sequence = __import__("collections").Sequence - */ - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 101, __pyx_L2_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_abc); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 101, __pyx_L2_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_Sequence); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 101, __pyx_L2_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XGOTREF(__pyx_collections_abc_Sequence); - __Pyx_DECREF_SET(__pyx_collections_abc_Sequence, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_4); - __pyx_t_4 = 0; - - /* "View.MemoryView":100 - * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" - * try: - * if __import__("sys").version_info >= (3, 3): # <<<<<<<<<<<<<< - * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence - * else: - */ - goto __pyx_L8; - } - - /* "View.MemoryView":103 - * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence - * else: - * __pyx_collections_abc_Sequence = __import__("collections").Sequence # <<<<<<<<<<<<<< - * except: - * - */ - /*else*/ { - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin___import__, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 103, __pyx_L2_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Sequence); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 103, __pyx_L2_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XGOTREF(__pyx_collections_abc_Sequence); - __Pyx_DECREF_SET(__pyx_collections_abc_Sequence, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_5); - __pyx_t_5 = 0; - } - __pyx_L8:; - - /* "View.MemoryView":99 - * - * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" - * try: # <<<<<<<<<<<<<< - * if __import__("sys").version_info >= (3, 3): - * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L7_try_end; - __pyx_L2_error:; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "View.MemoryView":104 - * else: - * __pyx_collections_abc_Sequence = __import__("collections").Sequence - * except: # <<<<<<<<<<<<<< - * - * __pyx_collections_abc_Sequence = None - */ - /*except:*/ { - __Pyx_AddTraceback("View.MemoryView", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_4, &__pyx_t_7) < 0) __PYX_ERR(1, 104, __pyx_L4_except_error) - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_7); - - /* "View.MemoryView":106 - * except: - * - * __pyx_collections_abc_Sequence = None # <<<<<<<<<<<<<< - * - * - */ - __Pyx_INCREF(Py_None); - __Pyx_XGOTREF(__pyx_collections_abc_Sequence); - __Pyx_DECREF_SET(__pyx_collections_abc_Sequence, Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - goto __pyx_L3_exception_handled; - } - - /* "View.MemoryView":99 - * - * cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence" - * try: # <<<<<<<<<<<<<< - * if __import__("sys").version_info >= (3, 3): - * __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence - */ - __pyx_L4_except_error:; - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L3_exception_handled:; - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - __pyx_L7_try_end:; - } - - /* "View.MemoryView":241 - * - * - * try: # <<<<<<<<<<<<<< - * count = __pyx_collections_abc_Sequence.count - * index = __pyx_collections_abc_Sequence.index - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_2, &__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_1); - /*try:*/ { - - /* "View.MemoryView":242 - * - * try: - * count = __pyx_collections_abc_Sequence.count # <<<<<<<<<<<<<< - * index = __pyx_collections_abc_Sequence.index - * except: - */ - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_count); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 242, __pyx_L11_error) - __Pyx_GOTREF(__pyx_t_7); - if (__Pyx_SetItemOnTypeDict(__pyx_array_type, __pyx_n_s_count, __pyx_t_7) < 0) __PYX_ERR(1, 242, __pyx_L11_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - PyType_Modified(__pyx_array_type); - - /* "View.MemoryView":243 - * try: - * count = __pyx_collections_abc_Sequence.count - * index = __pyx_collections_abc_Sequence.index # <<<<<<<<<<<<<< - * except: - * pass - */ - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_index); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 243, __pyx_L11_error) - __Pyx_GOTREF(__pyx_t_7); - if (__Pyx_SetItemOnTypeDict(__pyx_array_type, __pyx_n_s_index, __pyx_t_7) < 0) __PYX_ERR(1, 243, __pyx_L11_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - PyType_Modified(__pyx_array_type); - - /* "View.MemoryView":241 - * - * - * try: # <<<<<<<<<<<<<< - * count = __pyx_collections_abc_Sequence.count - * index = __pyx_collections_abc_Sequence.index - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - goto __pyx_L16_try_end; - __pyx_L11_error:; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "View.MemoryView":244 - * count = __pyx_collections_abc_Sequence.count - * index = __pyx_collections_abc_Sequence.index - * except: # <<<<<<<<<<<<<< - * pass - * - */ - /*except:*/ { - __Pyx_ErrRestore(0,0,0); - goto __pyx_L12_exception_handled; - } - __pyx_L12_exception_handled:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_2, __pyx_t_1); - __pyx_L16_try_end:; - } - - /* "View.MemoryView":309 - * return self.name - * - * cdef generic = Enum("") # <<<<<<<<<<<<<< - * cdef strided = Enum("") # default - * cdef indirect = Enum("") - */ - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 309, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_XGOTREF(generic); - __Pyx_DECREF_SET(generic, __pyx_t_7); - __Pyx_GIVEREF(__pyx_t_7); - __pyx_t_7 = 0; - - /* "View.MemoryView":310 - * - * cdef generic = Enum("") - * cdef strided = Enum("") # default # <<<<<<<<<<<<<< - * cdef indirect = Enum("") - * - */ - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 310, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_XGOTREF(strided); - __Pyx_DECREF_SET(strided, __pyx_t_7); - __Pyx_GIVEREF(__pyx_t_7); - __pyx_t_7 = 0; - - /* "View.MemoryView":311 - * cdef generic = Enum("") - * cdef strided = Enum("") # default - * cdef indirect = Enum("") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 311, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_XGOTREF(indirect); - __Pyx_DECREF_SET(indirect, __pyx_t_7); - __Pyx_GIVEREF(__pyx_t_7); - __pyx_t_7 = 0; - - /* "View.MemoryView":314 - * - * - * cdef contiguous = Enum("") # <<<<<<<<<<<<<< - * cdef indirect_contiguous = Enum("") - * - */ - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 314, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_XGOTREF(contiguous); - __Pyx_DECREF_SET(contiguous, __pyx_t_7); - __Pyx_GIVEREF(__pyx_t_7); - __pyx_t_7 = 0; - - /* "View.MemoryView":315 - * - * cdef contiguous = Enum("") - * cdef indirect_contiguous = Enum("") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 315, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_XGOTREF(indirect_contiguous); - __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_7); - __Pyx_GIVEREF(__pyx_t_7); - __pyx_t_7 = 0; - - /* "View.MemoryView":323 - * - * - * cdef int __pyx_memoryview_thread_locks_used = 0 # <<<<<<<<<<<<<< - * cdef PyThread_type_lock[8] __pyx_memoryview_thread_locks = [ - * PyThread_allocate_lock(), - */ - __pyx_memoryview_thread_locks_used = 0; - - /* "View.MemoryView":324 - * - * cdef int __pyx_memoryview_thread_locks_used = 0 - * cdef PyThread_type_lock[8] __pyx_memoryview_thread_locks = [ # <<<<<<<<<<<<<< - * PyThread_allocate_lock(), - * PyThread_allocate_lock(), - */ - __pyx_t_8[0] = PyThread_allocate_lock(); - __pyx_t_8[1] = PyThread_allocate_lock(); - __pyx_t_8[2] = PyThread_allocate_lock(); - __pyx_t_8[3] = PyThread_allocate_lock(); - __pyx_t_8[4] = PyThread_allocate_lock(); - __pyx_t_8[5] = PyThread_allocate_lock(); - __pyx_t_8[6] = PyThread_allocate_lock(); - __pyx_t_8[7] = PyThread_allocate_lock(); - memcpy(&(__pyx_memoryview_thread_locks[0]), __pyx_t_8, sizeof(__pyx_memoryview_thread_locks[0]) * (8)); - - /* "View.MemoryView":982 - * - * - * try: # <<<<<<<<<<<<<< - * count = __pyx_collections_abc_Sequence.count - * index = __pyx_collections_abc_Sequence.index - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "View.MemoryView":983 - * - * try: - * count = __pyx_collections_abc_Sequence.count # <<<<<<<<<<<<<< - * index = __pyx_collections_abc_Sequence.index - * except: - */ - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_count); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 983, __pyx_L17_error) - __Pyx_GOTREF(__pyx_t_7); - if (__Pyx_SetItemOnTypeDict(__pyx_memoryviewslice_type, __pyx_n_s_count, __pyx_t_7) < 0) __PYX_ERR(1, 983, __pyx_L17_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - PyType_Modified(__pyx_memoryviewslice_type); - - /* "View.MemoryView":984 - * try: - * count = __pyx_collections_abc_Sequence.count - * index = __pyx_collections_abc_Sequence.index # <<<<<<<<<<<<<< - * except: - * pass - */ - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_index); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 984, __pyx_L17_error) - __Pyx_GOTREF(__pyx_t_7); - if (__Pyx_SetItemOnTypeDict(__pyx_memoryviewslice_type, __pyx_n_s_index, __pyx_t_7) < 0) __PYX_ERR(1, 984, __pyx_L17_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - PyType_Modified(__pyx_memoryviewslice_type); - - /* "View.MemoryView":982 - * - * - * try: # <<<<<<<<<<<<<< - * count = __pyx_collections_abc_Sequence.count - * index = __pyx_collections_abc_Sequence.index - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L22_try_end; - __pyx_L17_error:; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "View.MemoryView":985 - * count = __pyx_collections_abc_Sequence.count - * index = __pyx_collections_abc_Sequence.index - * except: # <<<<<<<<<<<<<< - * pass - * - */ - /*except:*/ { - __Pyx_ErrRestore(0,0,0); - goto __pyx_L18_exception_handled; - } - __pyx_L18_exception_handled:; - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - __pyx_L22_try_end:; - } - - /* "View.MemoryView":988 - * pass - * - * try: # <<<<<<<<<<<<<< - * if __pyx_collections_abc_Sequence: - * - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_2, &__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_1); - /*try:*/ { - - /* "View.MemoryView":989 - * - * try: - * if __pyx_collections_abc_Sequence: # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_collections_abc_Sequence); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(1, 989, __pyx_L23_error) - if (__pyx_t_6) { - - /* "View.MemoryView":993 - * - * - * __pyx_collections_abc_Sequence.register(_memoryviewslice) # <<<<<<<<<<<<<< - * __pyx_collections_abc_Sequence.register(array) - * except: - */ - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_register); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 993, __pyx_L23_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_7, ((PyObject *)__pyx_memoryviewslice_type)); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 993, __pyx_L23_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "View.MemoryView":994 - * - * __pyx_collections_abc_Sequence.register(_memoryviewslice) - * __pyx_collections_abc_Sequence.register(array) # <<<<<<<<<<<<<< - * except: - * pass # ignore failure, it's a minor issue - */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_collections_abc_Sequence, __pyx_n_s_register); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 994, __pyx_L23_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_4, ((PyObject *)__pyx_array_type)); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 994, __pyx_L23_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "View.MemoryView":989 - * - * try: - * if __pyx_collections_abc_Sequence: # <<<<<<<<<<<<<< - * - * - */ - } - - /* "View.MemoryView":988 - * pass - * - * try: # <<<<<<<<<<<<<< - * if __pyx_collections_abc_Sequence: - * - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - goto __pyx_L28_try_end; - __pyx_L23_error:; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "View.MemoryView":995 - * __pyx_collections_abc_Sequence.register(_memoryviewslice) - * __pyx_collections_abc_Sequence.register(array) - * except: # <<<<<<<<<<<<<< - * pass # ignore failure, it's a minor issue - * - */ - /*except:*/ { - __Pyx_ErrRestore(0,0,0); - goto __pyx_L24_exception_handled; - } - __pyx_L24_exception_handled:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_2, __pyx_t_1); - __pyx_L28_try_end:; - } - - /* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_t_7 = PyCFunction_NewEx(&__pyx_mdef_15View_dot_MemoryView_1__pyx_unpickle_Enum, NULL, __pyx_n_s_View_MemoryView); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_Enum, __pyx_t_7) < 0) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "pygom/model/_tau_leap.pyx":1 - * import numpy as np # <<<<<<<<<<<<<< - * cimport numpy as np - * - */ - __pyx_t_7 = __Pyx_ImportDottedModule(__pyx_n_s_numpy, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_7) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "pygom/model/_tau_leap.pyx":8 - * cimport cython - * - * @cython.boundscheck(False) # Deactivate bounds checking # <<<<<<<<<<<<<< - * @cython.wraparound(False) # Deactivate negative indexing. - * @cython.cdivision(True) # Deactivate the div 0 error checking - */ - __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_5pygom_5model_9_tau_leap_1_cy_test_tau_leap_safety, 0, __pyx_n_s_cy_test_tau_leap_safety, NULL, __pyx_n_s_pygom_model__tau_leap, __pyx_d, ((PyObject *)__pyx_codeobj__24)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_cy_test_tau_leap_safety, __pyx_t_7) < 0) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "pygom/model/_tau_leap.pyx":1 - * import numpy as np # <<<<<<<<<<<<<< - * cimport numpy as np - * - */ - __pyx_t_7 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_7) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_7); - if (__pyx_m) { - if (__pyx_d && stringtab_initialized) { - __Pyx_AddTraceback("init pygom.model._tau_leap", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - #if !CYTHON_USE_MODULE_STATE - Py_CLEAR(__pyx_m); - #else - Py_DECREF(__pyx_m); - if (pystate_addmodule_run) { - PyObject *tp, *value, *tb; - PyErr_Fetch(&tp, &value, &tb); - PyState_RemoveModule(&__pyx_moduledef); - PyErr_Restore(tp, value, tb); - } - #endif - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init pygom.model._tau_leap"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} -/* #### Code section: cleanup_globals ### */ -/* #### Code section: cleanup_module ### */ -/* #### Code section: main_method ### */ -/* #### Code section: utility_code_pragmas ### */ -#ifdef _MSC_VER -#pragma warning( push ) -/* Warning 4127: conditional expression is constant - * Cython uses constant conditional expressions to allow in inline functions to be optimized at - * compile-time, so this warning is not useful - */ -#pragma warning( disable : 4127 ) -#endif - - - -/* #### Code section: utility_code_def ### */ - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* PyErrExceptionMatches */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; i= 0x030C00A6 - PyObject *current_exception = tstate->current_exception; - if (unlikely(!current_exception)) return 0; - exc_type = (PyObject*) Py_TYPE(current_exception); - if (exc_type == err) return 1; -#else - exc_type = tstate->curexc_type; - if (exc_type == err) return 1; - if (unlikely(!exc_type)) return 0; -#endif - #if CYTHON_AVOID_BORROWED_REFS - Py_INCREF(exc_type); - #endif - if (unlikely(PyTuple_Check(err))) { - result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); - } else { - result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); - } - #if CYTHON_AVOID_BORROWED_REFS - Py_DECREF(exc_type); - #endif - return result; -} -#endif - -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { -#if PY_VERSION_HEX >= 0x030C00A6 - PyObject *tmp_value; - assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); - if (value) { - #if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) - #endif - PyException_SetTraceback(value, tb); - } - tmp_value = tstate->current_exception; - tstate->current_exception = value; - Py_XDECREF(tmp_value); - Py_XDECREF(type); - Py_XDECREF(tb); -#else - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#endif -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { -#if PY_VERSION_HEX >= 0x030C00A6 - PyObject* exc_value; - exc_value = tstate->current_exception; - tstate->current_exception = 0; - *value = exc_value; - *type = NULL; - *tb = NULL; - if (exc_value) { - *type = (PyObject*) Py_TYPE(exc_value); - Py_INCREF(*type); - #if CYTHON_COMPILING_IN_CPYTHON - *tb = ((PyBaseExceptionObject*) exc_value)->traceback; - Py_XINCREF(*tb); - #else - *tb = PyException_GetTraceback(exc_value); - #endif - } -#else - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#endif -} -#endif - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* PyObjectGetAttrStrNoError */ -#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 -static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - __Pyx_PyErr_Clear(); -} -#endif -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { - PyObject *result; -#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 - (void) PyObject_GetOptionalAttr(obj, attr_name, &result); - return result; -#else -#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { - return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); - } -#endif - result = __Pyx_PyObject_GetAttrStr(obj, attr_name); - if (unlikely(!result)) { - __Pyx_PyObject_GetAttrStr_ClearAttributeError(); - } - return result; -#endif -} - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_b, name); - if (unlikely(!result) && !PyErr_Occurred()) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* TupleAndListFromArray */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { - PyObject *v; - Py_ssize_t i; - for (i = 0; i < length; i++) { - v = dest[i] = src[i]; - Py_INCREF(v); - } -} -static CYTHON_INLINE PyObject * -__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) -{ - PyObject *res; - if (n <= 0) { - Py_INCREF(__pyx_empty_tuple); - return __pyx_empty_tuple; - } - res = PyTuple_New(n); - if (unlikely(res == NULL)) return NULL; - __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); - return res; -} -static CYTHON_INLINE PyObject * -__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) -{ - PyObject *res; - if (n <= 0) { - return PyList_New(0); - } - res = PyList_New(n); - if (unlikely(res == NULL)) return NULL; - __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); - return res; -} -#endif - -/* BytesEquals */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API - return PyObject_RichCompareBool(s1, s2, equals); -#else - if (s1 == s2) { - return (equals == Py_EQ); - } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { - const char *ps1, *ps2; - Py_ssize_t length = PyBytes_GET_SIZE(s1); - if (length != PyBytes_GET_SIZE(s2)) - return (equals == Py_NE); - ps1 = PyBytes_AS_STRING(s1); - ps2 = PyBytes_AS_STRING(s2); - if (ps1[0] != ps2[0]) { - return (equals == Py_NE); - } else if (length == 1) { - return (equals == Py_EQ); - } else { - int result; -#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) - Py_hash_t hash1, hash2; - hash1 = ((PyBytesObject*)s1)->ob_shash; - hash2 = ((PyBytesObject*)s2)->ob_shash; - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - return (equals == Py_NE); - } -#endif - result = memcmp(ps1, ps2, (size_t)length); - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { - return (equals == Py_NE); - } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { - return (equals == Py_NE); - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -#endif -} - -/* UnicodeEquals */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API - return PyObject_RichCompareBool(s1, s2, equals); -#else -#if PY_MAJOR_VERSION < 3 - PyObject* owned_ref = NULL; -#endif - int s1_is_unicode, s2_is_unicode; - if (s1 == s2) { - goto return_eq; - } - s1_is_unicode = PyUnicode_CheckExact(s1); - s2_is_unicode = PyUnicode_CheckExact(s2); -#if PY_MAJOR_VERSION < 3 - if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { - owned_ref = PyUnicode_FromObject(s2); - if (unlikely(!owned_ref)) - return -1; - s2 = owned_ref; - s2_is_unicode = 1; - } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { - owned_ref = PyUnicode_FromObject(s1); - if (unlikely(!owned_ref)) - return -1; - s1 = owned_ref; - s1_is_unicode = 1; - } else if (((!s2_is_unicode) & (!s1_is_unicode))) { - return __Pyx_PyBytes_Equals(s1, s2, equals); - } -#endif - if (s1_is_unicode & s2_is_unicode) { - Py_ssize_t length; - int kind; - void *data1, *data2; - if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) - return -1; - length = __Pyx_PyUnicode_GET_LENGTH(s1); - if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { - goto return_ne; - } -#if CYTHON_USE_UNICODE_INTERNALS - { - Py_hash_t hash1, hash2; - #if CYTHON_PEP393_ENABLED - hash1 = ((PyASCIIObject*)s1)->hash; - hash2 = ((PyASCIIObject*)s2)->hash; - #else - hash1 = ((PyUnicodeObject*)s1)->hash; - hash2 = ((PyUnicodeObject*)s2)->hash; - #endif - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - goto return_ne; - } - } -#endif - kind = __Pyx_PyUnicode_KIND(s1); - if (kind != __Pyx_PyUnicode_KIND(s2)) { - goto return_ne; - } - data1 = __Pyx_PyUnicode_DATA(s1); - data2 = __Pyx_PyUnicode_DATA(s2); - if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { - goto return_ne; - } else if (length == 1) { - goto return_eq; - } else { - int result = memcmp(data1, data2, (size_t)(length * kind)); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & s2_is_unicode) { - goto return_ne; - } else if ((s2 == Py_None) & s1_is_unicode) { - goto return_ne; - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -return_eq: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ); -return_ne: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_NE); -#endif -} - -/* fastcall */ -#if CYTHON_METH_FASTCALL -static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) -{ - Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames); - for (i = 0; i < n; i++) - { - if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i]; - } - for (i = 0; i < n; i++) - { - int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ); - if (unlikely(eq != 0)) { - if (unlikely(eq < 0)) return NULL; - return kwvalues[i]; - } - } - return NULL; -} -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 -CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { - Py_ssize_t i, nkwargs = PyTuple_GET_SIZE(kwnames); - PyObject *dict; - dict = PyDict_New(); - if (unlikely(!dict)) - return NULL; - for (i=0; i= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject *const *kwvalues, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds)); - while (1) { - Py_XDECREF(key); key = NULL; - Py_XDECREF(value); value = NULL; - if (kwds_is_tuple) { - Py_ssize_t size; -#if CYTHON_ASSUME_SAFE_MACROS - size = PyTuple_GET_SIZE(kwds); -#else - size = PyTuple_Size(kwds); - if (size < 0) goto bad; -#endif - if (pos >= size) break; -#if CYTHON_AVOID_BORROWED_REFS - key = __Pyx_PySequence_ITEM(kwds, pos); - if (!key) goto bad; -#elif CYTHON_ASSUME_SAFE_MACROS - key = PyTuple_GET_ITEM(kwds, pos); -#else - key = PyTuple_GetItem(kwds, pos); - if (!key) goto bad; -#endif - value = kwvalues[pos]; - pos++; - } - else - { - if (!PyDict_Next(kwds, &pos, &key, &value)) break; -#if CYTHON_AVOID_BORROWED_REFS - Py_INCREF(key); -#endif - } - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; -#if CYTHON_AVOID_BORROWED_REFS - Py_INCREF(value); - Py_DECREF(key); -#endif - key = NULL; - value = NULL; - continue; - } -#if !CYTHON_AVOID_BORROWED_REFS - Py_INCREF(key); -#endif - Py_INCREF(value); - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; -#if CYTHON_AVOID_BORROWED_REFS - value = NULL; -#endif - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = ( - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key) - ); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; -#if CYTHON_AVOID_BORROWED_REFS - value = NULL; -#endif - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - Py_XDECREF(key); - Py_XDECREF(value); - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - #if PY_MAJOR_VERSION < 3 - PyErr_Format(PyExc_TypeError, - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - PyErr_Format(PyExc_TypeError, - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - Py_XDECREF(key); - Py_XDECREF(value); - return -1; -} - -/* ArgTypeTest */ -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) -{ - __Pyx_TypeName type_name; - __Pyx_TypeName obj_type_name; - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - else if (exact) { - #if PY_MAJOR_VERSION == 2 - if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; - #endif - } - else { - if (likely(__Pyx_TypeCheck(obj, type))) return 1; - } - type_name = __Pyx_PyType_GetName(type); - obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); - PyErr_Format(PyExc_TypeError, - "Argument '%.200s' has incorrect type (expected " __Pyx_FMT_TYPENAME - ", got " __Pyx_FMT_TYPENAME ")", name, type_name, obj_type_name); - __Pyx_DECREF_TypeName(type_name); - __Pyx_DECREF_TypeName(obj_type_name); - return 0; -} - -/* RaiseException */ -#if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - __Pyx_PyThreadState_declare - CYTHON_UNUSED_VAR(cause); - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; - } -#endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } - } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} -#else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; - } - } - } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; - } - } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; - } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; - } - PyException_SetCause(value, fixed_cause); - } - PyErr_SetObject(type, value); - if (tb) { - #if PY_VERSION_HEX >= 0x030C00A6 - PyException_SetTraceback(value, tb); - #elif CYTHON_FAST_THREAD_STATE - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } -#else - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); -#endif - } -bad: - Py_XDECREF(owned_instance); - return; -} -#endif - -/* PyFunctionFastCall */ -#if CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; -} -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - #if PY_MAJOR_VERSION < 3 - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) { - return NULL; - } - #else - if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) { - return NULL; - } - #endif - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } - } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; - } - nk = i / 2; - } - else { - kwtuple = NULL; - k = NULL; - } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); - } - else { - d = NULL; - nd = 0; - } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; -} -#endif - -/* PyObjectCall */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = Py_TYPE(func)->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - #if PY_MAJOR_VERSION < 3 - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - #else - if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) - return NULL; - #endif - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallMethO */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); - self = __Pyx_CyOrPyCFunction_GET_SELF(func); - #if PY_MAJOR_VERSION < 3 - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - #else - if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) - return NULL; - #endif - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectFastCall */ -#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API -static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs) { - PyObject *argstuple; - PyObject *result = 0; - size_t i; - argstuple = PyTuple_New((Py_ssize_t)nargs); - if (unlikely(!argstuple)) return NULL; - for (i = 0; i < nargs; i++) { - Py_INCREF(args[i]); - if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) < 0) goto bad; - } - result = __Pyx_PyObject_Call(func, argstuple, kwargs); - bad: - Py_DECREF(argstuple); - return result; -} -#endif -static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t _nargs, PyObject *kwargs) { - Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); -#if CYTHON_COMPILING_IN_CPYTHON - if (nargs == 0 && kwargs == NULL) { - if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) - return __Pyx_PyObject_CallMethO(func, NULL); - } - else if (nargs == 1 && kwargs == NULL) { - if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) - return __Pyx_PyObject_CallMethO(func, args[0]); - } -#endif - #if PY_VERSION_HEX < 0x030800B1 - #if CYTHON_FAST_PYCCALL - if (PyCFunction_Check(func)) { - if (kwargs) { - return _PyCFunction_FastCallDict(func, args, nargs, kwargs); - } else { - return _PyCFunction_FastCallKeywords(func, args, nargs, NULL); - } - } - #if PY_VERSION_HEX >= 0x030700A1 - if (!kwargs && __Pyx_IS_TYPE(func, &PyMethodDescr_Type)) { - return _PyMethodDescr_FastCallKeywords(func, args, nargs, NULL); - } - #endif - #endif - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs); - } - #endif - #endif - if (kwargs == NULL) { - #if CYTHON_VECTORCALL - #if PY_VERSION_HEX < 0x03090000 - vectorcallfunc f = _PyVectorcall_Function(func); - #else - vectorcallfunc f = PyVectorcall_Function(func); - #endif - if (f) { - return f(func, args, (size_t)nargs, NULL); - } - #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL - if (__Pyx_CyFunction_CheckExact(func)) { - __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func); - if (f) return f(func, args, (size_t)nargs, NULL); - } - #endif - } - if (nargs == 0) { - return __Pyx_PyObject_Call(func, __pyx_empty_tuple, kwargs); - } - #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API - return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); - #else - return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); - #endif -} - -/* RaiseUnexpectedTypeError */ -static int -__Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj) -{ - __Pyx_TypeName obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); - PyErr_Format(PyExc_TypeError, "Expected %s, got " __Pyx_FMT_TYPENAME, - expected, obj_type_name); - __Pyx_DECREF_TypeName(obj_type_name); - return 0; -} - -/* CIntToDigits */ -static const char DIGIT_PAIRS_10[2*10*10+1] = { - "00010203040506070809" - "10111213141516171819" - "20212223242526272829" - "30313233343536373839" - "40414243444546474849" - "50515253545556575859" - "60616263646566676869" - "70717273747576777879" - "80818283848586878889" - "90919293949596979899" -}; -static const char DIGIT_PAIRS_8[2*8*8+1] = { - "0001020304050607" - "1011121314151617" - "2021222324252627" - "3031323334353637" - "4041424344454647" - "5051525354555657" - "6061626364656667" - "7071727374757677" -}; -static const char DIGITS_HEX[2*16+1] = { - "0123456789abcdef" - "0123456789ABCDEF" -}; - -/* BuildPyUnicode */ -static PyObject* __Pyx_PyUnicode_BuildFromAscii(Py_ssize_t ulength, char* chars, int clength, - int prepend_sign, char padding_char) { - PyObject *uval; - Py_ssize_t uoffset = ulength - clength; -#if CYTHON_USE_UNICODE_INTERNALS - Py_ssize_t i; -#if CYTHON_PEP393_ENABLED - void *udata; - uval = PyUnicode_New(ulength, 127); - if (unlikely(!uval)) return NULL; - udata = PyUnicode_DATA(uval); -#else - Py_UNICODE *udata; - uval = PyUnicode_FromUnicode(NULL, ulength); - if (unlikely(!uval)) return NULL; - udata = PyUnicode_AS_UNICODE(uval); -#endif - if (uoffset > 0) { - i = 0; - if (prepend_sign) { - __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, 0, '-'); - i++; - } - for (; i < uoffset; i++) { - __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, i, padding_char); - } - } - for (i=0; i < clength; i++) { - __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, uoffset+i, chars[i]); - } -#else - { - PyObject *sign = NULL, *padding = NULL; - uval = NULL; - if (uoffset > 0) { - prepend_sign = !!prepend_sign; - if (uoffset > prepend_sign) { - padding = PyUnicode_FromOrdinal(padding_char); - if (likely(padding) && uoffset > prepend_sign + 1) { - PyObject *tmp; - PyObject *repeat = PyInt_FromSsize_t(uoffset - prepend_sign); - if (unlikely(!repeat)) goto done_or_error; - tmp = PyNumber_Multiply(padding, repeat); - Py_DECREF(repeat); - Py_DECREF(padding); - padding = tmp; - } - if (unlikely(!padding)) goto done_or_error; - } - if (prepend_sign) { - sign = PyUnicode_FromOrdinal('-'); - if (unlikely(!sign)) goto done_or_error; - } - } - uval = PyUnicode_DecodeASCII(chars, clength, NULL); - if (likely(uval) && padding) { - PyObject *tmp = PyNumber_Add(padding, uval); - Py_DECREF(uval); - uval = tmp; - } - if (likely(uval) && sign) { - PyObject *tmp = PyNumber_Add(sign, uval); - Py_DECREF(uval); - uval = tmp; - } -done_or_error: - Py_XDECREF(padding); - Py_XDECREF(sign); - } -#endif - return uval; -} - -/* CIntToPyUnicode */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_int(int value, Py_ssize_t width, char padding_char, char format_char) { - char digits[sizeof(int)*3+2]; - char *dpos, *end = digits + sizeof(int)*3+2; - const char *hex_digits = DIGITS_HEX; - Py_ssize_t length, ulength; - int prepend_sign, last_one_off; - int remaining; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const int neg_one = (int) -1, const_zero = (int) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (format_char == 'X') { - hex_digits += 16; - format_char = 'x'; - } - remaining = value; - last_one_off = 0; - dpos = end; - do { - int digit_pos; - switch (format_char) { - case 'o': - digit_pos = abs((int)(remaining % (8*8))); - remaining = (int) (remaining / (8*8)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); - last_one_off = (digit_pos < 8); - break; - case 'd': - digit_pos = abs((int)(remaining % (10*10))); - remaining = (int) (remaining / (10*10)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); - last_one_off = (digit_pos < 10); - break; - case 'x': - *(--dpos) = hex_digits[abs((int)(remaining % 16))]; - remaining = (int) (remaining / 16); - break; - default: - assert(0); - break; - } - } while (unlikely(remaining != 0)); - assert(!last_one_off || *dpos == '0'); - dpos += last_one_off; - length = end - dpos; - ulength = length; - prepend_sign = 0; - if (!is_unsigned && value <= neg_one) { - if (padding_char == ' ' || width <= length + 1) { - *(--dpos) = '-'; - ++length; - } else { - prepend_sign = 1; - } - ++ulength; - } - if (width > ulength) { - ulength = width; - } - if (ulength == 1) { - return PyUnicode_FromOrdinal(*dpos); - } - return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); -} - -/* CIntToPyUnicode */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_Py_ssize_t(Py_ssize_t value, Py_ssize_t width, char padding_char, char format_char) { - char digits[sizeof(Py_ssize_t)*3+2]; - char *dpos, *end = digits + sizeof(Py_ssize_t)*3+2; - const char *hex_digits = DIGITS_HEX; - Py_ssize_t length, ulength; - int prepend_sign, last_one_off; - Py_ssize_t remaining; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const Py_ssize_t neg_one = (Py_ssize_t) -1, const_zero = (Py_ssize_t) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (format_char == 'X') { - hex_digits += 16; - format_char = 'x'; - } - remaining = value; - last_one_off = 0; - dpos = end; - do { - int digit_pos; - switch (format_char) { - case 'o': - digit_pos = abs((int)(remaining % (8*8))); - remaining = (Py_ssize_t) (remaining / (8*8)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); - last_one_off = (digit_pos < 8); - break; - case 'd': - digit_pos = abs((int)(remaining % (10*10))); - remaining = (Py_ssize_t) (remaining / (10*10)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); - last_one_off = (digit_pos < 10); - break; - case 'x': - *(--dpos) = hex_digits[abs((int)(remaining % 16))]; - remaining = (Py_ssize_t) (remaining / 16); - break; - default: - assert(0); - break; - } - } while (unlikely(remaining != 0)); - assert(!last_one_off || *dpos == '0'); - dpos += last_one_off; - length = end - dpos; - ulength = length; - prepend_sign = 0; - if (!is_unsigned && value <= neg_one) { - if (padding_char == ' ' || width <= length + 1) { - *(--dpos) = '-'; - ++length; - } else { - prepend_sign = 1; - } - ++ulength; - } - if (width > ulength) { - ulength = width; - } - if (ulength == 1) { - return PyUnicode_FromOrdinal(*dpos); - } - return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); -} - -/* JoinPyUnicode */ -static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength, - Py_UCS4 max_char) { -#if CYTHON_USE_UNICODE_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - PyObject *result_uval; - int result_ukind, kind_shift; - Py_ssize_t i, char_pos; - void *result_udata; - CYTHON_MAYBE_UNUSED_VAR(max_char); -#if CYTHON_PEP393_ENABLED - result_uval = PyUnicode_New(result_ulength, max_char); - if (unlikely(!result_uval)) return NULL; - result_ukind = (max_char <= 255) ? PyUnicode_1BYTE_KIND : (max_char <= 65535) ? PyUnicode_2BYTE_KIND : PyUnicode_4BYTE_KIND; - kind_shift = (result_ukind == PyUnicode_4BYTE_KIND) ? 2 : result_ukind - 1; - result_udata = PyUnicode_DATA(result_uval); -#else - result_uval = PyUnicode_FromUnicode(NULL, result_ulength); - if (unlikely(!result_uval)) return NULL; - result_ukind = sizeof(Py_UNICODE); - kind_shift = (result_ukind == 4) ? 2 : result_ukind - 1; - result_udata = PyUnicode_AS_UNICODE(result_uval); -#endif - assert(kind_shift == 2 || kind_shift == 1 || kind_shift == 0); - char_pos = 0; - for (i=0; i < value_count; i++) { - int ukind; - Py_ssize_t ulength; - void *udata; - PyObject *uval = PyTuple_GET_ITEM(value_tuple, i); - if (unlikely(__Pyx_PyUnicode_READY(uval))) - goto bad; - ulength = __Pyx_PyUnicode_GET_LENGTH(uval); - if (unlikely(!ulength)) - continue; - if (unlikely((PY_SSIZE_T_MAX >> kind_shift) - ulength < char_pos)) - goto overflow; - ukind = __Pyx_PyUnicode_KIND(uval); - udata = __Pyx_PyUnicode_DATA(uval); - if (!CYTHON_PEP393_ENABLED || ukind == result_ukind) { - memcpy((char *)result_udata + (char_pos << kind_shift), udata, (size_t) (ulength << kind_shift)); - } else { - #if PY_VERSION_HEX >= 0x030d0000 - if (unlikely(PyUnicode_CopyCharacters(result_uval, char_pos, uval, 0, ulength) < 0)) goto bad; - #elif CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030300F0 || defined(_PyUnicode_FastCopyCharacters) - _PyUnicode_FastCopyCharacters(result_uval, char_pos, uval, 0, ulength); - #else - Py_ssize_t j; - for (j=0; j < ulength; j++) { - Py_UCS4 uchar = __Pyx_PyUnicode_READ(ukind, udata, j); - __Pyx_PyUnicode_WRITE(result_ukind, result_udata, char_pos+j, uchar); - } - #endif - } - char_pos += ulength; - } - return result_uval; -overflow: - PyErr_SetString(PyExc_OverflowError, "join() result is too long for a Python string"); -bad: - Py_DECREF(result_uval); - return NULL; -#else - CYTHON_UNUSED_VAR(max_char); - CYTHON_UNUSED_VAR(result_ulength); - CYTHON_UNUSED_VAR(value_count); - return PyUnicode_Join(__pyx_empty_unicode, value_tuple); -#endif -} - -/* GetAttr */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { -#if CYTHON_USE_TYPE_SLOTS -#if PY_MAJOR_VERSION >= 3 - if (likely(PyUnicode_Check(n))) -#else - if (likely(PyString_Check(n))) -#endif - return __Pyx_PyObject_GetAttrStr(o, n); -#endif - return PyObject_GetAttr(o, n); -} - -/* GetItemInt */ -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (unlikely(!j)) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; - PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; - if (mm && mm->mp_subscript) { - PyObject *r, *key = PyInt_FromSsize_t(i); - if (unlikely(!key)) return NULL; - r = mm->mp_subscript(o, key); - Py_DECREF(key); - return r; - } - if (likely(sm && sm->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { - Py_ssize_t l = sm->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - } - return sm->sq_item(o, i); - } - } -#else - if (is_list || !PyMapping_Check(o)) { - return PySequence_GetItem(o, i); - } -#endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* PyObjectCallOneArg */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *args[2] = {NULL, arg}; - return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); -} - -/* ObjectGetItem */ -#if CYTHON_USE_TYPE_SLOTS -static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject *index) { - PyObject *runerr = NULL; - Py_ssize_t key_value; - key_value = __Pyx_PyIndex_AsSsize_t(index); - if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { - return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); - } - if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { - __Pyx_TypeName index_type_name = __Pyx_PyType_GetName(Py_TYPE(index)); - PyErr_Clear(); - PyErr_Format(PyExc_IndexError, - "cannot fit '" __Pyx_FMT_TYPENAME "' into an index-sized integer", index_type_name); - __Pyx_DECREF_TypeName(index_type_name); - } - return NULL; -} -static PyObject *__Pyx_PyObject_GetItem_Slow(PyObject *obj, PyObject *key) { - __Pyx_TypeName obj_type_name; - if (likely(PyType_Check(obj))) { - PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(obj, __pyx_n_s_class_getitem); - if (!meth) { - PyErr_Clear(); - } else { - PyObject *result = __Pyx_PyObject_CallOneArg(meth, key); - Py_DECREF(meth); - return result; - } - } - obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); - PyErr_Format(PyExc_TypeError, - "'" __Pyx_FMT_TYPENAME "' object is not subscriptable", obj_type_name); - __Pyx_DECREF_TypeName(obj_type_name); - return NULL; -} -static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key) { - PyTypeObject *tp = Py_TYPE(obj); - PyMappingMethods *mm = tp->tp_as_mapping; - PySequenceMethods *sm = tp->tp_as_sequence; - if (likely(mm && mm->mp_subscript)) { - return mm->mp_subscript(obj, key); - } - if (likely(sm && sm->sq_item)) { - return __Pyx_PyObject_GetIndex(obj, key); - } - return __Pyx_PyObject_GetItem_Slow(obj, key); -} -#endif - -/* KeywordStringCheck */ -static int __Pyx_CheckKeywordStrings( - PyObject *kw, - const char* function_name, - int kw_allowed) -{ - PyObject* key = 0; - Py_ssize_t pos = 0; -#if CYTHON_COMPILING_IN_PYPY - if (!kw_allowed && PyDict_Next(kw, &pos, &key, 0)) - goto invalid_keyword; - return 1; -#else - if (CYTHON_METH_FASTCALL && likely(PyTuple_Check(kw))) { - Py_ssize_t kwsize; -#if CYTHON_ASSUME_SAFE_MACROS - kwsize = PyTuple_GET_SIZE(kw); -#else - kwsize = PyTuple_Size(kw); - if (kwsize < 0) return 0; -#endif - if (unlikely(kwsize == 0)) - return 1; - if (!kw_allowed) { -#if CYTHON_ASSUME_SAFE_MACROS - key = PyTuple_GET_ITEM(kw, 0); -#else - key = PyTuple_GetItem(kw, pos); - if (!key) return 0; -#endif - goto invalid_keyword; - } -#if PY_VERSION_HEX < 0x03090000 - for (pos = 0; pos < kwsize; pos++) { -#if CYTHON_ASSUME_SAFE_MACROS - key = PyTuple_GET_ITEM(kw, pos); -#else - key = PyTuple_GetItem(kw, pos); - if (!key) return 0; -#endif - if (unlikely(!PyUnicode_Check(key))) - goto invalid_keyword_type; - } -#endif - return 1; - } - while (PyDict_Next(kw, &pos, &key, 0)) { - #if PY_MAJOR_VERSION < 3 - if (unlikely(!PyString_Check(key))) - #endif - if (unlikely(!PyUnicode_Check(key))) - goto invalid_keyword_type; - } - if (!kw_allowed && unlikely(key)) - goto invalid_keyword; - return 1; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - return 0; -#endif -invalid_keyword: - #if PY_MAJOR_VERSION < 3 - PyErr_Format(PyExc_TypeError, - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - PyErr_Format(PyExc_TypeError, - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif - return 0; -} - -/* DivInt[Py_ssize_t] */ -static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) { - Py_ssize_t q = a / b; - Py_ssize_t r = a - q*b; - q -= ((r != 0) & ((r ^ b) < 0)); - return q; -} - -/* GetAttr3 */ -#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 -static PyObject *__Pyx_GetAttr3Default(PyObject *d) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - return NULL; - __Pyx_PyErr_Clear(); - Py_INCREF(d); - return d; -} -#endif -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { - PyObject *r; -#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 - int res = PyObject_GetOptionalAttr(o, n, &r); - return (res != 0) ? r : __Pyx_NewRef(d); -#else - #if CYTHON_USE_TYPE_SLOTS - if (likely(PyString_Check(n))) { - r = __Pyx_PyObject_GetAttrStrNoError(o, n); - if (unlikely(!r) && likely(!PyErr_Occurred())) { - r = __Pyx_NewRef(d); - } - return r; - } - #endif - r = PyObject_GetAttr(o, n); - return (likely(r)) ? r : __Pyx_GetAttr3Default(d); -#endif -} - -/* PyDictVersioning */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* GetModuleGlobalName */ -#if CYTHON_USE_DICT_VERSIONS -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) -#else -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) -#endif -{ - PyObject *result; -#if !CYTHON_AVOID_BORROWED_REFS -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && PY_VERSION_HEX < 0x030d0000 - result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } else if (unlikely(PyErr_Occurred())) { - return NULL; - } -#elif CYTHON_COMPILING_IN_LIMITED_API - if (unlikely(!__pyx_m)) { - return NULL; - } - result = PyObject_GetAttr(__pyx_m, name); - if (likely(result)) { - return result; - } -#else - result = PyDict_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } -#endif -#else - result = PyObject_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } - PyErr_Clear(); -#endif - return __Pyx_GetBuiltinName(name); -} - -/* RaiseTooManyValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); -} - -/* RaiseNeedMoreValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { - PyErr_Format(PyExc_ValueError, - "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", - index, (index == 1) ? "" : "s"); -} - -/* RaiseNoneIterError */ -static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); -} - -/* ExtTypeTest */ -static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { - __Pyx_TypeName obj_type_name; - __Pyx_TypeName type_name; - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - if (likely(__Pyx_TypeCheck(obj, type))) - return 1; - obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); - type_name = __Pyx_PyType_GetName(type); - PyErr_Format(PyExc_TypeError, - "Cannot convert " __Pyx_FMT_TYPENAME " to " __Pyx_FMT_TYPENAME, - obj_type_name, type_name); - __Pyx_DECREF_TypeName(obj_type_name); - __Pyx_DECREF_TypeName(type_name); - return 0; -} - -/* GetTopmostException */ -#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE -static _PyErr_StackItem * -__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) -{ - _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && - exc_info->previous_item != NULL) - { - exc_info = exc_info->previous_item; - } - return exc_info; -} -#endif - -/* SaveResetException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - PyObject *exc_value = exc_info->exc_value; - if (exc_value == NULL || exc_value == Py_None) { - *value = NULL; - *type = NULL; - *tb = NULL; - } else { - *value = exc_value; - Py_INCREF(*value); - *type = (PyObject*) Py_TYPE(exc_value); - Py_INCREF(*type); - *tb = PyException_GetTraceback(exc_value); - } - #elif CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - *type = exc_info->exc_type; - *value = exc_info->exc_value; - *tb = exc_info->exc_traceback; - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); - #else - *type = tstate->exc_type; - *value = tstate->exc_value; - *tb = tstate->exc_traceback; - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); - #endif -} -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 - _PyErr_StackItem *exc_info = tstate->exc_info; - PyObject *tmp_value = exc_info->exc_value; - exc_info->exc_value = value; - Py_XDECREF(tmp_value); - Py_XDECREF(type); - Py_XDECREF(tb); - #else - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = type; - exc_info->exc_value = value; - exc_info->exc_traceback = tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = type; - tstate->exc_value = value; - tstate->exc_traceback = tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); - #endif -} -#endif - -/* GetException */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) -#endif -{ - PyObject *local_type = NULL, *local_value, *local_tb = NULL; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030C00A6 - local_value = tstate->current_exception; - tstate->current_exception = 0; - if (likely(local_value)) { - local_type = (PyObject*) Py_TYPE(local_value); - Py_INCREF(local_type); - local_tb = PyException_GetTraceback(local_value); - } - #else - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; - #endif -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE && PY_VERSION_HEX >= 0x030C00A6 - if (unlikely(tstate->current_exception)) -#elif CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if CYTHON_USE_EXC_INFO_STACK - { - _PyErr_StackItem *exc_info = tstate->exc_info; - #if PY_VERSION_HEX >= 0x030B00a4 - tmp_value = exc_info->exc_value; - exc_info->exc_value = local_value; - tmp_type = NULL; - tmp_tb = NULL; - Py_XDECREF(local_type); - Py_XDECREF(local_tb); - #else - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = local_type; - exc_info->exc_value = local_value; - exc_info->exc_traceback = local_tb; - #endif - } - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); - return -1; -} - -/* SwapException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_value = exc_info->exc_value; - exc_info->exc_value = *value; - if (tmp_value == NULL || tmp_value == Py_None) { - Py_XDECREF(tmp_value); - tmp_value = NULL; - tmp_type = NULL; - tmp_tb = NULL; - } else { - tmp_type = (PyObject*) Py_TYPE(tmp_value); - Py_INCREF(tmp_type); - #if CYTHON_COMPILING_IN_CPYTHON - tmp_tb = ((PyBaseExceptionObject*) tmp_value)->traceback; - Py_XINCREF(tmp_tb); - #else - tmp_tb = PyException_GetTraceback(tmp_value); - #endif - } - #elif CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = *type; - exc_info->exc_value = *value; - exc_info->exc_traceback = *tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = *type; - tstate->exc_value = *value; - tstate->exc_traceback = *tb; - #endif - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); - PyErr_SetExcInfo(*type, *value, *tb); - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#endif - -/* Import */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *module = 0; - PyObject *empty_dict = 0; - PyObject *empty_list = 0; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (unlikely(!py_import)) - goto bad; - if (!from_list) { - empty_list = PyList_New(0); - if (unlikely(!empty_list)) - goto bad; - from_list = empty_list; - } - #endif - empty_dict = PyDict_New(); - if (unlikely(!empty_dict)) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if (strchr(__Pyx_MODULE_NAME, '.') != NULL) { - module = PyImport_ImportModuleLevelObject( - name, __pyx_d, empty_dict, from_list, 1); - if (unlikely(!module)) { - if (unlikely(!PyErr_ExceptionMatches(PyExc_ImportError))) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (unlikely(!py_level)) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, __pyx_d, empty_dict, from_list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, __pyx_d, empty_dict, from_list, level); - #endif - } - } -bad: - Py_XDECREF(empty_dict); - Py_XDECREF(empty_list); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - return module; -} - -/* ImportDottedModule */ -#if PY_MAJOR_VERSION >= 3 -static PyObject *__Pyx__ImportDottedModule_Error(PyObject *name, PyObject *parts_tuple, Py_ssize_t count) { - PyObject *partial_name = NULL, *slice = NULL, *sep = NULL; - if (unlikely(PyErr_Occurred())) { - PyErr_Clear(); - } - if (likely(PyTuple_GET_SIZE(parts_tuple) == count)) { - partial_name = name; - } else { - slice = PySequence_GetSlice(parts_tuple, 0, count); - if (unlikely(!slice)) - goto bad; - sep = PyUnicode_FromStringAndSize(".", 1); - if (unlikely(!sep)) - goto bad; - partial_name = PyUnicode_Join(sep, slice); - } - PyErr_Format( -#if PY_MAJOR_VERSION < 3 - PyExc_ImportError, - "No module named '%s'", PyString_AS_STRING(partial_name)); -#else -#if PY_VERSION_HEX >= 0x030600B1 - PyExc_ModuleNotFoundError, -#else - PyExc_ImportError, -#endif - "No module named '%U'", partial_name); -#endif -bad: - Py_XDECREF(sep); - Py_XDECREF(slice); - Py_XDECREF(partial_name); - return NULL; -} -#endif -#if PY_MAJOR_VERSION >= 3 -static PyObject *__Pyx__ImportDottedModule_Lookup(PyObject *name) { - PyObject *imported_module; -#if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) - PyObject *modules = PyImport_GetModuleDict(); - if (unlikely(!modules)) - return NULL; - imported_module = __Pyx_PyDict_GetItemStr(modules, name); - Py_XINCREF(imported_module); -#else - imported_module = PyImport_GetModule(name); -#endif - return imported_module; -} -#endif -#if PY_MAJOR_VERSION >= 3 -static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple) { - Py_ssize_t i, nparts; - nparts = PyTuple_GET_SIZE(parts_tuple); - for (i=1; i < nparts && module; i++) { - PyObject *part, *submodule; -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - part = PyTuple_GET_ITEM(parts_tuple, i); -#else - part = PySequence_ITEM(parts_tuple, i); -#endif - submodule = __Pyx_PyObject_GetAttrStrNoError(module, part); -#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) - Py_DECREF(part); -#endif - Py_DECREF(module); - module = submodule; - } - if (unlikely(!module)) { - return __Pyx__ImportDottedModule_Error(name, parts_tuple, i); - } - return module; -} -#endif -static PyObject *__Pyx__ImportDottedModule(PyObject *name, PyObject *parts_tuple) { -#if PY_MAJOR_VERSION < 3 - PyObject *module, *from_list, *star = __pyx_n_s__3; - CYTHON_UNUSED_VAR(parts_tuple); - from_list = PyList_New(1); - if (unlikely(!from_list)) - return NULL; - Py_INCREF(star); - PyList_SET_ITEM(from_list, 0, star); - module = __Pyx_Import(name, from_list, 0); - Py_DECREF(from_list); - return module; -#else - PyObject *imported_module; - PyObject *module = __Pyx_Import(name, NULL, 0); - if (!parts_tuple || unlikely(!module)) - return module; - imported_module = __Pyx__ImportDottedModule_Lookup(name); - if (likely(imported_module)) { - Py_DECREF(module); - return imported_module; - } - PyErr_Clear(); - return __Pyx_ImportDottedModule_WalkParts(module, name, parts_tuple); -#endif -} -static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple) { -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030400B1 - PyObject *module = __Pyx__ImportDottedModule_Lookup(name); - if (likely(module)) { - PyObject *spec = __Pyx_PyObject_GetAttrStrNoError(module, __pyx_n_s_spec); - if (likely(spec)) { - PyObject *unsafe = __Pyx_PyObject_GetAttrStrNoError(spec, __pyx_n_s_initializing); - if (likely(!unsafe || !__Pyx_PyObject_IsTrue(unsafe))) { - Py_DECREF(spec); - spec = NULL; - } - Py_XDECREF(unsafe); - } - if (likely(!spec)) { - PyErr_Clear(); - return module; - } - Py_DECREF(spec); - Py_DECREF(module); - } else if (PyErr_Occurred()) { - PyErr_Clear(); - } -#endif - return __Pyx__ImportDottedModule(name, parts_tuple); -} - -/* FastTypeChecks */ -#if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (cls == a || cls == b) return 1; - mro = cls->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - PyObject *base = PyTuple_GET_ITEM(mro, i); - if (base == (PyObject *)a || base == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - if (exc_type1) { - return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); - } else { - return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; itp_as_sequence && type->tp_as_sequence->sq_repeat)) { - return type->tp_as_sequence->sq_repeat(seq, mul); - } else -#endif - { - return __Pyx_PySequence_Multiply_Generic(seq, mul); - } -} - -/* SetItemInt */ -static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { - int r; - if (unlikely(!j)) return -1; - r = PyObject_SetItem(o, j, v); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int is_list, - CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o)); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o)))) { - PyObject* old = PyList_GET_ITEM(o, n); - Py_INCREF(v); - PyList_SET_ITEM(o, n, v); - Py_DECREF(old); - return 1; - } - } else { - PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; - PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; - if (mm && mm->mp_ass_subscript) { - int r; - PyObject *key = PyInt_FromSsize_t(i); - if (unlikely(!key)) return -1; - r = mm->mp_ass_subscript(o, key, v); - Py_DECREF(key); - return r; - } - if (likely(sm && sm->sq_ass_item)) { - if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { - Py_ssize_t l = sm->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return -1; - PyErr_Clear(); - } - } - return sm->sq_ass_item(o, i, v); - } - } -#else - if (is_list || !PyMapping_Check(o)) - { - return PySequence_SetItem(o, i, v); - } -#endif - return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v); -} - -/* RaiseUnboundLocalError */ -static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) { - PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname); -} - -/* DivInt[long] */ -static CYTHON_INLINE long __Pyx_div_long(long a, long b) { - long q = a / b; - long r = a - q*b; - q -= ((r != 0) & ((r ^ b) < 0)); - return q; -} - -/* ImportFrom */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { - PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); - if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { - const char* module_name_str = 0; - PyObject* module_name = 0; - PyObject* module_dot = 0; - PyObject* full_name = 0; - PyErr_Clear(); - module_name_str = PyModule_GetName(module); - if (unlikely(!module_name_str)) { goto modbad; } - module_name = PyUnicode_FromString(module_name_str); - if (unlikely(!module_name)) { goto modbad; } - module_dot = PyUnicode_Concat(module_name, __pyx_kp_u__2); - if (unlikely(!module_dot)) { goto modbad; } - full_name = PyUnicode_Concat(module_dot, name); - if (unlikely(!full_name)) { goto modbad; } - #if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) - { - PyObject *modules = PyImport_GetModuleDict(); - if (unlikely(!modules)) - goto modbad; - value = PyObject_GetItem(modules, full_name); - } - #else - value = PyImport_GetModule(full_name); - #endif - modbad: - Py_XDECREF(full_name); - Py_XDECREF(module_dot); - Py_XDECREF(module_name); - } - if (unlikely(!value)) { - PyErr_Format(PyExc_ImportError, - #if PY_MAJOR_VERSION < 3 - "cannot import name %.230s", PyString_AS_STRING(name)); - #else - "cannot import name %S", name); - #endif - } - return value; -} - -/* HasAttr */ -#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 -static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { - PyObject *r; - if (unlikely(!__Pyx_PyBaseString_Check(n))) { - PyErr_SetString(PyExc_TypeError, - "hasattr(): attribute name must be string"); - return -1; - } - r = __Pyx_GetAttr(o, n); - if (!r) { - PyErr_Clear(); - return 0; - } else { - Py_DECREF(r); - return 1; - } -} -#endif - -/* IsLittleEndian */ -static CYTHON_INLINE int __Pyx_Is_Little_Endian(void) -{ - union { - uint32_t u32; - uint8_t u8[4]; - } S; - S.u32 = 0x01020304; - return S.u8[0] == 4; -} - -/* BufferFormatCheck */ -static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, - __Pyx_BufFmt_StackElem* stack, - __Pyx_TypeInfo* type) { - stack[0].field = &ctx->root; - stack[0].parent_offset = 0; - ctx->root.type = type; - ctx->root.name = "buffer dtype"; - ctx->root.offset = 0; - ctx->head = stack; - ctx->head->field = &ctx->root; - ctx->fmt_offset = 0; - ctx->head->parent_offset = 0; - ctx->new_packmode = '@'; - ctx->enc_packmode = '@'; - ctx->new_count = 1; - ctx->enc_count = 0; - ctx->enc_type = 0; - ctx->is_complex = 0; - ctx->is_valid_array = 0; - ctx->struct_alignment = 0; - while (type->typegroup == 'S') { - ++ctx->head; - ctx->head->field = type->fields; - ctx->head->parent_offset = 0; - type = type->fields->type; - } -} -static int __Pyx_BufFmt_ParseNumber(const char** ts) { - int count; - const char* t = *ts; - if (*t < '0' || *t > '9') { - return -1; - } else { - count = *t++ - '0'; - while (*t >= '0' && *t <= '9') { - count *= 10; - count += *t++ - '0'; - } - } - *ts = t; - return count; -} -static int __Pyx_BufFmt_ExpectNumber(const char **ts) { - int number = __Pyx_BufFmt_ParseNumber(ts); - if (number == -1) - PyErr_Format(PyExc_ValueError,\ - "Does not understand character buffer dtype format string ('%c')", **ts); - return number; -} -static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { - PyErr_Format(PyExc_ValueError, - "Unexpected format string character: '%c'", ch); -} -static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { - switch (ch) { - case '?': return "'bool'"; - case 'c': return "'char'"; - case 'b': return "'signed char'"; - case 'B': return "'unsigned char'"; - case 'h': return "'short'"; - case 'H': return "'unsigned short'"; - case 'i': return "'int'"; - case 'I': return "'unsigned int'"; - case 'l': return "'long'"; - case 'L': return "'unsigned long'"; - case 'q': return "'long long'"; - case 'Q': return "'unsigned long long'"; - case 'f': return (is_complex ? "'complex float'" : "'float'"); - case 'd': return (is_complex ? "'complex double'" : "'double'"); - case 'g': return (is_complex ? "'complex long double'" : "'long double'"); - case 'T': return "a struct"; - case 'O': return "Python object"; - case 'P': return "a pointer"; - case 's': case 'p': return "a string"; - case 0: return "end"; - default: return "unparsable format string"; - } -} -static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return 2; - case 'i': case 'I': case 'l': case 'L': return 4; - case 'q': case 'Q': return 8; - case 'f': return (is_complex ? 8 : 4); - case 'd': return (is_complex ? 16 : 8); - case 'g': { - PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); - return 0; - } - case 'O': case 'P': return sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(short); - case 'i': case 'I': return sizeof(int); - case 'l': case 'L': return sizeof(long); - #ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(PY_LONG_LONG); - #endif - case 'f': return sizeof(float) * (is_complex ? 2 : 1); - case 'd': return sizeof(double) * (is_complex ? 2 : 1); - case 'g': return sizeof(long double) * (is_complex ? 2 : 1); - case 'O': case 'P': return sizeof(void*); - default: { - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } - } -} -typedef struct { char c; short x; } __Pyx_st_short; -typedef struct { char c; int x; } __Pyx_st_int; -typedef struct { char c; long x; } __Pyx_st_long; -typedef struct { char c; float x; } __Pyx_st_float; -typedef struct { char c; double x; } __Pyx_st_double; -typedef struct { char c; long double x; } __Pyx_st_longdouble; -typedef struct { char c; void *x; } __Pyx_st_void_p; -#ifdef HAVE_LONG_LONG -typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; -#endif -static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, int is_complex) { - CYTHON_UNUSED_VAR(is_complex); - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); - case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); - case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); -#ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); -#endif - case 'f': return sizeof(__Pyx_st_float) - sizeof(float); - case 'd': return sizeof(__Pyx_st_double) - sizeof(double); - case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); - case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -/* These are for computing the padding at the end of the struct to align - on the first member of the struct. This will probably the same as above, - but we don't have any guarantees. - */ -typedef struct { short x; char c; } __Pyx_pad_short; -typedef struct { int x; char c; } __Pyx_pad_int; -typedef struct { long x; char c; } __Pyx_pad_long; -typedef struct { float x; char c; } __Pyx_pad_float; -typedef struct { double x; char c; } __Pyx_pad_double; -typedef struct { long double x; char c; } __Pyx_pad_longdouble; -typedef struct { void *x; char c; } __Pyx_pad_void_p; -#ifdef HAVE_LONG_LONG -typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; -#endif -static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, int is_complex) { - CYTHON_UNUSED_VAR(is_complex); - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); - case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); - case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); -#ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); -#endif - case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); - case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); - case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); - case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { - switch (ch) { - case 'c': - return 'H'; - case 'b': case 'h': case 'i': - case 'l': case 'q': case 's': case 'p': - return 'I'; - case '?': case 'B': case 'H': case 'I': case 'L': case 'Q': - return 'U'; - case 'f': case 'd': case 'g': - return (is_complex ? 'C' : 'R'); - case 'O': - return 'O'; - case 'P': - return 'P'; - default: { - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } - } -} -static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { - if (ctx->head == NULL || ctx->head->field == &ctx->root) { - const char* expected; - const char* quote; - if (ctx->head == NULL) { - expected = "end"; - quote = ""; - } else { - expected = ctx->head->field->type->name; - quote = "'"; - } - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch, expected %s%s%s but got %s", - quote, expected, quote, - __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); - } else { - __Pyx_StructField* field = ctx->head->field; - __Pyx_StructField* parent = (ctx->head - 1)->field; - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", - field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), - parent->type->name, field->name); - } -} -static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { - char group; - size_t size, offset, arraysize = 1; - if (ctx->enc_type == 0) return 0; - if (ctx->head->field->type->arraysize[0]) { - int i, ndim = 0; - if (ctx->enc_type == 's' || ctx->enc_type == 'p') { - ctx->is_valid_array = ctx->head->field->type->ndim == 1; - ndim = 1; - if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { - PyErr_Format(PyExc_ValueError, - "Expected a dimension of size %zu, got %zu", - ctx->head->field->type->arraysize[0], ctx->enc_count); - return -1; - } - } - if (!ctx->is_valid_array) { - PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", - ctx->head->field->type->ndim, ndim); - return -1; - } - for (i = 0; i < ctx->head->field->type->ndim; i++) { - arraysize *= ctx->head->field->type->arraysize[i]; - } - ctx->is_valid_array = 0; - ctx->enc_count = 1; - } - group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); - do { - __Pyx_StructField* field = ctx->head->field; - __Pyx_TypeInfo* type = field->type; - if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { - size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); - } else { - size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); - } - if (ctx->enc_packmode == '@') { - size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); - size_t align_mod_offset; - if (align_at == 0) return -1; - align_mod_offset = ctx->fmt_offset % align_at; - if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; - if (ctx->struct_alignment == 0) - ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, - ctx->is_complex); - } - if (type->size != size || type->typegroup != group) { - if (type->typegroup == 'C' && type->fields != NULL) { - size_t parent_offset = ctx->head->parent_offset + field->offset; - ++ctx->head; - ctx->head->field = type->fields; - ctx->head->parent_offset = parent_offset; - continue; - } - if ((type->typegroup == 'H' || group == 'H') && type->size == size) { - } else { - __Pyx_BufFmt_RaiseExpected(ctx); - return -1; - } - } - offset = ctx->head->parent_offset + field->offset; - if (ctx->fmt_offset != offset) { - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", - (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); - return -1; - } - ctx->fmt_offset += size; - if (arraysize) - ctx->fmt_offset += (arraysize - 1) * size; - --ctx->enc_count; - while (1) { - if (field == &ctx->root) { - ctx->head = NULL; - if (ctx->enc_count != 0) { - __Pyx_BufFmt_RaiseExpected(ctx); - return -1; - } - break; - } - ctx->head->field = ++field; - if (field->type == NULL) { - --ctx->head; - field = ctx->head->field; - continue; - } else if (field->type->typegroup == 'S') { - size_t parent_offset = ctx->head->parent_offset + field->offset; - if (field->type->fields->type == NULL) continue; - field = field->type->fields; - ++ctx->head; - ctx->head->field = field; - ctx->head->parent_offset = parent_offset; - break; - } else { - break; - } - } - } while (ctx->enc_count); - ctx->enc_type = 0; - ctx->is_complex = 0; - return 0; -} -static int -__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) -{ - const char *ts = *tsp; - int i = 0, number, ndim; - ++ts; - if (ctx->new_count != 1) { - PyErr_SetString(PyExc_ValueError, - "Cannot handle repeated arrays in format string"); - return -1; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return -1; - ndim = ctx->head->field->type->ndim; - while (*ts && *ts != ')') { - switch (*ts) { - case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; - default: break; - } - number = __Pyx_BufFmt_ExpectNumber(&ts); - if (number == -1) return -1; - if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) { - PyErr_Format(PyExc_ValueError, - "Expected a dimension of size %zu, got %d", - ctx->head->field->type->arraysize[i], number); - return -1; - } - if (*ts != ',' && *ts != ')') { - PyErr_Format(PyExc_ValueError, - "Expected a comma in format string, got '%c'", *ts); - return -1; - } - if (*ts == ',') ts++; - i++; - } - if (i != ndim) { - PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", - ctx->head->field->type->ndim, i); - return -1; - } - if (!*ts) { - PyErr_SetString(PyExc_ValueError, - "Unexpected end of format string, expected ')'"); - return -1; - } - ctx->is_valid_array = 1; - ctx->new_count = 1; - *tsp = ++ts; - return 0; -} -static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { - int got_Z = 0; - while (1) { - switch(*ts) { - case 0: - if (ctx->enc_type != 0 && ctx->head == NULL) { - __Pyx_BufFmt_RaiseExpected(ctx); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - if (ctx->head != NULL) { - __Pyx_BufFmt_RaiseExpected(ctx); - return NULL; - } - return ts; - case ' ': - case '\r': - case '\n': - ++ts; - break; - case '<': - if (!__Pyx_Is_Little_Endian()) { - PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); - return NULL; - } - ctx->new_packmode = '='; - ++ts; - break; - case '>': - case '!': - if (__Pyx_Is_Little_Endian()) { - PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); - return NULL; - } - ctx->new_packmode = '='; - ++ts; - break; - case '=': - case '@': - case '^': - ctx->new_packmode = *ts++; - break; - case 'T': - { - const char* ts_after_sub; - size_t i, struct_count = ctx->new_count; - size_t struct_alignment = ctx->struct_alignment; - ctx->new_count = 1; - ++ts; - if (*ts != '{') { - PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_type = 0; - ctx->enc_count = 0; - ctx->struct_alignment = 0; - ++ts; - ts_after_sub = ts; - for (i = 0; i != struct_count; ++i) { - ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); - if (!ts_after_sub) return NULL; - } - ts = ts_after_sub; - if (struct_alignment) ctx->struct_alignment = struct_alignment; - } - break; - case '}': - { - size_t alignment = ctx->struct_alignment; - ++ts; - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_type = 0; - if (alignment && ctx->fmt_offset % alignment) { - ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); - } - } - return ts; - case 'x': - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->fmt_offset += ctx->new_count; - ctx->new_count = 1; - ctx->enc_count = 0; - ctx->enc_type = 0; - ctx->enc_packmode = ctx->new_packmode; - ++ts; - break; - case 'Z': - got_Z = 1; - ++ts; - if (*ts != 'f' && *ts != 'd' && *ts != 'g') { - __Pyx_BufFmt_RaiseUnexpectedChar('Z'); - return NULL; - } - CYTHON_FALLTHROUGH; - case '?': case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': - case 'l': case 'L': case 'q': case 'Q': - case 'f': case 'd': case 'g': - case 'O': case 'p': - if ((ctx->enc_type == *ts) && (got_Z == ctx->is_complex) && - (ctx->enc_packmode == ctx->new_packmode) && (!ctx->is_valid_array)) { - ctx->enc_count += ctx->new_count; - ctx->new_count = 1; - got_Z = 0; - ++ts; - break; - } - CYTHON_FALLTHROUGH; - case 's': - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_count = ctx->new_count; - ctx->enc_packmode = ctx->new_packmode; - ctx->enc_type = *ts; - ctx->is_complex = got_Z; - ++ts; - ctx->new_count = 1; - got_Z = 0; - break; - case ':': - ++ts; - while(*ts != ':') ++ts; - ++ts; - break; - case '(': - if (__pyx_buffmt_parse_array(ctx, &ts) < 0) return NULL; - break; - default: - { - int number = __Pyx_BufFmt_ExpectNumber(&ts); - if (number == -1) return NULL; - ctx->new_count = (size_t)number; - } - } - } -} - -/* BufferGetAndValidate */ - static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { - if (unlikely(info->buf == NULL)) return; - if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; - __Pyx_ReleaseBuffer(info); -} -static void __Pyx_ZeroBuffer(Py_buffer* buf) { - buf->buf = NULL; - buf->obj = NULL; - buf->strides = __Pyx_zeros; - buf->shape = __Pyx_zeros; - buf->suboffsets = __Pyx_minusones; -} -static int __Pyx__GetBufferAndValidate( - Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, - int nd, int cast, __Pyx_BufFmt_StackElem* stack) -{ - buf->buf = NULL; - if (unlikely(__Pyx_GetBuffer(obj, buf, flags) == -1)) { - __Pyx_ZeroBuffer(buf); - return -1; - } - if (unlikely(buf->ndim != nd)) { - PyErr_Format(PyExc_ValueError, - "Buffer has wrong number of dimensions (expected %d, got %d)", - nd, buf->ndim); - goto fail; - } - if (!cast) { - __Pyx_BufFmt_Context ctx; - __Pyx_BufFmt_Init(&ctx, stack, dtype); - if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; - } - if (unlikely((size_t)buf->itemsize != dtype->size)) { - PyErr_Format(PyExc_ValueError, - "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", - buf->itemsize, (buf->itemsize > 1) ? "s" : "", - dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); - goto fail; - } - if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; - return 0; -fail:; - __Pyx_SafeReleaseBuffer(buf); - return -1; -} - -/* PyObject_GenericGetAttrNoDict */ - #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { - __Pyx_TypeName type_name = __Pyx_PyType_GetName(tp); - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", - type_name, attr_name); -#else - "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", - type_name, PyString_AS_STRING(attr_name)); -#endif - __Pyx_DECREF_TypeName(type_name); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { - PyObject *descr; - PyTypeObject *tp = Py_TYPE(obj); - if (unlikely(!PyString_Check(attr_name))) { - return PyObject_GenericGetAttr(obj, attr_name); - } - assert(!tp->tp_dictoffset); - descr = _PyType_Lookup(tp, attr_name); - if (unlikely(!descr)) { - return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); - } - Py_INCREF(descr); - #if PY_MAJOR_VERSION < 3 - if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) - #endif - { - descrgetfunc f = Py_TYPE(descr)->tp_descr_get; - if (unlikely(f)) { - PyObject *res = f(descr, obj, (PyObject *)tp); - Py_DECREF(descr); - return res; - } - } - return descr; -} -#endif - -/* PyObject_GenericGetAttr */ - #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { - if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { - return PyObject_GenericGetAttr(obj, attr_name); - } - return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); -} -#endif - -/* FixUpExtensionType */ - #if CYTHON_USE_TYPE_SPECS -static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { -#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API - CYTHON_UNUSED_VAR(spec); - CYTHON_UNUSED_VAR(type); -#else - const PyType_Slot *slot = spec->slots; - while (slot && slot->slot && slot->slot != Py_tp_members) - slot++; - if (slot && slot->slot == Py_tp_members) { - int changed = 0; -#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON) - const -#endif - PyMemberDef *memb = (PyMemberDef*) slot->pfunc; - while (memb && memb->name) { - if (memb->name[0] == '_' && memb->name[1] == '_') { -#if PY_VERSION_HEX < 0x030900b1 - if (strcmp(memb->name, "__weaklistoffset__") == 0) { - assert(memb->type == T_PYSSIZET); - assert(memb->flags == READONLY); - type->tp_weaklistoffset = memb->offset; - changed = 1; - } - else if (strcmp(memb->name, "__dictoffset__") == 0) { - assert(memb->type == T_PYSSIZET); - assert(memb->flags == READONLY); - type->tp_dictoffset = memb->offset; - changed = 1; - } -#if CYTHON_METH_FASTCALL - else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { - assert(memb->type == T_PYSSIZET); - assert(memb->flags == READONLY); -#if PY_VERSION_HEX >= 0x030800b4 - type->tp_vectorcall_offset = memb->offset; -#else - type->tp_print = (printfunc) memb->offset; -#endif - changed = 1; - } -#endif -#else - if ((0)); -#endif -#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON - else if (strcmp(memb->name, "__module__") == 0) { - PyObject *descr; - assert(memb->type == T_OBJECT); - assert(memb->flags == 0 || memb->flags == READONLY); - descr = PyDescr_NewMember(type, memb); - if (unlikely(!descr)) - return -1; - if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) { - Py_DECREF(descr); - return -1; - } - Py_DECREF(descr); - changed = 1; - } -#endif - } - memb++; - } - if (changed) - PyType_Modified(type); - } -#endif - return 0; -} -#endif - -/* PyObjectCallNoArg */ - static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { - PyObject *arg[2] = {NULL, NULL}; - return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); -} - -/* PyObjectGetMethod */ - static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { - PyObject *attr; -#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP - __Pyx_TypeName type_name; - PyTypeObject *tp = Py_TYPE(obj); - PyObject *descr; - descrgetfunc f = NULL; - PyObject **dictptr, *dict; - int meth_found = 0; - assert (*method == NULL); - if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; - } - if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { - return 0; - } - descr = _PyType_Lookup(tp, name); - if (likely(descr != NULL)) { - Py_INCREF(descr); -#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR - if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) -#elif PY_MAJOR_VERSION >= 3 - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type))) - #endif -#else - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr))) - #endif -#endif - { - meth_found = 1; - } else { - f = Py_TYPE(descr)->tp_descr_get; - if (f != NULL && PyDescr_IsData(descr)) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - } - } - dictptr = _PyObject_GetDictPtr(obj); - if (dictptr != NULL && (dict = *dictptr) != NULL) { - Py_INCREF(dict); - attr = __Pyx_PyDict_GetItemStr(dict, name); - if (attr != NULL) { - Py_INCREF(attr); - Py_DECREF(dict); - Py_XDECREF(descr); - goto try_unpack; - } - Py_DECREF(dict); - } - if (meth_found) { - *method = descr; - return 1; - } - if (f != NULL) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - if (likely(descr != NULL)) { - *method = descr; - return 0; - } - type_name = __Pyx_PyType_GetName(tp); - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", - type_name, name); -#else - "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", - type_name, PyString_AS_STRING(name)); -#endif - __Pyx_DECREF_TypeName(type_name); - return 0; -#else - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; -#endif -try_unpack: -#if CYTHON_UNPACK_METHODS - if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { - PyObject *function = PyMethod_GET_FUNCTION(attr); - Py_INCREF(function); - Py_DECREF(attr); - *method = function; - return 1; - } -#endif - *method = attr; - return 0; -} - -/* PyObjectCallMethod0 */ - static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { - PyObject *method = NULL, *result = NULL; - int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); - if (likely(is_method)) { - result = __Pyx_PyObject_CallOneArg(method, obj); - Py_DECREF(method); - return result; - } - if (unlikely(!method)) goto bad; - result = __Pyx_PyObject_CallNoArg(method); - Py_DECREF(method); -bad: - return result; -} - -/* ValidateBasesTuple */ - #if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS -static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) { - Py_ssize_t i, n; -#if CYTHON_ASSUME_SAFE_MACROS - n = PyTuple_GET_SIZE(bases); -#else - n = PyTuple_Size(bases); - if (n < 0) return -1; -#endif - for (i = 1; i < n; i++) - { -#if CYTHON_AVOID_BORROWED_REFS - PyObject *b0 = PySequence_GetItem(bases, i); - if (!b0) return -1; -#elif CYTHON_ASSUME_SAFE_MACROS - PyObject *b0 = PyTuple_GET_ITEM(bases, i); -#else - PyObject *b0 = PyTuple_GetItem(bases, i); - if (!b0) return -1; -#endif - PyTypeObject *b; -#if PY_MAJOR_VERSION < 3 - if (PyClass_Check(b0)) - { - PyErr_Format(PyExc_TypeError, "base class '%.200s' is an old-style class", - PyString_AS_STRING(((PyClassObject*)b0)->cl_name)); -#if CYTHON_AVOID_BORROWED_REFS - Py_DECREF(b0); -#endif - return -1; - } -#endif - b = (PyTypeObject*) b0; - if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE)) - { - __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); - PyErr_Format(PyExc_TypeError, - "base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name); - __Pyx_DECREF_TypeName(b_name); -#if CYTHON_AVOID_BORROWED_REFS - Py_DECREF(b0); -#endif - return -1; - } - if (dictoffset == 0) - { - Py_ssize_t b_dictoffset = 0; -#if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY - b_dictoffset = b->tp_dictoffset; -#else - PyObject *py_b_dictoffset = PyObject_GetAttrString((PyObject*)b, "__dictoffset__"); - if (!py_b_dictoffset) goto dictoffset_return; - b_dictoffset = PyLong_AsSsize_t(py_b_dictoffset); - Py_DECREF(py_b_dictoffset); - if (b_dictoffset == -1 && PyErr_Occurred()) goto dictoffset_return; -#endif - if (b_dictoffset) { - { - __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); - PyErr_Format(PyExc_TypeError, - "extension type '%.200s' has no __dict__ slot, " - "but base type '" __Pyx_FMT_TYPENAME "' has: " - "either add 'cdef dict __dict__' to the extension type " - "or add '__slots__ = [...]' to the base type", - type_name, b_name); - __Pyx_DECREF_TypeName(b_name); - } -#if !(CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY) - dictoffset_return: -#endif -#if CYTHON_AVOID_BORROWED_REFS - Py_DECREF(b0); -#endif - return -1; - } - } -#if CYTHON_AVOID_BORROWED_REFS - Py_DECREF(b0); -#endif - } - return 0; -} -#endif - -/* PyType_Ready */ - static int __Pyx_PyType_Ready(PyTypeObject *t) { -#if CYTHON_USE_TYPE_SPECS || !(CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API) || defined(PYSTON_MAJOR_VERSION) - (void)__Pyx_PyObject_CallMethod0; -#if CYTHON_USE_TYPE_SPECS - (void)__Pyx_validate_bases_tuple; -#endif - return PyType_Ready(t); -#else - int r; - PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*); - if (bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, bases) == -1)) - return -1; -#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) - { - int gc_was_enabled; - #if PY_VERSION_HEX >= 0x030A00b1 - gc_was_enabled = PyGC_Disable(); - (void)__Pyx_PyObject_CallMethod0; - #else - PyObject *ret, *py_status; - PyObject *gc = NULL; - #if PY_VERSION_HEX >= 0x030700a1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM+0 >= 0x07030400) - gc = PyImport_GetModule(__pyx_kp_u_gc); - #endif - if (unlikely(!gc)) gc = PyImport_Import(__pyx_kp_u_gc); - if (unlikely(!gc)) return -1; - py_status = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_isenabled); - if (unlikely(!py_status)) { - Py_DECREF(gc); - return -1; - } - gc_was_enabled = __Pyx_PyObject_IsTrue(py_status); - Py_DECREF(py_status); - if (gc_was_enabled > 0) { - ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_disable); - if (unlikely(!ret)) { - Py_DECREF(gc); - return -1; - } - Py_DECREF(ret); - } else if (unlikely(gc_was_enabled == -1)) { - Py_DECREF(gc); - return -1; - } - #endif - t->tp_flags |= Py_TPFLAGS_HEAPTYPE; -#if PY_VERSION_HEX >= 0x030A0000 - t->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; -#endif -#else - (void)__Pyx_PyObject_CallMethod0; -#endif - r = PyType_Ready(t); -#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) - t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; - #if PY_VERSION_HEX >= 0x030A00b1 - if (gc_was_enabled) - PyGC_Enable(); - #else - if (gc_was_enabled) { - PyObject *tp, *v, *tb; - PyErr_Fetch(&tp, &v, &tb); - ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_enable); - if (likely(ret || r == -1)) { - Py_XDECREF(ret); - PyErr_Restore(tp, v, tb); - } else { - Py_XDECREF(tp); - Py_XDECREF(v); - Py_XDECREF(tb); - r = -1; - } - } - Py_DECREF(gc); - #endif - } -#endif - return r; -#endif -} - -/* SetVTable */ - static int __Pyx_SetVtable(PyTypeObject *type, void *vtable) { - PyObject *ob = PyCapsule_New(vtable, 0, 0); - if (unlikely(!ob)) - goto bad; -#if CYTHON_COMPILING_IN_LIMITED_API - if (unlikely(PyObject_SetAttr((PyObject *) type, __pyx_n_s_pyx_vtable, ob) < 0)) -#else - if (unlikely(PyDict_SetItem(type->tp_dict, __pyx_n_s_pyx_vtable, ob) < 0)) -#endif - goto bad; - Py_DECREF(ob); - return 0; -bad: - Py_XDECREF(ob); - return -1; -} - -/* GetVTable */ - static void* __Pyx_GetVtable(PyTypeObject *type) { - void* ptr; -#if CYTHON_COMPILING_IN_LIMITED_API - PyObject *ob = PyObject_GetAttr((PyObject *)type, __pyx_n_s_pyx_vtable); -#else - PyObject *ob = PyObject_GetItem(type->tp_dict, __pyx_n_s_pyx_vtable); -#endif - if (!ob) - goto bad; - ptr = PyCapsule_GetPointer(ob, 0); - if (!ptr && !PyErr_Occurred()) - PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type"); - Py_DECREF(ob); - return ptr; -bad: - Py_XDECREF(ob); - return NULL; -} - -/* MergeVTables */ - #if !CYTHON_COMPILING_IN_LIMITED_API -static int __Pyx_MergeVtables(PyTypeObject *type) { - int i; - void** base_vtables; - __Pyx_TypeName tp_base_name; - __Pyx_TypeName base_name; - void* unknown = (void*)-1; - PyObject* bases = type->tp_bases; - int base_depth = 0; - { - PyTypeObject* base = type->tp_base; - while (base) { - base_depth += 1; - base = base->tp_base; - } - } - base_vtables = (void**) malloc(sizeof(void*) * (size_t)(base_depth + 1)); - base_vtables[0] = unknown; - for (i = 1; i < PyTuple_GET_SIZE(bases); i++) { - void* base_vtable = __Pyx_GetVtable(((PyTypeObject*)PyTuple_GET_ITEM(bases, i))); - if (base_vtable != NULL) { - int j; - PyTypeObject* base = type->tp_base; - for (j = 0; j < base_depth; j++) { - if (base_vtables[j] == unknown) { - base_vtables[j] = __Pyx_GetVtable(base); - base_vtables[j + 1] = unknown; - } - if (base_vtables[j] == base_vtable) { - break; - } else if (base_vtables[j] == NULL) { - goto bad; - } - base = base->tp_base; - } - } - } - PyErr_Clear(); - free(base_vtables); - return 0; -bad: - tp_base_name = __Pyx_PyType_GetName(type->tp_base); - base_name = __Pyx_PyType_GetName((PyTypeObject*)PyTuple_GET_ITEM(bases, i)); - PyErr_Format(PyExc_TypeError, - "multiple bases have vtable conflict: '" __Pyx_FMT_TYPENAME "' and '" __Pyx_FMT_TYPENAME "'", tp_base_name, base_name); - __Pyx_DECREF_TypeName(tp_base_name); - __Pyx_DECREF_TypeName(base_name); - free(base_vtables); - return -1; -} -#endif - -/* SetupReduce */ - #if !CYTHON_COMPILING_IN_LIMITED_API -static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { - int ret; - PyObject *name_attr; - name_attr = __Pyx_PyObject_GetAttrStrNoError(meth, __pyx_n_s_name_2); - if (likely(name_attr)) { - ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); - } else { - ret = -1; - } - if (unlikely(ret < 0)) { - PyErr_Clear(); - ret = 0; - } - Py_XDECREF(name_attr); - return ret; -} -static int __Pyx_setup_reduce(PyObject* type_obj) { - int ret = 0; - PyObject *object_reduce = NULL; - PyObject *object_getstate = NULL; - PyObject *object_reduce_ex = NULL; - PyObject *reduce = NULL; - PyObject *reduce_ex = NULL; - PyObject *reduce_cython = NULL; - PyObject *setstate = NULL; - PyObject *setstate_cython = NULL; - PyObject *getstate = NULL; -#if CYTHON_USE_PYTYPE_LOOKUP - getstate = _PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate); -#else - getstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_getstate); - if (!getstate && PyErr_Occurred()) { - goto __PYX_BAD; - } -#endif - if (getstate) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_getstate = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_getstate); -#else - object_getstate = __Pyx_PyObject_GetAttrStrNoError((PyObject*)&PyBaseObject_Type, __pyx_n_s_getstate); - if (!object_getstate && PyErr_Occurred()) { - goto __PYX_BAD; - } -#endif - if (object_getstate != getstate) { - goto __PYX_GOOD; - } - } -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#else - object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#endif - reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; - if (reduce_ex == object_reduce_ex) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#else - object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#endif - reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; - if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { - reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); - if (likely(reduce_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (reduce == object_reduce || PyErr_Occurred()) { - goto __PYX_BAD; - } - setstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate); - if (!setstate) PyErr_Clear(); - if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { - setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); - if (likely(setstate_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (!setstate || PyErr_Occurred()) { - goto __PYX_BAD; - } - } - PyType_Modified((PyTypeObject*)type_obj); - } - } - goto __PYX_GOOD; -__PYX_BAD: - if (!PyErr_Occurred()) { - __Pyx_TypeName type_obj_name = - __Pyx_PyType_GetName((PyTypeObject*)type_obj); - PyErr_Format(PyExc_RuntimeError, - "Unable to initialize pickling for " __Pyx_FMT_TYPENAME, type_obj_name); - __Pyx_DECREF_TypeName(type_obj_name); - } - ret = -1; -__PYX_GOOD: -#if !CYTHON_USE_PYTYPE_LOOKUP - Py_XDECREF(object_reduce); - Py_XDECREF(object_reduce_ex); - Py_XDECREF(object_getstate); - Py_XDECREF(getstate); -#endif - Py_XDECREF(reduce); - Py_XDECREF(reduce_ex); - Py_XDECREF(reduce_cython); - Py_XDECREF(setstate); - Py_XDECREF(setstate_cython); - return ret; -} -#endif - -/* TypeImport */ - #ifndef __PYX_HAVE_RT_ImportType_3_0_10 -#define __PYX_HAVE_RT_ImportType_3_0_10 -static PyTypeObject *__Pyx_ImportType_3_0_10(PyObject *module, const char *module_name, const char *class_name, - size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_3_0_10 check_size) -{ - PyObject *result = 0; - char warning[200]; - Py_ssize_t basicsize; - Py_ssize_t itemsize; -#if CYTHON_COMPILING_IN_LIMITED_API - PyObject *py_basicsize; - PyObject *py_itemsize; -#endif - result = PyObject_GetAttrString(module, class_name); - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#if !CYTHON_COMPILING_IN_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; - itemsize = ((PyTypeObject *)result)->tp_itemsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; - py_itemsize = PyObject_GetAttrString(result, "__itemsize__"); - if (!py_itemsize) - goto bad; - itemsize = PyLong_AsSsize_t(py_itemsize); - Py_DECREF(py_itemsize); - py_itemsize = 0; - if (itemsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if (itemsize) { - if (size % alignment) { - alignment = size % alignment; - } - if (itemsize < (Py_ssize_t)alignment) - itemsize = (Py_ssize_t)alignment; - } - if ((size_t)(basicsize + itemsize) < size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize+itemsize); - goto bad; - } - if (check_size == __Pyx_ImportType_CheckSize_Error_3_0_10 && - ((size_t)basicsize > size || (size_t)(basicsize + itemsize) < size)) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd-%zd from PyObject", - module_name, class_name, size, basicsize, basicsize+itemsize); - goto bad; - } - else if (check_size == __Pyx_ImportType_CheckSize_Warn_3_0_10 && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(result); - return NULL; -} -#endif - -/* FetchSharedCythonModule */ - static PyObject *__Pyx_FetchSharedCythonABIModule(void) { - return __Pyx_PyImport_AddModuleRef((char*) __PYX_ABI_MODULE_NAME); -} - -/* FetchCommonType */ - static int __Pyx_VerifyCachedType(PyObject *cached_type, - const char *name, - Py_ssize_t basicsize, - Py_ssize_t expected_basicsize) { - if (!PyType_Check(cached_type)) { - PyErr_Format(PyExc_TypeError, - "Shared Cython type %.200s is not a type object", name); - return -1; - } - if (basicsize != expected_basicsize) { - PyErr_Format(PyExc_TypeError, - "Shared Cython type %.200s has the wrong size, try recompiling", - name); - return -1; - } - return 0; -} -#if !CYTHON_USE_TYPE_SPECS -static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { - PyObject* abi_module; - const char* object_name; - PyTypeObject *cached_type = NULL; - abi_module = __Pyx_FetchSharedCythonABIModule(); - if (!abi_module) return NULL; - object_name = strrchr(type->tp_name, '.'); - object_name = object_name ? object_name+1 : type->tp_name; - cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name); - if (cached_type) { - if (__Pyx_VerifyCachedType( - (PyObject *)cached_type, - object_name, - cached_type->tp_basicsize, - type->tp_basicsize) < 0) { - goto bad; - } - goto done; - } - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; - PyErr_Clear(); - if (PyType_Ready(type) < 0) goto bad; - if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0) - goto bad; - Py_INCREF(type); - cached_type = type; -done: - Py_DECREF(abi_module); - return cached_type; -bad: - Py_XDECREF(cached_type); - cached_type = NULL; - goto done; -} -#else -static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) { - PyObject *abi_module, *cached_type = NULL; - const char* object_name = strrchr(spec->name, '.'); - object_name = object_name ? object_name+1 : spec->name; - abi_module = __Pyx_FetchSharedCythonABIModule(); - if (!abi_module) return NULL; - cached_type = PyObject_GetAttrString(abi_module, object_name); - if (cached_type) { - Py_ssize_t basicsize; -#if CYTHON_COMPILING_IN_LIMITED_API - PyObject *py_basicsize; - py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); - if (unlikely(!py_basicsize)) goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; -#else - basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1; -#endif - if (__Pyx_VerifyCachedType( - cached_type, - object_name, - basicsize, - spec->basicsize) < 0) { - goto bad; - } - goto done; - } - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; - PyErr_Clear(); - CYTHON_UNUSED_VAR(module); - cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases); - if (unlikely(!cached_type)) goto bad; - if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; - if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad; -done: - Py_DECREF(abi_module); - assert(cached_type == NULL || PyType_Check(cached_type)); - return (PyTypeObject *) cached_type; -bad: - Py_XDECREF(cached_type); - cached_type = NULL; - goto done; -} -#endif - -/* PyVectorcallFastCallDict */ - #if CYTHON_METH_FASTCALL -static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) -{ - PyObject *res = NULL; - PyObject *kwnames; - PyObject **newargs; - PyObject **kwvalues; - Py_ssize_t i, pos; - size_t j; - PyObject *key, *value; - unsigned long keys_are_strings; - Py_ssize_t nkw = PyDict_GET_SIZE(kw); - newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); - if (unlikely(newargs == NULL)) { - PyErr_NoMemory(); - return NULL; - } - for (j = 0; j < nargs; j++) newargs[j] = args[j]; - kwnames = PyTuple_New(nkw); - if (unlikely(kwnames == NULL)) { - PyMem_Free(newargs); - return NULL; - } - kwvalues = newargs + nargs; - pos = i = 0; - keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; - while (PyDict_Next(kw, &pos, &key, &value)) { - keys_are_strings &= Py_TYPE(key)->tp_flags; - Py_INCREF(key); - Py_INCREF(value); - PyTuple_SET_ITEM(kwnames, i, key); - kwvalues[i] = value; - i++; - } - if (unlikely(!keys_are_strings)) { - PyErr_SetString(PyExc_TypeError, "keywords must be strings"); - goto cleanup; - } - res = vc(func, newargs, nargs, kwnames); -cleanup: - Py_DECREF(kwnames); - for (i = 0; i < nkw; i++) - Py_DECREF(kwvalues[i]); - PyMem_Free(newargs); - return res; -} -static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) -{ - if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) { - return vc(func, args, nargs, NULL); - } - return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); -} -#endif - -/* CythonFunctionShared */ - #if CYTHON_COMPILING_IN_LIMITED_API -static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { - if (__Pyx_CyFunction_Check(func)) { - return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; - } else if (PyCFunction_Check(func)) { - return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; - } - return 0; -} -#else -static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { - return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; -} -#endif -static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { -#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API - __Pyx_Py_XDECREF_SET( - __Pyx_CyFunction_GetClassObj(f), - ((classobj) ? __Pyx_NewRef(classobj) : NULL)); -#else - __Pyx_Py_XDECREF_SET( - ((PyCMethodObject *) (f))->mm_class, - (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); -#endif -} -static PyObject * -__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) -{ - CYTHON_UNUSED_VAR(closure); - if (unlikely(op->func_doc == NULL)) { -#if CYTHON_COMPILING_IN_LIMITED_API - op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); - if (unlikely(!op->func_doc)) return NULL; -#else - if (((PyCFunctionObject*)op)->m_ml->ml_doc) { -#if PY_MAJOR_VERSION >= 3 - op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); -#else - op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); -#endif - if (unlikely(op->func_doc == NULL)) - return NULL; - } else { - Py_INCREF(Py_None); - return Py_None; - } -#endif - } - Py_INCREF(op->func_doc); - return op->func_doc; -} -static int -__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) -{ - CYTHON_UNUSED_VAR(context); - if (value == NULL) { - value = Py_None; - } - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->func_doc, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) -{ - CYTHON_UNUSED_VAR(context); - if (unlikely(op->func_name == NULL)) { -#if CYTHON_COMPILING_IN_LIMITED_API - op->func_name = PyObject_GetAttrString(op->func, "__name__"); -#elif PY_MAJOR_VERSION >= 3 - op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); -#else - op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); -#endif - if (unlikely(op->func_name == NULL)) - return NULL; - } - Py_INCREF(op->func_name); - return op->func_name; -} -static int -__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) -{ - CYTHON_UNUSED_VAR(context); -#if PY_MAJOR_VERSION >= 3 - if (unlikely(value == NULL || !PyUnicode_Check(value))) -#else - if (unlikely(value == NULL || !PyString_Check(value))) -#endif - { - PyErr_SetString(PyExc_TypeError, - "__name__ must be set to a string object"); - return -1; - } - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->func_name, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) -{ - CYTHON_UNUSED_VAR(context); - Py_INCREF(op->func_qualname); - return op->func_qualname; -} -static int -__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) -{ - CYTHON_UNUSED_VAR(context); -#if PY_MAJOR_VERSION >= 3 - if (unlikely(value == NULL || !PyUnicode_Check(value))) -#else - if (unlikely(value == NULL || !PyString_Check(value))) -#endif - { - PyErr_SetString(PyExc_TypeError, - "__qualname__ must be set to a string object"); - return -1; - } - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->func_qualname, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) -{ - CYTHON_UNUSED_VAR(context); - if (unlikely(op->func_dict == NULL)) { - op->func_dict = PyDict_New(); - if (unlikely(op->func_dict == NULL)) - return NULL; - } - Py_INCREF(op->func_dict); - return op->func_dict; -} -static int -__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, void *context) -{ - CYTHON_UNUSED_VAR(context); - if (unlikely(value == NULL)) { - PyErr_SetString(PyExc_TypeError, - "function's dictionary may not be deleted"); - return -1; - } - if (unlikely(!PyDict_Check(value))) { - PyErr_SetString(PyExc_TypeError, - "setting function's dictionary to a non-dict"); - return -1; - } - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->func_dict, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) -{ - CYTHON_UNUSED_VAR(context); - Py_INCREF(op->func_globals); - return op->func_globals; -} -static PyObject * -__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) -{ - CYTHON_UNUSED_VAR(op); - CYTHON_UNUSED_VAR(context); - Py_INCREF(Py_None); - return Py_None; -} -static PyObject * -__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) -{ - PyObject* result = (op->func_code) ? op->func_code : Py_None; - CYTHON_UNUSED_VAR(context); - Py_INCREF(result); - return result; -} -static int -__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { - int result = 0; - PyObject *res = op->defaults_getter((PyObject *) op); - if (unlikely(!res)) - return -1; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - op->defaults_tuple = PyTuple_GET_ITEM(res, 0); - Py_INCREF(op->defaults_tuple); - op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); - Py_INCREF(op->defaults_kwdict); - #else - op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); - if (unlikely(!op->defaults_tuple)) result = -1; - else { - op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); - if (unlikely(!op->defaults_kwdict)) result = -1; - } - #endif - Py_DECREF(res); - return result; -} -static int -__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { - CYTHON_UNUSED_VAR(context); - if (!value) { - value = Py_None; - } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { - PyErr_SetString(PyExc_TypeError, - "__defaults__ must be set to a tuple object"); - return -1; - } - PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " - "currently affect the values used in function calls", 1); - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { - PyObject* result = op->defaults_tuple; - CYTHON_UNUSED_VAR(context); - if (unlikely(!result)) { - if (op->defaults_getter) { - if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; - result = op->defaults_tuple; - } else { - result = Py_None; - } - } - Py_INCREF(result); - return result; -} -static int -__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { - CYTHON_UNUSED_VAR(context); - if (!value) { - value = Py_None; - } else if (unlikely(value != Py_None && !PyDict_Check(value))) { - PyErr_SetString(PyExc_TypeError, - "__kwdefaults__ must be set to a dict object"); - return -1; - } - PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " - "currently affect the values used in function calls", 1); - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { - PyObject* result = op->defaults_kwdict; - CYTHON_UNUSED_VAR(context); - if (unlikely(!result)) { - if (op->defaults_getter) { - if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; - result = op->defaults_kwdict; - } else { - result = Py_None; - } - } - Py_INCREF(result); - return result; -} -static int -__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { - CYTHON_UNUSED_VAR(context); - if (!value || value == Py_None) { - value = NULL; - } else if (unlikely(!PyDict_Check(value))) { - PyErr_SetString(PyExc_TypeError, - "__annotations__ must be set to a dict object"); - return -1; - } - Py_XINCREF(value); - __Pyx_Py_XDECREF_SET(op->func_annotations, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { - PyObject* result = op->func_annotations; - CYTHON_UNUSED_VAR(context); - if (unlikely(!result)) { - result = PyDict_New(); - if (unlikely(!result)) return NULL; - op->func_annotations = result; - } - Py_INCREF(result); - return result; -} -static PyObject * -__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { - int is_coroutine; - CYTHON_UNUSED_VAR(context); - if (op->func_is_coroutine) { - return __Pyx_NewRef(op->func_is_coroutine); - } - is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; -#if PY_VERSION_HEX >= 0x03050000 - if (is_coroutine) { - PyObject *module, *fromlist, *marker = __pyx_n_s_is_coroutine; - fromlist = PyList_New(1); - if (unlikely(!fromlist)) return NULL; - Py_INCREF(marker); -#if CYTHON_ASSUME_SAFE_MACROS - PyList_SET_ITEM(fromlist, 0, marker); -#else - if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { - Py_DECREF(marker); - Py_DECREF(fromlist); - return NULL; - } -#endif - module = PyImport_ImportModuleLevelObject(__pyx_n_s_asyncio_coroutines, NULL, NULL, fromlist, 0); - Py_DECREF(fromlist); - if (unlikely(!module)) goto ignore; - op->func_is_coroutine = __Pyx_PyObject_GetAttrStr(module, marker); - Py_DECREF(module); - if (likely(op->func_is_coroutine)) { - return __Pyx_NewRef(op->func_is_coroutine); - } -ignore: - PyErr_Clear(); - } -#endif - op->func_is_coroutine = __Pyx_PyBool_FromLong(is_coroutine); - return __Pyx_NewRef(op->func_is_coroutine); -} -#if CYTHON_COMPILING_IN_LIMITED_API -static PyObject * -__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { - CYTHON_UNUSED_VAR(context); - return PyObject_GetAttrString(op->func, "__module__"); -} -static int -__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { - CYTHON_UNUSED_VAR(context); - return PyObject_SetAttrString(op->func, "__module__", value); -} -#endif -static PyGetSetDef __pyx_CyFunction_getsets[] = { - {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, - {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, - {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, - {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, - {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, - {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, - {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, - {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, - {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, - {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, - {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, - {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, - {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, - {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, - {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, - {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, - {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, - {(char *) "_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, -#if CYTHON_COMPILING_IN_LIMITED_API - {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, -#endif - {0, 0, 0, 0, 0} -}; -static PyMemberDef __pyx_CyFunction_members[] = { -#if !CYTHON_COMPILING_IN_LIMITED_API - {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, -#endif -#if CYTHON_USE_TYPE_SPECS - {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, -#if CYTHON_METH_FASTCALL -#if CYTHON_BACKPORT_VECTORCALL - {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, -#else -#if !CYTHON_COMPILING_IN_LIMITED_API - {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, -#endif -#endif -#endif -#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API - {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, -#else - {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, -#endif -#endif - {0, 0, 0, 0, 0} -}; -static PyObject * -__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) -{ - CYTHON_UNUSED_VAR(args); -#if PY_MAJOR_VERSION >= 3 - Py_INCREF(m->func_qualname); - return m->func_qualname; -#else - return PyString_FromString(((PyCFunctionObject*)m)->m_ml->ml_name); -#endif -} -static PyMethodDef __pyx_CyFunction_methods[] = { - {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, - {0, 0, 0, 0} -}; -#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API -#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) -#else -#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) -#endif -static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, - PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { -#if !CYTHON_COMPILING_IN_LIMITED_API - PyCFunctionObject *cf = (PyCFunctionObject*) op; -#endif - if (unlikely(op == NULL)) - return NULL; -#if CYTHON_COMPILING_IN_LIMITED_API - op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); - if (unlikely(!op->func)) return NULL; -#endif - op->flags = flags; - __Pyx_CyFunction_weakreflist(op) = NULL; -#if !CYTHON_COMPILING_IN_LIMITED_API - cf->m_ml = ml; - cf->m_self = (PyObject *) op; -#endif - Py_XINCREF(closure); - op->func_closure = closure; -#if !CYTHON_COMPILING_IN_LIMITED_API - Py_XINCREF(module); - cf->m_module = module; -#endif - op->func_dict = NULL; - op->func_name = NULL; - Py_INCREF(qualname); - op->func_qualname = qualname; - op->func_doc = NULL; -#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API - op->func_classobj = NULL; -#else - ((PyCMethodObject*)op)->mm_class = NULL; -#endif - op->func_globals = globals; - Py_INCREF(op->func_globals); - Py_XINCREF(code); - op->func_code = code; - op->defaults_pyobjects = 0; - op->defaults_size = 0; - op->defaults = NULL; - op->defaults_tuple = NULL; - op->defaults_kwdict = NULL; - op->defaults_getter = NULL; - op->func_annotations = NULL; - op->func_is_coroutine = NULL; -#if CYTHON_METH_FASTCALL - switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { - case METH_NOARGS: - __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; - break; - case METH_O: - __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; - break; - case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: - __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; - break; - case METH_FASTCALL | METH_KEYWORDS: - __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; - break; - case METH_VARARGS | METH_KEYWORDS: - __Pyx_CyFunction_func_vectorcall(op) = NULL; - break; - default: - PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); - Py_DECREF(op); - return NULL; - } -#endif - return (PyObject *) op; -} -static int -__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) -{ - Py_CLEAR(m->func_closure); -#if CYTHON_COMPILING_IN_LIMITED_API - Py_CLEAR(m->func); -#else - Py_CLEAR(((PyCFunctionObject*)m)->m_module); -#endif - Py_CLEAR(m->func_dict); - Py_CLEAR(m->func_name); - Py_CLEAR(m->func_qualname); - Py_CLEAR(m->func_doc); - Py_CLEAR(m->func_globals); - Py_CLEAR(m->func_code); -#if !CYTHON_COMPILING_IN_LIMITED_API -#if PY_VERSION_HEX < 0x030900B1 - Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); -#else - { - PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; - ((PyCMethodObject *) (m))->mm_class = NULL; - Py_XDECREF(cls); - } -#endif -#endif - Py_CLEAR(m->defaults_tuple); - Py_CLEAR(m->defaults_kwdict); - Py_CLEAR(m->func_annotations); - Py_CLEAR(m->func_is_coroutine); - if (m->defaults) { - PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); - int i; - for (i = 0; i < m->defaults_pyobjects; i++) - Py_XDECREF(pydefaults[i]); - PyObject_Free(m->defaults); - m->defaults = NULL; - } - return 0; -} -static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) -{ - if (__Pyx_CyFunction_weakreflist(m) != NULL) - PyObject_ClearWeakRefs((PyObject *) m); - __Pyx_CyFunction_clear(m); - __Pyx_PyHeapTypeObject_GC_Del(m); -} -static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) -{ - PyObject_GC_UnTrack(m); - __Pyx__CyFunction_dealloc(m); -} -static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) -{ - Py_VISIT(m->func_closure); -#if CYTHON_COMPILING_IN_LIMITED_API - Py_VISIT(m->func); -#else - Py_VISIT(((PyCFunctionObject*)m)->m_module); -#endif - Py_VISIT(m->func_dict); - Py_VISIT(m->func_name); - Py_VISIT(m->func_qualname); - Py_VISIT(m->func_doc); - Py_VISIT(m->func_globals); - Py_VISIT(m->func_code); -#if !CYTHON_COMPILING_IN_LIMITED_API - Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); -#endif - Py_VISIT(m->defaults_tuple); - Py_VISIT(m->defaults_kwdict); - Py_VISIT(m->func_is_coroutine); - if (m->defaults) { - PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); - int i; - for (i = 0; i < m->defaults_pyobjects; i++) - Py_VISIT(pydefaults[i]); - } - return 0; -} -static PyObject* -__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) -{ -#if PY_MAJOR_VERSION >= 3 - return PyUnicode_FromFormat("", - op->func_qualname, (void *)op); -#else - return PyString_FromFormat("", - PyString_AsString(op->func_qualname), (void *)op); -#endif -} -static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { -#if CYTHON_COMPILING_IN_LIMITED_API - PyObject *f = ((__pyx_CyFunctionObject*)func)->func; - PyObject *py_name = NULL; - PyCFunction meth; - int flags; - meth = PyCFunction_GetFunction(f); - if (unlikely(!meth)) return NULL; - flags = PyCFunction_GetFlags(f); - if (unlikely(flags < 0)) return NULL; -#else - PyCFunctionObject* f = (PyCFunctionObject*)func; - PyCFunction meth = f->m_ml->ml_meth; - int flags = f->m_ml->ml_flags; -#endif - Py_ssize_t size; - switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { - case METH_VARARGS: - if (likely(kw == NULL || PyDict_Size(kw) == 0)) - return (*meth)(self, arg); - break; - case METH_VARARGS | METH_KEYWORDS: - return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); - case METH_NOARGS: - if (likely(kw == NULL || PyDict_Size(kw) == 0)) { -#if CYTHON_ASSUME_SAFE_MACROS - size = PyTuple_GET_SIZE(arg); -#else - size = PyTuple_Size(arg); - if (unlikely(size < 0)) return NULL; -#endif - if (likely(size == 0)) - return (*meth)(self, NULL); -#if CYTHON_COMPILING_IN_LIMITED_API - py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); - if (!py_name) return NULL; - PyErr_Format(PyExc_TypeError, - "%.200S() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", - py_name, size); - Py_DECREF(py_name); -#else - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", - f->m_ml->ml_name, size); -#endif - return NULL; - } - break; - case METH_O: - if (likely(kw == NULL || PyDict_Size(kw) == 0)) { -#if CYTHON_ASSUME_SAFE_MACROS - size = PyTuple_GET_SIZE(arg); -#else - size = PyTuple_Size(arg); - if (unlikely(size < 0)) return NULL; -#endif - if (likely(size == 1)) { - PyObject *result, *arg0; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - arg0 = PyTuple_GET_ITEM(arg, 0); - #else - arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; - #endif - result = (*meth)(self, arg0); - #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) - Py_DECREF(arg0); - #endif - return result; - } -#if CYTHON_COMPILING_IN_LIMITED_API - py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); - if (!py_name) return NULL; - PyErr_Format(PyExc_TypeError, - "%.200S() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", - py_name, size); - Py_DECREF(py_name); -#else - PyErr_Format(PyExc_TypeError, - "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", - f->m_ml->ml_name, size); -#endif - return NULL; - } - break; - default: - PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); - return NULL; - } -#if CYTHON_COMPILING_IN_LIMITED_API - py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); - if (!py_name) return NULL; - PyErr_Format(PyExc_TypeError, "%.200S() takes no keyword arguments", - py_name); - Py_DECREF(py_name); -#else - PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", - f->m_ml->ml_name); -#endif - return NULL; -} -static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *self, *result; -#if CYTHON_COMPILING_IN_LIMITED_API - self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); - if (unlikely(!self) && PyErr_Occurred()) return NULL; -#else - self = ((PyCFunctionObject*)func)->m_self; -#endif - result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); - return result; -} -static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { - PyObject *result; - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; -#if CYTHON_METH_FASTCALL - __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); - if (vc) { -#if CYTHON_ASSUME_SAFE_MACROS - return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); -#else - (void) &__Pyx_PyVectorcall_FastCallDict; - return PyVectorcall_Call(func, args, kw); -#endif - } -#endif - if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { - Py_ssize_t argc; - PyObject *new_args; - PyObject *self; -#if CYTHON_ASSUME_SAFE_MACROS - argc = PyTuple_GET_SIZE(args); -#else - argc = PyTuple_Size(args); - if (unlikely(!argc) < 0) return NULL; -#endif - new_args = PyTuple_GetSlice(args, 1, argc); - if (unlikely(!new_args)) - return NULL; - self = PyTuple_GetItem(args, 0); - if (unlikely(!self)) { - Py_DECREF(new_args); -#if PY_MAJOR_VERSION > 2 - PyErr_Format(PyExc_TypeError, - "unbound method %.200S() needs an argument", - cyfunc->func_qualname); -#else - PyErr_SetString(PyExc_TypeError, - "unbound method needs an argument"); -#endif - return NULL; - } - result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); - Py_DECREF(new_args); - } else { - result = __Pyx_CyFunction_Call(func, args, kw); - } - return result; -} -#if CYTHON_METH_FASTCALL -static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) -{ - int ret = 0; - if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { - if (unlikely(nargs < 1)) { - PyErr_Format(PyExc_TypeError, "%.200s() needs an argument", - ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); - return -1; - } - ret = 1; - } - if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); - return -1; - } - return ret; -} -static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; - PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; -#if CYTHON_BACKPORT_VECTORCALL - Py_ssize_t nargs = (Py_ssize_t)nargsf; -#else - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); -#endif - PyObject *self; - switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { - case 1: - self = args[0]; - args += 1; - nargs -= 1; - break; - case 0: - self = ((PyCFunctionObject*)cyfunc)->m_self; - break; - default: - return NULL; - } - if (unlikely(nargs != 0)) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", - def->ml_name, nargs); - return NULL; - } - return def->ml_meth(self, NULL); -} -static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; - PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; -#if CYTHON_BACKPORT_VECTORCALL - Py_ssize_t nargs = (Py_ssize_t)nargsf; -#else - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); -#endif - PyObject *self; - switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { - case 1: - self = args[0]; - args += 1; - nargs -= 1; - break; - case 0: - self = ((PyCFunctionObject*)cyfunc)->m_self; - break; - default: - return NULL; - } - if (unlikely(nargs != 1)) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", - def->ml_name, nargs); - return NULL; - } - return def->ml_meth(self, args[0]); -} -static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; - PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; -#if CYTHON_BACKPORT_VECTORCALL - Py_ssize_t nargs = (Py_ssize_t)nargsf; -#else - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); -#endif - PyObject *self; - switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { - case 1: - self = args[0]; - args += 1; - nargs -= 1; - break; - case 0: - self = ((PyCFunctionObject*)cyfunc)->m_self; - break; - default: - return NULL; - } - return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames); -} -static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; - PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; - PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); -#if CYTHON_BACKPORT_VECTORCALL - Py_ssize_t nargs = (Py_ssize_t)nargsf; -#else - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); -#endif - PyObject *self; - switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { - case 1: - self = args[0]; - args += 1; - nargs -= 1; - break; - case 0: - self = ((PyCFunctionObject*)cyfunc)->m_self; - break; - default: - return NULL; - } - return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, (size_t)nargs, kwnames); -} -#endif -#if CYTHON_USE_TYPE_SPECS -static PyType_Slot __pyx_CyFunctionType_slots[] = { - {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, - {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, - {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, - {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, - {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, - {Py_tp_methods, (void *)__pyx_CyFunction_methods}, - {Py_tp_members, (void *)__pyx_CyFunction_members}, - {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, - {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, - {0, 0}, -}; -static PyType_Spec __pyx_CyFunctionType_spec = { - __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", - sizeof(__pyx_CyFunctionObject), - 0, -#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR - Py_TPFLAGS_METHOD_DESCRIPTOR | -#endif -#if (defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL) - _Py_TPFLAGS_HAVE_VECTORCALL | -#endif - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - __pyx_CyFunctionType_slots -}; -#else -static PyTypeObject __pyx_CyFunctionType_type = { - PyVarObject_HEAD_INIT(0, 0) - __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", - sizeof(__pyx_CyFunctionObject), - 0, - (destructor) __Pyx_CyFunction_dealloc, -#if !CYTHON_METH_FASTCALL - 0, -#elif CYTHON_BACKPORT_VECTORCALL - (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), -#else - offsetof(PyCFunctionObject, vectorcall), -#endif - 0, - 0, -#if PY_MAJOR_VERSION < 3 - 0, -#else - 0, -#endif - (reprfunc) __Pyx_CyFunction_repr, - 0, - 0, - 0, - 0, - __Pyx_CyFunction_CallAsMethod, - 0, - 0, - 0, - 0, -#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR - Py_TPFLAGS_METHOD_DESCRIPTOR | -#endif -#if defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL - _Py_TPFLAGS_HAVE_VECTORCALL | -#endif - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - 0, - (traverseproc) __Pyx_CyFunction_traverse, - (inquiry) __Pyx_CyFunction_clear, - 0, -#if PY_VERSION_HEX < 0x030500A0 - offsetof(__pyx_CyFunctionObject, func_weakreflist), -#else - offsetof(PyCFunctionObject, m_weakreflist), -#endif - 0, - 0, - __pyx_CyFunction_methods, - __pyx_CyFunction_members, - __pyx_CyFunction_getsets, - 0, - 0, - __Pyx_PyMethod_New, - 0, - offsetof(__pyx_CyFunctionObject, func_dict), - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -#if PY_VERSION_HEX >= 0x030400a1 - 0, -#endif -#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, -#endif -#if __PYX_NEED_TP_PRINT_SLOT - 0, -#endif -#if PY_VERSION_HEX >= 0x030C0000 - 0, -#endif -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 - 0, -#endif -}; -#endif -static int __pyx_CyFunction_init(PyObject *module) { -#if CYTHON_USE_TYPE_SPECS - __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL); -#else - CYTHON_UNUSED_VAR(module); - __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); -#endif - if (unlikely(__pyx_CyFunctionType == NULL)) { - return -1; - } - return 0; -} -static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->defaults = PyObject_Malloc(size); - if (unlikely(!m->defaults)) - return PyErr_NoMemory(); - memset(m->defaults, 0, size); - m->defaults_pyobjects = pyobjects; - m->defaults_size = size; - return m->defaults; -} -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->defaults_tuple = tuple; - Py_INCREF(tuple); -} -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->defaults_kwdict = dict; - Py_INCREF(dict); -} -static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->func_annotations = dict; - Py_INCREF(dict); -} - -/* CythonFunction */ - static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, - PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { - PyObject *op = __Pyx_CyFunction_Init( - PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), - ml, flags, qualname, closure, module, globals, code - ); - if (likely(op)) { - PyObject_GC_Track(op); - } - return op; -} - -/* CLineInTraceback */ - #ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - CYTHON_MAYBE_UNUSED_VAR(tstate); - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - (void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ - #if !CYTHON_COMPILING_IN_LIMITED_API -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} -#endif - -/* AddTraceback */ - #include "compile.h" -#include "frameobject.h" -#include "traceback.h" -#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API - #ifndef Py_BUILD_CORE - #define Py_BUILD_CORE 1 - #endif - #include "internal/pycore_frame.h" -#endif -#if CYTHON_COMPILING_IN_LIMITED_API -static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, - PyObject *firstlineno, PyObject *name) { - PyObject *replace = NULL; - if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; - if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; - replace = PyObject_GetAttrString(code, "replace"); - if (likely(replace)) { - PyObject *result; - result = PyObject_Call(replace, __pyx_empty_tuple, scratch_dict); - Py_DECREF(replace); - return result; - } - PyErr_Clear(); - #if __PYX_LIMITED_VERSION_HEX < 0x030780000 - { - PyObject *compiled = NULL, *result = NULL; - if (unlikely(PyDict_SetItemString(scratch_dict, "code", code))) return NULL; - if (unlikely(PyDict_SetItemString(scratch_dict, "type", (PyObject*)(&PyType_Type)))) return NULL; - compiled = Py_CompileString( - "out = type(code)(\n" - " code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize,\n" - " code.co_flags, code.co_code, code.co_consts, code.co_names,\n" - " code.co_varnames, code.co_filename, co_name, co_firstlineno,\n" - " code.co_lnotab)\n", "", Py_file_input); - if (!compiled) return NULL; - result = PyEval_EvalCode(compiled, scratch_dict, scratch_dict); - Py_DECREF(compiled); - if (!result) PyErr_Print(); - Py_DECREF(result); - result = PyDict_GetItemString(scratch_dict, "out"); - if (result) Py_INCREF(result); - return result; - } - #else - return NULL; - #endif -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; - PyObject *replace = NULL, *getframe = NULL, *frame = NULL; - PyObject *exc_type, *exc_value, *exc_traceback; - int success = 0; - if (c_line) { - (void) __pyx_cfilenm; - (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); - } - PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); - code_object = Py_CompileString("_getframe()", filename, Py_eval_input); - if (unlikely(!code_object)) goto bad; - py_py_line = PyLong_FromLong(py_line); - if (unlikely(!py_py_line)) goto bad; - py_funcname = PyUnicode_FromString(funcname); - if (unlikely(!py_funcname)) goto bad; - dict = PyDict_New(); - if (unlikely(!dict)) goto bad; - { - PyObject *old_code_object = code_object; - code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); - Py_DECREF(old_code_object); - } - if (unlikely(!code_object)) goto bad; - getframe = PySys_GetObject("_getframe"); - if (unlikely(!getframe)) goto bad; - if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; - frame = PyEval_EvalCode(code_object, dict, dict); - if (unlikely(!frame) || frame == Py_None) goto bad; - success = 1; - bad: - PyErr_Restore(exc_type, exc_value, exc_traceback); - Py_XDECREF(code_object); - Py_XDECREF(py_py_line); - Py_XDECREF(py_funcname); - Py_XDECREF(dict); - Py_XDECREF(replace); - if (success) { - PyTraceBack_Here( - (struct _frame*)frame); - } - Py_XDECREF(frame); -} -#else -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = NULL; - PyObject *py_funcname = NULL; - #if PY_MAJOR_VERSION < 3 - PyObject *py_srcfile = NULL; - py_srcfile = PyString_FromString(filename); - if (!py_srcfile) goto bad; - #endif - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - if (!py_funcname) goto bad; - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - if (!py_funcname) goto bad; - funcname = PyUnicode_AsUTF8(py_funcname); - if (!funcname) goto bad; - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - if (!py_funcname) goto bad; - #endif - } - #if PY_MAJOR_VERSION < 3 - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - #else - py_code = PyCode_NewEmpty(filename, funcname, py_line); - #endif - Py_XDECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_funcname); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_srcfile); - #endif - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject *ptype, *pvalue, *ptraceback; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) { - /* If the code object creation fails, then we should clear the - fetched exception references and propagate the new exception */ - Py_XDECREF(ptype); - Py_XDECREF(pvalue); - Py_XDECREF(ptraceback); - goto bad; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} -#endif - -#if PY_MAJOR_VERSION < 3 -static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { - __Pyx_TypeName obj_type_name; - if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); - if (__Pyx_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags); - if (__Pyx_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags); - obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); - PyErr_Format(PyExc_TypeError, - "'" __Pyx_FMT_TYPENAME "' does not have the buffer interface", - obj_type_name); - __Pyx_DECREF_TypeName(obj_type_name); - return -1; -} -static void __Pyx_ReleaseBuffer(Py_buffer *view) { - PyObject *obj = view->obj; - if (!obj) return; - if (PyObject_CheckBuffer(obj)) { - PyBuffer_Release(view); - return; - } - if ((0)) {} - view->obj = NULL; - Py_DECREF(obj); -} -#endif - - - /* MemviewSliceIsContig */ - static int -__pyx_memviewslice_is_contig(const __Pyx_memviewslice mvs, char order, int ndim) -{ - int i, index, step, start; - Py_ssize_t itemsize = mvs.memview->view.itemsize; - if (order == 'F') { - step = 1; - start = 0; - } else { - step = -1; - start = ndim - 1; - } - for (i = 0; i < ndim; i++) { - index = start + step * i; - if (mvs.suboffsets[index] >= 0 || mvs.strides[index] != itemsize) - return 0; - itemsize *= mvs.shape[index]; - } - return 1; -} - -/* OverlappingSlices */ - static void -__pyx_get_array_memory_extents(__Pyx_memviewslice *slice, - void **out_start, void **out_end, - int ndim, size_t itemsize) -{ - char *start, *end; - int i; - start = end = slice->data; - for (i = 0; i < ndim; i++) { - Py_ssize_t stride = slice->strides[i]; - Py_ssize_t extent = slice->shape[i]; - if (extent == 0) { - *out_start = *out_end = start; - return; - } else { - if (stride > 0) - end += stride * (extent - 1); - else - start += stride * (extent - 1); - } - } - *out_start = start; - *out_end = end + itemsize; -} -static int -__pyx_slices_overlap(__Pyx_memviewslice *slice1, - __Pyx_memviewslice *slice2, - int ndim, size_t itemsize) -{ - void *start1, *end1, *start2, *end2; - __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize); - __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize); - return (start1 < end2) && (start2 < end1); -} - -/* TypeInfoCompare */ - static int -__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b) -{ - int i; - if (!a || !b) - return 0; - if (a == b) - return 1; - if (a->size != b->size || a->typegroup != b->typegroup || - a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) { - if (a->typegroup == 'H' || b->typegroup == 'H') { - return a->size == b->size; - } else { - return 0; - } - } - if (a->ndim) { - for (i = 0; i < a->ndim; i++) - if (a->arraysize[i] != b->arraysize[i]) - return 0; - } - if (a->typegroup == 'S') { - if (a->flags != b->flags) - return 0; - if (a->fields || b->fields) { - if (!(a->fields && b->fields)) - return 0; - for (i = 0; a->fields[i].type && b->fields[i].type; i++) { - __Pyx_StructField *field_a = a->fields + i; - __Pyx_StructField *field_b = b->fields + i; - if (field_a->offset != field_b->offset || - !__pyx_typeinfo_cmp(field_a->type, field_b->type)) - return 0; - } - return !a->fields[i].type && !b->fields[i].type; - } - } - return 1; -} - -/* MemviewSliceValidateAndInit */ - static int -__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec) -{ - if (buf->shape[dim] <= 1) - return 1; - if (buf->strides) { - if (spec & __Pyx_MEMVIEW_CONTIG) { - if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) { - if (unlikely(buf->strides[dim] != sizeof(void *))) { - PyErr_Format(PyExc_ValueError, - "Buffer is not indirectly contiguous " - "in dimension %d.", dim); - goto fail; - } - } else if (unlikely(buf->strides[dim] != buf->itemsize)) { - PyErr_SetString(PyExc_ValueError, - "Buffer and memoryview are not contiguous " - "in the same dimension."); - goto fail; - } - } - if (spec & __Pyx_MEMVIEW_FOLLOW) { - Py_ssize_t stride = buf->strides[dim]; - if (stride < 0) - stride = -stride; - if (unlikely(stride < buf->itemsize)) { - PyErr_SetString(PyExc_ValueError, - "Buffer and memoryview are not contiguous " - "in the same dimension."); - goto fail; - } - } - } else { - if (unlikely(spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1)) { - PyErr_Format(PyExc_ValueError, - "C-contiguous buffer is not contiguous in " - "dimension %d", dim); - goto fail; - } else if (unlikely(spec & (__Pyx_MEMVIEW_PTR))) { - PyErr_Format(PyExc_ValueError, - "C-contiguous buffer is not indirect in " - "dimension %d", dim); - goto fail; - } else if (unlikely(buf->suboffsets)) { - PyErr_SetString(PyExc_ValueError, - "Buffer exposes suboffsets but no strides"); - goto fail; - } - } - return 1; -fail: - return 0; -} -static int -__pyx_check_suboffsets(Py_buffer *buf, int dim, int ndim, int spec) -{ - CYTHON_UNUSED_VAR(ndim); - if (spec & __Pyx_MEMVIEW_DIRECT) { - if (unlikely(buf->suboffsets && buf->suboffsets[dim] >= 0)) { - PyErr_Format(PyExc_ValueError, - "Buffer not compatible with direct access " - "in dimension %d.", dim); - goto fail; - } - } - if (spec & __Pyx_MEMVIEW_PTR) { - if (unlikely(!buf->suboffsets || (buf->suboffsets[dim] < 0))) { - PyErr_Format(PyExc_ValueError, - "Buffer is not indirectly accessible " - "in dimension %d.", dim); - goto fail; - } - } - return 1; -fail: - return 0; -} -static int -__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag) -{ - int i; - if (c_or_f_flag & __Pyx_IS_F_CONTIG) { - Py_ssize_t stride = 1; - for (i = 0; i < ndim; i++) { - if (unlikely(stride * buf->itemsize != buf->strides[i] && buf->shape[i] > 1)) { - PyErr_SetString(PyExc_ValueError, - "Buffer not fortran contiguous."); - goto fail; - } - stride = stride * buf->shape[i]; - } - } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) { - Py_ssize_t stride = 1; - for (i = ndim - 1; i >- 1; i--) { - if (unlikely(stride * buf->itemsize != buf->strides[i] && buf->shape[i] > 1)) { - PyErr_SetString(PyExc_ValueError, - "Buffer not C contiguous."); - goto fail; - } - stride = stride * buf->shape[i]; - } - } - return 1; -fail: - return 0; -} -static int __Pyx_ValidateAndInit_memviewslice( - int *axes_specs, - int c_or_f_flag, - int buf_flags, - int ndim, - __Pyx_TypeInfo *dtype, - __Pyx_BufFmt_StackElem stack[], - __Pyx_memviewslice *memviewslice, - PyObject *original_obj) -{ - struct __pyx_memoryview_obj *memview, *new_memview; - __Pyx_RefNannyDeclarations - Py_buffer *buf; - int i, spec = 0, retval = -1; - __Pyx_BufFmt_Context ctx; - int from_memoryview = __pyx_memoryview_check(original_obj); - __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0); - if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *) - original_obj)->typeinfo)) { - memview = (struct __pyx_memoryview_obj *) original_obj; - new_memview = NULL; - } else { - memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new( - original_obj, buf_flags, 0, dtype); - new_memview = memview; - if (unlikely(!memview)) - goto fail; - } - buf = &memview->view; - if (unlikely(buf->ndim != ndim)) { - PyErr_Format(PyExc_ValueError, - "Buffer has wrong number of dimensions (expected %d, got %d)", - ndim, buf->ndim); - goto fail; - } - if (new_memview) { - __Pyx_BufFmt_Init(&ctx, stack, dtype); - if (unlikely(!__Pyx_BufFmt_CheckString(&ctx, buf->format))) goto fail; - } - if (unlikely((unsigned) buf->itemsize != dtype->size)) { - PyErr_Format(PyExc_ValueError, - "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) " - "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)", - buf->itemsize, - (buf->itemsize > 1) ? "s" : "", - dtype->name, - dtype->size, - (dtype->size > 1) ? "s" : ""); - goto fail; - } - if (buf->len > 0) { - for (i = 0; i < ndim; i++) { - spec = axes_specs[i]; - if (unlikely(!__pyx_check_strides(buf, i, ndim, spec))) - goto fail; - if (unlikely(!__pyx_check_suboffsets(buf, i, ndim, spec))) - goto fail; - } - if (unlikely(buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))) - goto fail; - } - if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice, - new_memview != NULL) == -1)) { - goto fail; - } - retval = 0; - goto no_fail; -fail: - Py_XDECREF(new_memview); - retval = -1; -no_fail: - __Pyx_RefNannyFinishContext(); - return retval; -} - -/* ObjectToMemviewSlice */ - static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_double(PyObject *obj, int writable_flag) { - __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_BufFmt_StackElem stack[1]; - int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) }; - int retcode; - if (obj == Py_None) { - result.memview = (struct __pyx_memoryview_obj *) Py_None; - return result; - } - retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0, - PyBUF_RECORDS_RO | writable_flag, 1, - &__Pyx_TypeInfo_double, stack, - &result, obj); - if (unlikely(retcode == -1)) - goto __pyx_fail; - return result; -__pyx_fail: - result.memview = NULL; - result.data = NULL; - return result; -} - -/* ObjectToMemviewSlice */ - static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int64_t(PyObject *obj, int writable_flag) { - __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_BufFmt_StackElem stack[1]; - int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) }; - int retcode; - if (obj == Py_None) { - result.memview = (struct __pyx_memoryview_obj *) Py_None; - return result; - } - retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0, - PyBUF_RECORDS_RO | writable_flag, 2, - &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, stack, - &result, obj); - if (unlikely(retcode == -1)) - goto __pyx_fail; - return result; -__pyx_fail: - result.memview = NULL; - result.data = NULL; - return result; -} - -/* CIntFromPyVerify */ - #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* Declarations */ - #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) - #ifdef __cplusplus - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - return ::std::complex< float >(x, y); - } - #else - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - return x + y*(__pyx_t_float_complex)_Complex_I; - } - #endif -#else - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - __pyx_t_float_complex z; - z.real = x; - z.imag = y; - return z; - } -#endif - -/* Arithmetic */ - #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) -#else - static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - return (a.real == b.real) && (a.imag == b.imag); - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real + b.real; - z.imag = a.imag + b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real - b.real; - z.imag = a.imag - b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real * b.real - a.imag * b.imag; - z.imag = a.real * b.imag + a.imag * b.real; - return z; - } - #if 1 - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - if (b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); - } else if (fabsf(b.real) >= fabsf(b.imag)) { - if (b.real == 0 && b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.imag); - } else { - float r = b.imag / b.real; - float s = (float)(1.0) / (b.real + b.imag * r); - return __pyx_t_float_complex_from_parts( - (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); - } - } else { - float r = b.real / b.imag; - float s = (float)(1.0) / (b.imag + b.real * r); - return __pyx_t_float_complex_from_parts( - (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); - } - } - #else - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - if (b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); - } else { - float denom = b.real * b.real + b.imag * b.imag; - return __pyx_t_float_complex_from_parts( - (a.real * b.real + a.imag * b.imag) / denom, - (a.imag * b.real - a.real * b.imag) / denom); - } - } - #endif - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex a) { - __pyx_t_float_complex z; - z.real = -a.real; - z.imag = -a.imag; - return z; - } - static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex a) { - return (a.real == 0) && (a.imag == 0); - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex a) { - __pyx_t_float_complex z; - z.real = a.real; - z.imag = -a.imag; - return z; - } - #if 1 - static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex z) { - #if !defined(HAVE_HYPOT) || defined(_MSC_VER) - return sqrtf(z.real*z.real + z.imag*z.imag); - #else - return hypotf(z.real, z.imag); - #endif - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - float r, lnr, theta, z_r, z_theta; - if (b.imag == 0 && b.real == (int)b.real) { - if (b.real < 0) { - float denom = a.real * a.real + a.imag * a.imag; - a.real = a.real / denom; - a.imag = -a.imag / denom; - b.real = -b.real; - } - switch ((int)b.real) { - case 0: - z.real = 1; - z.imag = 0; - return z; - case 1: - return a; - case 2: - return __Pyx_c_prod_float(a, a); - case 3: - z = __Pyx_c_prod_float(a, a); - return __Pyx_c_prod_float(z, a); - case 4: - z = __Pyx_c_prod_float(a, a); - return __Pyx_c_prod_float(z, z); - } - } - if (a.imag == 0) { - if (a.real == 0) { - return a; - } else if ((b.imag == 0) && (a.real >= 0)) { - z.real = powf(a.real, b.real); - z.imag = 0; - return z; - } else if (a.real > 0) { - r = a.real; - theta = 0; - } else { - r = -a.real; - theta = atan2f(0.0, -1.0); - } - } else { - r = __Pyx_c_abs_float(a); - theta = atan2f(a.imag, a.real); - } - lnr = logf(r); - z_r = expf(lnr * b.real - theta * b.imag); - z_theta = theta * b.real + lnr * b.imag; - z.real = z_r * cosf(z_theta); - z.imag = z_r * sinf(z_theta); - return z; - } - #endif -#endif - -/* Declarations */ - #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) - #ifdef __cplusplus - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - return ::std::complex< double >(x, y); - } - #else - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - return x + y*(__pyx_t_double_complex)_Complex_I; - } - #endif -#else - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - __pyx_t_double_complex z; - z.real = x; - z.imag = y; - return z; - } -#endif - -/* Arithmetic */ - #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) -#else - static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - return (a.real == b.real) && (a.imag == b.imag); - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real + b.real; - z.imag = a.imag + b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real - b.real; - z.imag = a.imag - b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real * b.real - a.imag * b.imag; - z.imag = a.real * b.imag + a.imag * b.real; - return z; - } - #if 1 - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - if (b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); - } else if (fabs(b.real) >= fabs(b.imag)) { - if (b.real == 0 && b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); - } else { - double r = b.imag / b.real; - double s = (double)(1.0) / (b.real + b.imag * r); - return __pyx_t_double_complex_from_parts( - (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); - } - } else { - double r = b.real / b.imag; - double s = (double)(1.0) / (b.imag + b.real * r); - return __pyx_t_double_complex_from_parts( - (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); - } - } - #else - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - if (b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); - } else { - double denom = b.real * b.real + b.imag * b.imag; - return __pyx_t_double_complex_from_parts( - (a.real * b.real + a.imag * b.imag) / denom, - (a.imag * b.real - a.real * b.imag) / denom); - } - } - #endif - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { - __pyx_t_double_complex z; - z.real = -a.real; - z.imag = -a.imag; - return z; - } - static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { - return (a.real == 0) && (a.imag == 0); - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { - __pyx_t_double_complex z; - z.real = a.real; - z.imag = -a.imag; - return z; - } - #if 1 - static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { - #if !defined(HAVE_HYPOT) || defined(_MSC_VER) - return sqrt(z.real*z.real + z.imag*z.imag); - #else - return hypot(z.real, z.imag); - #endif - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - double r, lnr, theta, z_r, z_theta; - if (b.imag == 0 && b.real == (int)b.real) { - if (b.real < 0) { - double denom = a.real * a.real + a.imag * a.imag; - a.real = a.real / denom; - a.imag = -a.imag / denom; - b.real = -b.real; - } - switch ((int)b.real) { - case 0: - z.real = 1; - z.imag = 0; - return z; - case 1: - return a; - case 2: - return __Pyx_c_prod_double(a, a); - case 3: - z = __Pyx_c_prod_double(a, a); - return __Pyx_c_prod_double(z, a); - case 4: - z = __Pyx_c_prod_double(a, a); - return __Pyx_c_prod_double(z, z); - } - } - if (a.imag == 0) { - if (a.real == 0) { - return a; - } else if ((b.imag == 0) && (a.real >= 0)) { - z.real = pow(a.real, b.real); - z.imag = 0; - return z; - } else if (a.real > 0) { - r = a.real; - theta = 0; - } else { - r = -a.real; - theta = atan2(0.0, -1.0); - } - } else { - r = __Pyx_c_abs_double(a); - theta = atan2(a.imag, a.real); - } - lnr = log(r); - z_r = exp(lnr * b.real - theta * b.imag); - z_theta = theta * b.real + lnr * b.imag; - z.real = z_r * cos(z_theta); - z.imag = z_r * sin(z_theta); - return z; - } - #endif -#endif - -/* Declarations */ - #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) - #ifdef __cplusplus - static CYTHON_INLINE __pyx_t_long_double_complex __pyx_t_long_double_complex_from_parts(long double x, long double y) { - return ::std::complex< long double >(x, y); - } - #else - static CYTHON_INLINE __pyx_t_long_double_complex __pyx_t_long_double_complex_from_parts(long double x, long double y) { - return x + y*(__pyx_t_long_double_complex)_Complex_I; - } - #endif -#else - static CYTHON_INLINE __pyx_t_long_double_complex __pyx_t_long_double_complex_from_parts(long double x, long double y) { - __pyx_t_long_double_complex z; - z.real = x; - z.imag = y; - return z; - } -#endif - -/* Arithmetic */ - #if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) -#else - static CYTHON_INLINE int __Pyx_c_eq_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { - return (a.real == b.real) && (a.imag == b.imag); - } - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_sum_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { - __pyx_t_long_double_complex z; - z.real = a.real + b.real; - z.imag = a.imag + b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_diff_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { - __pyx_t_long_double_complex z; - z.real = a.real - b.real; - z.imag = a.imag - b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_prod_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { - __pyx_t_long_double_complex z; - z.real = a.real * b.real - a.imag * b.imag; - z.imag = a.real * b.imag + a.imag * b.real; - return z; - } - #if 1 - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_quot_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { - if (b.imag == 0) { - return __pyx_t_long_double_complex_from_parts(a.real / b.real, a.imag / b.real); - } else if (fabsl(b.real) >= fabsl(b.imag)) { - if (b.real == 0 && b.imag == 0) { - return __pyx_t_long_double_complex_from_parts(a.real / b.real, a.imag / b.imag); - } else { - long double r = b.imag / b.real; - long double s = (long double)(1.0) / (b.real + b.imag * r); - return __pyx_t_long_double_complex_from_parts( - (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); - } - } else { - long double r = b.real / b.imag; - long double s = (long double)(1.0) / (b.imag + b.real * r); - return __pyx_t_long_double_complex_from_parts( - (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); - } - } - #else - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_quot_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { - if (b.imag == 0) { - return __pyx_t_long_double_complex_from_parts(a.real / b.real, a.imag / b.real); - } else { - long double denom = b.real * b.real + b.imag * b.imag; - return __pyx_t_long_double_complex_from_parts( - (a.real * b.real + a.imag * b.imag) / denom, - (a.imag * b.real - a.real * b.imag) / denom); - } - } - #endif - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_neg_long__double(__pyx_t_long_double_complex a) { - __pyx_t_long_double_complex z; - z.real = -a.real; - z.imag = -a.imag; - return z; - } - static CYTHON_INLINE int __Pyx_c_is_zero_long__double(__pyx_t_long_double_complex a) { - return (a.real == 0) && (a.imag == 0); - } - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_conj_long__double(__pyx_t_long_double_complex a) { - __pyx_t_long_double_complex z; - z.real = a.real; - z.imag = -a.imag; - return z; - } - #if 1 - static CYTHON_INLINE long double __Pyx_c_abs_long__double(__pyx_t_long_double_complex z) { - #if !defined(HAVE_HYPOT) || defined(_MSC_VER) - return sqrtl(z.real*z.real + z.imag*z.imag); - #else - return hypotl(z.real, z.imag); - #endif - } - static CYTHON_INLINE __pyx_t_long_double_complex __Pyx_c_pow_long__double(__pyx_t_long_double_complex a, __pyx_t_long_double_complex b) { - __pyx_t_long_double_complex z; - long double r, lnr, theta, z_r, z_theta; - if (b.imag == 0 && b.real == (int)b.real) { - if (b.real < 0) { - long double denom = a.real * a.real + a.imag * a.imag; - a.real = a.real / denom; - a.imag = -a.imag / denom; - b.real = -b.real; - } - switch ((int)b.real) { - case 0: - z.real = 1; - z.imag = 0; - return z; - case 1: - return a; - case 2: - return __Pyx_c_prod_long__double(a, a); - case 3: - z = __Pyx_c_prod_long__double(a, a); - return __Pyx_c_prod_long__double(z, a); - case 4: - z = __Pyx_c_prod_long__double(a, a); - return __Pyx_c_prod_long__double(z, z); - } - } - if (a.imag == 0) { - if (a.real == 0) { - return a; - } else if ((b.imag == 0) && (a.real >= 0)) { - z.real = powl(a.real, b.real); - z.imag = 0; - return z; - } else if (a.real > 0) { - r = a.real; - theta = 0; - } else { - r = -a.real; - theta = atan2l(0.0, -1.0); - } - } else { - r = __Pyx_c_abs_long__double(a); - theta = atan2l(a.imag, a.real); - } - lnr = logl(r); - z_r = expl(lnr * b.real - theta * b.imag); - z_theta = theta * b.real + lnr * b.imag; - z.real = z_r * cosl(z_theta); - z.imag = z_r * sinl(z_theta); - return z; - } - #endif -#endif - -/* MemviewSliceCopyTemplate */ - static __Pyx_memviewslice -__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, - const char *mode, int ndim, - size_t sizeof_dtype, int contig_flag, - int dtype_is_object) -{ - __Pyx_RefNannyDeclarations - int i; - __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } }; - struct __pyx_memoryview_obj *from_memview = from_mvs->memview; - Py_buffer *buf = &from_memview->view; - PyObject *shape_tuple = NULL; - PyObject *temp_int = NULL; - struct __pyx_array_obj *array_obj = NULL; - struct __pyx_memoryview_obj *memview_obj = NULL; - __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0); - for (i = 0; i < ndim; i++) { - if (unlikely(from_mvs->suboffsets[i] >= 0)) { - PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with " - "indirect dimensions (axis %d)", i); - goto fail; - } - } - shape_tuple = PyTuple_New(ndim); - if (unlikely(!shape_tuple)) { - goto fail; - } - __Pyx_GOTREF(shape_tuple); - for(i = 0; i < ndim; i++) { - temp_int = PyInt_FromSsize_t(from_mvs->shape[i]); - if(unlikely(!temp_int)) { - goto fail; - } else { - PyTuple_SET_ITEM(shape_tuple, i, temp_int); - temp_int = NULL; - } - } - array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL); - if (unlikely(!array_obj)) { - goto fail; - } - __Pyx_GOTREF(array_obj); - memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new( - (PyObject *) array_obj, contig_flag, - dtype_is_object, - from_mvs->memview->typeinfo); - if (unlikely(!memview_obj)) - goto fail; - if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0)) - goto fail; - if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim, - dtype_is_object) < 0)) - goto fail; - goto no_fail; -fail: - __Pyx_XDECREF(new_mvs.memview); - new_mvs.memview = NULL; - new_mvs.data = NULL; -no_fail: - __Pyx_XDECREF(shape_tuple); - __Pyx_XDECREF(temp_int); - __Pyx_XDECREF(array_obj); - __Pyx_RefNannyFinishContext(); - return new_mvs; -} - -/* MemviewSliceInit */ - static int -__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview, - int ndim, - __Pyx_memviewslice *memviewslice, - int memview_is_new_reference) -{ - __Pyx_RefNannyDeclarations - int i, retval=-1; - Py_buffer *buf = &memview->view; - __Pyx_RefNannySetupContext("init_memviewslice", 0); - if (unlikely(memviewslice->memview || memviewslice->data)) { - PyErr_SetString(PyExc_ValueError, - "memviewslice is already initialized!"); - goto fail; - } - if (buf->strides) { - for (i = 0; i < ndim; i++) { - memviewslice->strides[i] = buf->strides[i]; - } - } else { - Py_ssize_t stride = buf->itemsize; - for (i = ndim - 1; i >= 0; i--) { - memviewslice->strides[i] = stride; - stride *= buf->shape[i]; - } - } - for (i = 0; i < ndim; i++) { - memviewslice->shape[i] = buf->shape[i]; - if (buf->suboffsets) { - memviewslice->suboffsets[i] = buf->suboffsets[i]; - } else { - memviewslice->suboffsets[i] = -1; - } - } - memviewslice->memview = memview; - memviewslice->data = (char *)buf->buf; - if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) { - Py_INCREF(memview); - } - retval = 0; - goto no_fail; -fail: - memviewslice->memview = 0; - memviewslice->data = 0; - retval = -1; -no_fail: - __Pyx_RefNannyFinishContext(); - return retval; -} -#ifndef Py_NO_RETURN -#define Py_NO_RETURN -#endif -static void __pyx_fatalerror(const char *fmt, ...) Py_NO_RETURN { - va_list vargs; - char msg[200]; -#if PY_VERSION_HEX >= 0x030A0000 || defined(HAVE_STDARG_PROTOTYPES) - va_start(vargs, fmt); -#else - va_start(vargs); -#endif - vsnprintf(msg, 200, fmt, vargs); - va_end(vargs); - Py_FatalError(msg); -} -static CYTHON_INLINE int -__pyx_add_acquisition_count_locked(__pyx_atomic_int_type *acquisition_count, - PyThread_type_lock lock) -{ - int result; - PyThread_acquire_lock(lock, 1); - result = (*acquisition_count)++; - PyThread_release_lock(lock); - return result; -} -static CYTHON_INLINE int -__pyx_sub_acquisition_count_locked(__pyx_atomic_int_type *acquisition_count, - PyThread_type_lock lock) -{ - int result; - PyThread_acquire_lock(lock, 1); - result = (*acquisition_count)--; - PyThread_release_lock(lock); - return result; -} -static CYTHON_INLINE void -__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno) -{ - __pyx_nonatomic_int_type old_acquisition_count; - struct __pyx_memoryview_obj *memview = memslice->memview; - if (unlikely(!memview || (PyObject *) memview == Py_None)) { - return; - } - old_acquisition_count = __pyx_add_acquisition_count(memview); - if (unlikely(old_acquisition_count <= 0)) { - if (likely(old_acquisition_count == 0)) { - if (have_gil) { - Py_INCREF((PyObject *) memview); - } else { - PyGILState_STATE _gilstate = PyGILState_Ensure(); - Py_INCREF((PyObject *) memview); - PyGILState_Release(_gilstate); - } - } else { - __pyx_fatalerror("Acquisition count is %d (line %d)", - old_acquisition_count+1, lineno); - } - } -} -static CYTHON_INLINE void __Pyx_XCLEAR_MEMVIEW(__Pyx_memviewslice *memslice, - int have_gil, int lineno) { - __pyx_nonatomic_int_type old_acquisition_count; - struct __pyx_memoryview_obj *memview = memslice->memview; - if (unlikely(!memview || (PyObject *) memview == Py_None)) { - memslice->memview = NULL; - return; - } - old_acquisition_count = __pyx_sub_acquisition_count(memview); - memslice->data = NULL; - if (likely(old_acquisition_count > 1)) { - memslice->memview = NULL; - } else if (likely(old_acquisition_count == 1)) { - if (have_gil) { - Py_CLEAR(memslice->memview); - } else { - PyGILState_STATE _gilstate = PyGILState_Ensure(); - Py_CLEAR(memslice->memview); - PyGILState_Release(_gilstate); - } - } else { - __pyx_fatalerror("Acquisition count is %d (line %d)", - old_acquisition_count-1, lineno); - } -} - -/* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_npy_int64(npy_int64 value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const npy_int64 neg_one = (npy_int64) -1, const_zero = (npy_int64) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(npy_int64) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(npy_int64) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(npy_int64) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(npy_int64) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(npy_int64) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; -#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 - return _PyLong_FromByteArray(bytes, sizeof(npy_int64), - little, !is_unsigned); -#else - PyObject *from_bytes, *result = NULL; - PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; - from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); - if (!from_bytes) return NULL; - py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(npy_int64)); - if (!py_bytes) goto limited_bad; - order_str = PyUnicode_FromString(little ? "little" : "big"); - if (!order_str) goto limited_bad; - arg_tuple = PyTuple_Pack(2, py_bytes, order_str); - if (!arg_tuple) goto limited_bad; - if (!is_unsigned) { - kwds = PyDict_New(); - if (!kwds) goto limited_bad; - if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; - } - result = PyObject_Call(from_bytes, arg_tuple, kwds); - limited_bad: - Py_XDECREF(kwds); - Py_XDECREF(arg_tuple); - Py_XDECREF(order_str); - Py_XDECREF(py_bytes); - Py_XDECREF(from_bytes); - return result; -#endif - } -} - -/* CIntFromPy */ - static CYTHON_INLINE npy_int64 __Pyx_PyInt_As_npy_int64(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const npy_int64 neg_one = (npy_int64) -1, const_zero = (npy_int64) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if ((sizeof(npy_int64) < sizeof(long))) { - __PYX_VERIFY_RETURN_INT(npy_int64, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (npy_int64) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - if (unlikely(__Pyx_PyLong_IsNeg(x))) { - goto raise_neg_overflow; - } else if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(npy_int64, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_DigitCount(x)) { - case 2: - if ((8 * sizeof(npy_int64) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(npy_int64) >= 2 * PyLong_SHIFT)) { - return (npy_int64) (((((npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0])); - } - } - break; - case 3: - if ((8 * sizeof(npy_int64) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(npy_int64) >= 3 * PyLong_SHIFT)) { - return (npy_int64) (((((((npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0])); - } - } - break; - case 4: - if ((8 * sizeof(npy_int64) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(npy_int64) >= 4 * PyLong_SHIFT)) { - return (npy_int64) (((((((((npy_int64)digits[3]) << PyLong_SHIFT) | (npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0])); - } - } - break; - } - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (npy_int64) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if ((sizeof(npy_int64) <= sizeof(unsigned long))) { - __PYX_VERIFY_RETURN_INT_EXC(npy_int64, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(npy_int64) <= sizeof(unsigned PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(npy_int64, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(npy_int64, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_SignedDigitCount(x)) { - case -2: - if ((8 * sizeof(npy_int64) - 1 > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(npy_int64, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(npy_int64) - 1 > 2 * PyLong_SHIFT)) { - return (npy_int64) (((npy_int64)-1)*(((((npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); - } - } - break; - case 2: - if ((8 * sizeof(npy_int64) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(npy_int64) - 1 > 2 * PyLong_SHIFT)) { - return (npy_int64) ((((((npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); - } - } - break; - case -3: - if ((8 * sizeof(npy_int64) - 1 > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(npy_int64, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(npy_int64) - 1 > 3 * PyLong_SHIFT)) { - return (npy_int64) (((npy_int64)-1)*(((((((npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); - } - } - break; - case 3: - if ((8 * sizeof(npy_int64) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(npy_int64) - 1 > 3 * PyLong_SHIFT)) { - return (npy_int64) ((((((((npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); - } - } - break; - case -4: - if ((8 * sizeof(npy_int64) - 1 > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(npy_int64, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(npy_int64) - 1 > 4 * PyLong_SHIFT)) { - return (npy_int64) (((npy_int64)-1)*(((((((((npy_int64)digits[3]) << PyLong_SHIFT) | (npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); - } - } - break; - case 4: - if ((8 * sizeof(npy_int64) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(npy_int64) - 1 > 4 * PyLong_SHIFT)) { - return (npy_int64) ((((((((((npy_int64)digits[3]) << PyLong_SHIFT) | (npy_int64)digits[2]) << PyLong_SHIFT) | (npy_int64)digits[1]) << PyLong_SHIFT) | (npy_int64)digits[0]))); - } - } - break; - } - } -#endif - if ((sizeof(npy_int64) <= sizeof(long))) { - __PYX_VERIFY_RETURN_INT_EXC(npy_int64, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(npy_int64) <= sizeof(PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(npy_int64, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { - npy_int64 val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); -#if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } -#endif - if (likely(v)) { - int ret = -1; -#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); -#else - PyObject *stepval = NULL, *mask = NULL, *shift = NULL; - int bits, remaining_bits, is_negative = 0; - long idigit; - int chunk_size = (sizeof(long) < 8) ? 30 : 62; - if (unlikely(!PyLong_CheckExact(v))) { - PyObject *tmp = v; - v = PyNumber_Long(v); - assert(PyLong_CheckExact(v)); - Py_DECREF(tmp); - if (unlikely(!v)) return (npy_int64) -1; - } -#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - if (Py_SIZE(x) == 0) - return (npy_int64) 0; - is_negative = Py_SIZE(x) < 0; -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (npy_int64) -1; - is_negative = result == 1; - } -#endif - if (is_unsigned && unlikely(is_negative)) { - goto raise_neg_overflow; - } else if (is_negative) { - stepval = PyNumber_Invert(v); - if (unlikely(!stepval)) - return (npy_int64) -1; - } else { - stepval = __Pyx_NewRef(v); - } - val = (npy_int64) 0; - mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; - shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; - for (bits = 0; bits < (int) sizeof(npy_int64) * 8 - chunk_size; bits += chunk_size) { - PyObject *tmp, *digit; - digit = PyNumber_And(stepval, mask); - if (unlikely(!digit)) goto done; - idigit = PyLong_AsLong(digit); - Py_DECREF(digit); - if (unlikely(idigit < 0)) goto done; - tmp = PyNumber_Rshift(stepval, shift); - if (unlikely(!tmp)) goto done; - Py_DECREF(stepval); stepval = tmp; - val |= ((npy_int64) idigit) << bits; - #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - if (Py_SIZE(stepval) == 0) - goto unpacking_done; - #endif - } - idigit = PyLong_AsLong(stepval); - if (unlikely(idigit < 0)) goto done; - remaining_bits = ((int) sizeof(npy_int64) * 8) - bits - (is_unsigned ? 0 : 1); - if (unlikely(idigit >= (1L << remaining_bits))) - goto raise_overflow; - val |= ((npy_int64) idigit) << bits; - #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - unpacking_done: - #endif - if (!is_unsigned) { - if (unlikely(val & (((npy_int64) 1) << (sizeof(npy_int64) * 8 - 1)))) - goto raise_overflow; - if (is_negative) - val = ~val; - } - ret = 0; - done: - Py_XDECREF(shift); - Py_XDECREF(mask); - Py_XDECREF(stepval); -#endif - Py_DECREF(v); - if (likely(!ret)) - return val; - } - return (npy_int64) -1; - } - } else { - npy_int64 val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (npy_int64) -1; - val = __Pyx_PyInt_As_npy_int64(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to npy_int64"); - return (npy_int64) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to npy_int64"); - return (npy_int64) -1; -} - -/* CIntFromPy */ - static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const int neg_one = (int) -1, const_zero = (int) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if ((sizeof(int) < sizeof(long))) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - if (unlikely(__Pyx_PyLong_IsNeg(x))) { - goto raise_neg_overflow; - } else if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_DigitCount(x)) { - case 2: - if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if ((sizeof(int) <= sizeof(unsigned long))) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_SignedDigitCount(x)) { - case -2: - if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } - } -#endif - if ((sizeof(int) <= sizeof(long))) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); -#if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } -#endif - if (likely(v)) { - int ret = -1; -#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); -#else - PyObject *stepval = NULL, *mask = NULL, *shift = NULL; - int bits, remaining_bits, is_negative = 0; - long idigit; - int chunk_size = (sizeof(long) < 8) ? 30 : 62; - if (unlikely(!PyLong_CheckExact(v))) { - PyObject *tmp = v; - v = PyNumber_Long(v); - assert(PyLong_CheckExact(v)); - Py_DECREF(tmp); - if (unlikely(!v)) return (int) -1; - } -#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - if (Py_SIZE(x) == 0) - return (int) 0; - is_negative = Py_SIZE(x) < 0; -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - is_negative = result == 1; - } -#endif - if (is_unsigned && unlikely(is_negative)) { - goto raise_neg_overflow; - } else if (is_negative) { - stepval = PyNumber_Invert(v); - if (unlikely(!stepval)) - return (int) -1; - } else { - stepval = __Pyx_NewRef(v); - } - val = (int) 0; - mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; - shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; - for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { - PyObject *tmp, *digit; - digit = PyNumber_And(stepval, mask); - if (unlikely(!digit)) goto done; - idigit = PyLong_AsLong(digit); - Py_DECREF(digit); - if (unlikely(idigit < 0)) goto done; - tmp = PyNumber_Rshift(stepval, shift); - if (unlikely(!tmp)) goto done; - Py_DECREF(stepval); stepval = tmp; - val |= ((int) idigit) << bits; - #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - if (Py_SIZE(stepval) == 0) - goto unpacking_done; - #endif - } - idigit = PyLong_AsLong(stepval); - if (unlikely(idigit < 0)) goto done; - remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); - if (unlikely(idigit >= (1L << remaining_bits))) - goto raise_overflow; - val |= ((int) idigit) << bits; - #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - unpacking_done: - #endif - if (!is_unsigned) { - if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) - goto raise_overflow; - if (is_negative) - val = ~val; - } - ret = 0; - done: - Py_XDECREF(shift); - Py_XDECREF(mask); - Py_XDECREF(stepval); -#endif - Py_DECREF(v); - if (likely(!ret)) - return val; - } - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* CIntFromPy */ - static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const long neg_one = (long) -1, const_zero = (long) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if ((sizeof(long) < sizeof(long))) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - if (unlikely(__Pyx_PyLong_IsNeg(x))) { - goto raise_neg_overflow; - } else if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_DigitCount(x)) { - case 2: - if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if ((sizeof(long) <= sizeof(unsigned long))) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_SignedDigitCount(x)) { - case -2: - if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } - } -#endif - if ((sizeof(long) <= sizeof(long))) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); -#if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } -#endif - if (likely(v)) { - int ret = -1; -#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); -#else - PyObject *stepval = NULL, *mask = NULL, *shift = NULL; - int bits, remaining_bits, is_negative = 0; - long idigit; - int chunk_size = (sizeof(long) < 8) ? 30 : 62; - if (unlikely(!PyLong_CheckExact(v))) { - PyObject *tmp = v; - v = PyNumber_Long(v); - assert(PyLong_CheckExact(v)); - Py_DECREF(tmp); - if (unlikely(!v)) return (long) -1; - } -#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - if (Py_SIZE(x) == 0) - return (long) 0; - is_negative = Py_SIZE(x) < 0; -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - is_negative = result == 1; - } -#endif - if (is_unsigned && unlikely(is_negative)) { - goto raise_neg_overflow; - } else if (is_negative) { - stepval = PyNumber_Invert(v); - if (unlikely(!stepval)) - return (long) -1; - } else { - stepval = __Pyx_NewRef(v); - } - val = (long) 0; - mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; - shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; - for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { - PyObject *tmp, *digit; - digit = PyNumber_And(stepval, mask); - if (unlikely(!digit)) goto done; - idigit = PyLong_AsLong(digit); - Py_DECREF(digit); - if (unlikely(idigit < 0)) goto done; - tmp = PyNumber_Rshift(stepval, shift); - if (unlikely(!tmp)) goto done; - Py_DECREF(stepval); stepval = tmp; - val |= ((long) idigit) << bits; - #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - if (Py_SIZE(stepval) == 0) - goto unpacking_done; - #endif - } - idigit = PyLong_AsLong(stepval); - if (unlikely(idigit < 0)) goto done; - remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); - if (unlikely(idigit >= (1L << remaining_bits))) - goto raise_overflow; - val |= ((long) idigit) << bits; - #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - unpacking_done: - #endif - if (!is_unsigned) { - if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) - goto raise_overflow; - if (is_negative) - val = ~val; - } - ret = 0; - done: - Py_XDECREF(shift); - Py_XDECREF(mask); - Py_XDECREF(stepval); -#endif - Py_DECREF(v); - if (likely(!ret)) - return val; - } - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const int neg_one = (int) -1, const_zero = (int) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(int) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(int) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(int) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; -#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 - return _PyLong_FromByteArray(bytes, sizeof(int), - little, !is_unsigned); -#else - PyObject *from_bytes, *result = NULL; - PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; - from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); - if (!from_bytes) return NULL; - py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(int)); - if (!py_bytes) goto limited_bad; - order_str = PyUnicode_FromString(little ? "little" : "big"); - if (!order_str) goto limited_bad; - arg_tuple = PyTuple_Pack(2, py_bytes, order_str); - if (!arg_tuple) goto limited_bad; - if (!is_unsigned) { - kwds = PyDict_New(); - if (!kwds) goto limited_bad; - if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; - } - result = PyObject_Call(from_bytes, arg_tuple, kwds); - limited_bad: - Py_XDECREF(kwds); - Py_XDECREF(arg_tuple); - Py_XDECREF(order_str); - Py_XDECREF(py_bytes); - Py_XDECREF(from_bytes); - return result; -#endif - } -} - -/* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const long neg_one = (long) -1, const_zero = (long) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; -#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); -#else - PyObject *from_bytes, *result = NULL; - PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; - from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); - if (!from_bytes) return NULL; - py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); - if (!py_bytes) goto limited_bad; - order_str = PyUnicode_FromString(little ? "little" : "big"); - if (!order_str) goto limited_bad; - arg_tuple = PyTuple_Pack(2, py_bytes, order_str); - if (!arg_tuple) goto limited_bad; - if (!is_unsigned) { - kwds = PyDict_New(); - if (!kwds) goto limited_bad; - if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; - } - result = PyObject_Call(from_bytes, arg_tuple, kwds); - limited_bad: - Py_XDECREF(kwds); - Py_XDECREF(arg_tuple); - Py_XDECREF(order_str); - Py_XDECREF(py_bytes); - Py_XDECREF(from_bytes); - return result; -#endif - } -} - -/* CIntFromPy */ - static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const char neg_one = (char) -1, const_zero = (char) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if ((sizeof(char) < sizeof(long))) { - __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (char) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - if (unlikely(__Pyx_PyLong_IsNeg(x))) { - goto raise_neg_overflow; - } else if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(char, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_DigitCount(x)) { - case 2: - if ((8 * sizeof(char) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(char) >= 2 * PyLong_SHIFT)) { - return (char) (((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); - } - } - break; - case 3: - if ((8 * sizeof(char) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(char) >= 3 * PyLong_SHIFT)) { - return (char) (((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); - } - } - break; - case 4: - if ((8 * sizeof(char) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(char) >= 4 * PyLong_SHIFT)) { - return (char) (((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); - } - } - break; - } - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (char) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if ((sizeof(char) <= sizeof(unsigned long))) { - __PYX_VERIFY_RETURN_INT_EXC(char, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(char) <= sizeof(unsigned PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(char, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(char, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_SignedDigitCount(x)) { - case -2: - if ((8 * sizeof(char) - 1 > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(char) - 1 > 2 * PyLong_SHIFT)) { - return (char) (((char)-1)*(((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - case 2: - if ((8 * sizeof(char) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(char) - 1 > 2 * PyLong_SHIFT)) { - return (char) ((((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - case -3: - if ((8 * sizeof(char) - 1 > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(char) - 1 > 3 * PyLong_SHIFT)) { - return (char) (((char)-1)*(((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - case 3: - if ((8 * sizeof(char) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(char) - 1 > 3 * PyLong_SHIFT)) { - return (char) ((((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - case -4: - if ((8 * sizeof(char) - 1 > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(char) - 1 > 4 * PyLong_SHIFT)) { - return (char) (((char)-1)*(((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - case 4: - if ((8 * sizeof(char) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(char) - 1 > 4 * PyLong_SHIFT)) { - return (char) ((((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - } - } -#endif - if ((sizeof(char) <= sizeof(long))) { - __PYX_VERIFY_RETURN_INT_EXC(char, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(char) <= sizeof(PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(char, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { - char val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); -#if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } -#endif - if (likely(v)) { - int ret = -1; -#if PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); -#else - PyObject *stepval = NULL, *mask = NULL, *shift = NULL; - int bits, remaining_bits, is_negative = 0; - long idigit; - int chunk_size = (sizeof(long) < 8) ? 30 : 62; - if (unlikely(!PyLong_CheckExact(v))) { - PyObject *tmp = v; - v = PyNumber_Long(v); - assert(PyLong_CheckExact(v)); - Py_DECREF(tmp); - if (unlikely(!v)) return (char) -1; - } -#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - if (Py_SIZE(x) == 0) - return (char) 0; - is_negative = Py_SIZE(x) < 0; -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (char) -1; - is_negative = result == 1; - } -#endif - if (is_unsigned && unlikely(is_negative)) { - goto raise_neg_overflow; - } else if (is_negative) { - stepval = PyNumber_Invert(v); - if (unlikely(!stepval)) - return (char) -1; - } else { - stepval = __Pyx_NewRef(v); - } - val = (char) 0; - mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; - shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; - for (bits = 0; bits < (int) sizeof(char) * 8 - chunk_size; bits += chunk_size) { - PyObject *tmp, *digit; - digit = PyNumber_And(stepval, mask); - if (unlikely(!digit)) goto done; - idigit = PyLong_AsLong(digit); - Py_DECREF(digit); - if (unlikely(idigit < 0)) goto done; - tmp = PyNumber_Rshift(stepval, shift); - if (unlikely(!tmp)) goto done; - Py_DECREF(stepval); stepval = tmp; - val |= ((char) idigit) << bits; - #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - if (Py_SIZE(stepval) == 0) - goto unpacking_done; - #endif - } - idigit = PyLong_AsLong(stepval); - if (unlikely(idigit < 0)) goto done; - remaining_bits = ((int) sizeof(char) * 8) - bits - (is_unsigned ? 0 : 1); - if (unlikely(idigit >= (1L << remaining_bits))) - goto raise_overflow; - val |= ((char) idigit) << bits; - #if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030B0000 - unpacking_done: - #endif - if (!is_unsigned) { - if (unlikely(val & (((char) 1) << (sizeof(char) * 8 - 1)))) - goto raise_overflow; - if (is_negative) - val = ~val; - } - ret = 0; - done: - Py_XDECREF(shift); - Py_XDECREF(mask); - Py_XDECREF(stepval); -#endif - Py_DECREF(v); - if (likely(!ret)) - return val; - } - return (char) -1; - } - } else { - char val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (char) -1; - val = __Pyx_PyInt_As_char(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to char"); - return (char) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to char"); - return (char) -1; -} - -/* FormatTypeName */ - #if CYTHON_COMPILING_IN_LIMITED_API -static __Pyx_TypeName -__Pyx_PyType_GetName(PyTypeObject* tp) -{ - PyObject *name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, - __pyx_n_s_name_2); - if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) { - PyErr_Clear(); - Py_XDECREF(name); - name = __Pyx_NewRef(__pyx_n_s__25); - } - return name; -} -#endif - -/* CheckBinaryVersion */ - static unsigned long __Pyx_get_runtime_version(void) { -#if __PYX_LIMITED_VERSION_HEX >= 0x030B00A4 - return Py_Version & ~0xFFUL; -#else - const char* rt_version = Py_GetVersion(); - unsigned long version = 0; - unsigned long factor = 0x01000000UL; - unsigned int digit = 0; - int i = 0; - while (factor) { - while ('0' <= rt_version[i] && rt_version[i] <= '9') { - digit = digit * 10 + (unsigned int) (rt_version[i] - '0'); - ++i; - } - version += factor * digit; - if (rt_version[i] != '.') - break; - digit = 0; - factor >>= 8; - ++i; - } - return version; -#endif -} -static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { - const unsigned long MAJOR_MINOR = 0xFFFF0000UL; - if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) - return 0; - if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) - return 1; - { - char message[200]; - PyOS_snprintf(message, sizeof(message), - "compile time Python version %d.%d " - "of module '%.100s' " - "%s " - "runtime version %d.%d", - (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), - __Pyx_MODULE_NAME, - (allow_newer) ? "was newer than" : "does not match", - (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) - ); - return PyErr_WarnEx(NULL, message, 1); - } -} - -/* FunctionImport */ - #ifndef __PYX_HAVE_RT_ImportFunction_3_0_10 -#define __PYX_HAVE_RT_ImportFunction_3_0_10 -static int __Pyx_ImportFunction_3_0_10(PyObject *module, const char *funcname, void (**f)(void), const char *sig) { - PyObject *d = 0; - PyObject *cobj = 0; - union { - void (*fp)(void); - void *p; - } tmp; - d = PyObject_GetAttrString(module, (char *)"__pyx_capi__"); - if (!d) - goto bad; - cobj = PyDict_GetItemString(d, funcname); - if (!cobj) { - PyErr_Format(PyExc_ImportError, - "%.200s does not export expected C function %.200s", - PyModule_GetName(module), funcname); - goto bad; - } - if (!PyCapsule_IsValid(cobj, sig)) { - PyErr_Format(PyExc_TypeError, - "C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)", - PyModule_GetName(module), funcname, sig, PyCapsule_GetName(cobj)); - goto bad; - } - tmp.p = PyCapsule_GetPointer(cobj, sig); - *f = tmp.fp; - if (!(*f)) - goto bad; - Py_DECREF(d); - return 0; -bad: - Py_XDECREF(d); - return -1; -} -#endif - -/* InitStrings */ - #if PY_MAJOR_VERSION >= 3 -static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) { - if (t.is_unicode | t.is_str) { - if (t.intern) { - *str = PyUnicode_InternFromString(t.s); - } else if (t.encoding) { - *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL); - } else { - *str = PyUnicode_FromStringAndSize(t.s, t.n - 1); - } - } else { - *str = PyBytes_FromStringAndSize(t.s, t.n - 1); - } - if (!*str) - return -1; - if (PyObject_Hash(*str) == -1) - return -1; - return 0; -} -#endif -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { - while (t->p) { - #if PY_MAJOR_VERSION >= 3 - __Pyx_InitString(*t, t->p); - #else - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - #endif - ++t; - } - return 0; -} - -#include -static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { - size_t len = strlen(s); - if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { - PyErr_SetString(PyExc_OverflowError, "byte string is too long"); - return -1; - } - return (Py_ssize_t) len; -} -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - Py_ssize_t len = __Pyx_ssize_strlen(c_str); - if (unlikely(len < 0)) return NULL; - return __Pyx_PyUnicode_FromStringAndSize(c_str, len); -} -static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { - Py_ssize_t len = __Pyx_ssize_strlen(c_str); - if (unlikely(len < 0)) return NULL; - return PyByteArray_FromStringAndSize(c_str, len); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_LIMITED_API) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { - __Pyx_TypeName result_type_name = __Pyx_PyType_GetName(Py_TYPE(result)); -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " - "The ability to return an instance of a strict subclass of int is deprecated, " - "and may be removed in a future version of Python.", - result_type_name)) { - __Pyx_DECREF_TypeName(result_type_name); - Py_DECREF(result); - return NULL; - } - __Pyx_DECREF_TypeName(result_type_name); - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type " __Pyx_FMT_TYPENAME ")", - type_name, type_name, result_type_name); - __Pyx_DECREF_TypeName(result_type_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - if (likely(__Pyx_PyLong_IsCompact(b))) { - return __Pyx_PyLong_CompactValue(b); - } else { - const digit* digits = __Pyx_PyLong_Digits(b); - const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { - if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { - return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); -#if PY_MAJOR_VERSION < 3 - } else if (likely(PyInt_CheckExact(o))) { - return PyInt_AS_LONG(o); -#endif - } else { - Py_ssize_t ival; - PyObject *x; - x = PyNumber_Index(o); - if (!x) return -1; - ival = PyInt_AsLong(x); - Py_DECREF(x); - return ival; - } -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -/* #### Code section: utility_code_pragmas_end ### */ -#ifdef _MSC_VER -#pragma warning( pop ) -#endif - - - -/* #### Code section: end ### */ -#endif /* Py_PYTHON_H */ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..4366a52e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,55 @@ +[build-system] +requires = ["setuptools-scm>=3.2.0", + "setuptools_scm_git_archive", + "numpy>=2.0.0", + "cython>=0.29", + "setuptools>=61.0", + "scipy>=1.12.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "pygom" +#dynamic = ["version"] +version = "0.1.8a" +dependencies = [ + "dask[complete]>=0.13.0", + "graphviz>=0.4.9", + "matplotlib>=1.0.0", + "numpy>=2.0.0", + "pandas>=2.2.2", + "python-dateutil>=2.0.0", + "scipy>=1.4.1", + "sympy>=1.0.0", + "numpydoc>=0.6.0", + "cython>=0.29" +] +authors = [ + {name="Edwin Tye"}, + {name="Thomas Finnie", email="thomas.finnie@ukhsa.gov.uk"}, + {name="Hannah Williams"}, + {name="Jonty Carruthers"}, + {name="Martin Grunnill"}, + {name="Joe Gibson", email="joseph.gibson@ukhsa.gov.uk"} +] + +description = "ODE modeling in Python." +readme = "README.md" +requires-python = ">=3.8" + + +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GPL2", + "Operating System :: OS Independent", +] + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.setuptools.dynamic] +# version = {attr = "0.1.8a"} # TODO: change to git tag +readme = {file = ["README.rst"]} + +[project.urls] +Homepage = "http://ukhsa-collaboration.github.io/pygom/md/intro.html" +Issues = "https://github.com/ukhsa-collaboration/pygom/issues" diff --git a/setup.py b/setup.py index 284ceee0..cf81d157 100644 --- a/setup.py +++ b/setup.py @@ -1,108 +1,21 @@ #!/bin/env python -""" -@author: Edwin Tye (Edwin.Tye@phe.gov.uk) -""" -import re -import subprocess -from setuptools import setup -from setuptools.extension import Extension - -try: - import numpy -except ImportError: - raise ImportError('numpy needs to be installed before PyGOM can be ' - 'installed. Try installing with "pip install numpy" ' - 'before installing PyGOM.') - -## For the cython parts ### -try: - from Cython.Distutils import build_ext -except ImportError: - use_cython = False -else: - use_cython = True - -cmdclass = { } -ext_modules = [ ] - -#For this to work the .c files are not include in GIT except in the release -#release branch (the c files would be created using python setup.py sdist) -if use_cython: - ext_modules += [ - Extension("pygom.model._tau_leap", - ["pygom/model/_tau_leap.pyx"], - include_dirs=[numpy.get_include()], - extra_compile_args=['-std=c99'], +from setuptools import setup, Extension +from Cython.Build import cythonize +from Cython.Compiler import Options +import numpy + +# Options for the compiled modules +Options.docstrings = True +Options.annotate = False + +extensions = [ + Extension("pygom.model._tau_leap", + ["src/pygom/model/_tau_leap.pyx"], + include_dirs=[numpy.get_include()], + extra_compile_args=['-std=c99'], # extra_compile_args=['-fopenmp'], # extra_link_args=['-fopenmp']), -) - ] - cmdclass.update({'build_ext': build_ext}) -else: -# raise ImportError('You will need Cython installed to create' -# 'the c extensions. Try installing with' -# '"pip install cython" before installing PyGOM.') - ext_modules += [ - Extension("pygom.model._tau_leap", - ["pygom/model/_tau_leap.c"], - include_dirs=[numpy.get_include()], - extra_compile_args=['-std=c99'], -# extra_compile_args=['-fopenmp'], -# extra_link_args=['-fopenmp']), -) - ] -package_data = { - 'pygom.data': ['eg1.json'],# An example epijson file - } - -# read the requirements file and have use that to populate install_requires -requires = open("requirements.txt").read().strip().split("\n") -install_requires = [] -extras_require = {} -for r in requires: - if ";" in r: - # requirements.txt conditional dependencies need to be reformatted for wheels - # to the form: `'[extra_name]:condition' : ['requirements']` - req, cond = r.split(";", 1) - cond = ":" + cond - cond_reqs = extras_require.setdefault(cond, []) - cond_reqs.append(req) - else: - install_requires.append(r) - -with open('README.md', 'r') as f: - readme = f.read() - -setup_requires = [ - 'setuptools-scm>=3.2.0', - 'setuptools_scm_git_archive', - 'numpy>=2.0.0' - ] + ) +] -setup( - name='pygom', - use_scm_version=True, - description='ODE modeling in Python', - long_description=readme, - long_description_content_type='text/x-rst', - license="GPL2", - url='https://github.com/PublicHealthEngland/pygom', - author="Thomas Finnie", - author_email="Thomas.Finnie@phe.gov.uk", - packages=[ - 'pygom', - 'pygom.model', - 'pygom.model.ode_utils', - 'pygom.loss', - 'pygom.utilR' - ], - package_data=package_data, - include_package_data=True, - cmdclass=cmdclass, - ext_modules=ext_modules, - install_requires=install_requires, - extras_require=extras_require, - setup_requires=setup_requires, - test_suite='tests', - scripts=[] - ) +setup(ext_modules=cythonize(extensions, compiler_directives={"language_level": 3, "profile": False})) diff --git a/pygom/__init__.py b/src/pygom/__init__.py similarity index 100% rename from pygom/__init__.py rename to src/pygom/__init__.py diff --git a/pygom/approximate_bayesian_computation/__init__.py b/src/pygom/approximate_bayesian_computation/__init__.py similarity index 100% rename from pygom/approximate_bayesian_computation/__init__.py rename to src/pygom/approximate_bayesian_computation/__init__.py diff --git a/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py b/src/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py similarity index 100% rename from pygom/approximate_bayesian_computation/approximate_bayesian_computation.py rename to src/pygom/approximate_bayesian_computation/approximate_bayesian_computation.py diff --git a/pygom/data/eg1.json b/src/pygom/data/eg1.json similarity index 100% rename from pygom/data/eg1.json rename to src/pygom/data/eg1.json diff --git a/pygom/loss/.gitignore b/src/pygom/loss/.gitignore similarity index 100% rename from pygom/loss/.gitignore rename to src/pygom/loss/.gitignore diff --git a/pygom/loss/__init__.py b/src/pygom/loss/__init__.py similarity index 100% rename from pygom/loss/__init__.py rename to src/pygom/loss/__init__.py diff --git a/pygom/loss/base_loss.py b/src/pygom/loss/base_loss.py similarity index 100% rename from pygom/loss/base_loss.py rename to src/pygom/loss/base_loss.py diff --git a/pygom/loss/confidence_interval.py b/src/pygom/loss/confidence_interval.py similarity index 100% rename from pygom/loss/confidence_interval.py rename to src/pygom/loss/confidence_interval.py diff --git a/pygom/loss/epijson_loss.py b/src/pygom/loss/epijson_loss.py similarity index 100% rename from pygom/loss/epijson_loss.py rename to src/pygom/loss/epijson_loss.py diff --git a/pygom/loss/get_init.py b/src/pygom/loss/get_init.py similarity index 100% rename from pygom/loss/get_init.py rename to src/pygom/loss/get_init.py diff --git a/pygom/loss/loss_type.py b/src/pygom/loss/loss_type.py similarity index 100% rename from pygom/loss/loss_type.py rename to src/pygom/loss/loss_type.py diff --git a/pygom/loss/ode_loss.py b/src/pygom/loss/ode_loss.py similarity index 100% rename from pygom/loss/ode_loss.py rename to src/pygom/loss/ode_loss.py diff --git a/pygom/loss/read_epijson.py b/src/pygom/loss/read_epijson.py similarity index 100% rename from pygom/loss/read_epijson.py rename to src/pygom/loss/read_epijson.py diff --git a/pygom/model/__init__.py b/src/pygom/model/__init__.py similarity index 100% rename from pygom/model/__init__.py rename to src/pygom/model/__init__.py diff --git a/pygom/model/_model_errors.py b/src/pygom/model/_model_errors.py similarity index 100% rename from pygom/model/_model_errors.py rename to src/pygom/model/_model_errors.py diff --git a/pygom/model/_model_verification.py b/src/pygom/model/_model_verification.py similarity index 100% rename from pygom/model/_model_verification.py rename to src/pygom/model/_model_verification.py diff --git a/pygom/model/_ode_composition.py b/src/pygom/model/_ode_composition.py similarity index 100% rename from pygom/model/_ode_composition.py rename to src/pygom/model/_ode_composition.py diff --git a/pygom/model/_tau_leap.pyx b/src/pygom/model/_tau_leap.pyx similarity index 100% rename from pygom/model/_tau_leap.pyx rename to src/pygom/model/_tau_leap.pyx diff --git a/pygom/model/_transition_graph.py b/src/pygom/model/_transition_graph.py similarity index 100% rename from pygom/model/_transition_graph.py rename to src/pygom/model/_transition_graph.py diff --git a/pygom/model/base_ode_model.py b/src/pygom/model/base_ode_model.py similarity index 100% rename from pygom/model/base_ode_model.py rename to src/pygom/model/base_ode_model.py diff --git a/pygom/model/common_models.py b/src/pygom/model/common_models.py similarity index 100% rename from pygom/model/common_models.py rename to src/pygom/model/common_models.py diff --git a/pygom/model/deterministic.py b/src/pygom/model/deterministic.py similarity index 100% rename from pygom/model/deterministic.py rename to src/pygom/model/deterministic.py diff --git a/pygom/model/epi_analysis.py b/src/pygom/model/epi_analysis.py similarity index 100% rename from pygom/model/epi_analysis.py rename to src/pygom/model/epi_analysis.py diff --git a/pygom/model/ode_utils/__init__.py b/src/pygom/model/ode_utils/__init__.py similarity index 100% rename from pygom/model/ode_utils/__init__.py rename to src/pygom/model/ode_utils/__init__.py diff --git a/pygom/model/ode_utils/checks_and_conversions.py b/src/pygom/model/ode_utils/checks_and_conversions.py similarity index 100% rename from pygom/model/ode_utils/checks_and_conversions.py rename to src/pygom/model/ode_utils/checks_and_conversions.py diff --git a/pygom/model/ode_utils/compile_canary.py b/src/pygom/model/ode_utils/compile_canary.py similarity index 100% rename from pygom/model/ode_utils/compile_canary.py rename to src/pygom/model/ode_utils/compile_canary.py diff --git a/pygom/model/ode_utils/plot_det.py b/src/pygom/model/ode_utils/plot_det.py similarity index 100% rename from pygom/model/ode_utils/plot_det.py rename to src/pygom/model/ode_utils/plot_det.py diff --git a/pygom/model/ode_utils/plot_stoc.py b/src/pygom/model/ode_utils/plot_stoc.py similarity index 100% rename from pygom/model/ode_utils/plot_stoc.py rename to src/pygom/model/ode_utils/plot_stoc.py diff --git a/pygom/model/ode_variable.py b/src/pygom/model/ode_variable.py similarity index 100% rename from pygom/model/ode_variable.py rename to src/pygom/model/ode_variable.py diff --git a/pygom/model/simulate.py b/src/pygom/model/simulate.py similarity index 100% rename from pygom/model/simulate.py rename to src/pygom/model/simulate.py diff --git a/pygom/model/stochastic_simulation.py b/src/pygom/model/stochastic_simulation.py similarity index 100% rename from pygom/model/stochastic_simulation.py rename to src/pygom/model/stochastic_simulation.py diff --git a/pygom/model/transition.py b/src/pygom/model/transition.py similarity index 100% rename from pygom/model/transition.py rename to src/pygom/model/transition.py diff --git a/pygom/utilR/__init__.py b/src/pygom/utilR/__init__.py similarity index 100% rename from pygom/utilR/__init__.py rename to src/pygom/utilR/__init__.py diff --git a/pygom/utilR/distn.py b/src/pygom/utilR/distn.py similarity index 100% rename from pygom/utilR/distn.py rename to src/pygom/utilR/distn.py From 550e5a2f80c98c147201ced69e564db4c2c1b849 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 23:22:25 +0100 Subject: [PATCH 066/123] Additional tidying and ensuring git is used for versions again. --- MANIFEST.in | 1 - pyproject.toml | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) delete mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 80f66d3c..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -include data/*.json diff --git a/pyproject.toml b/pyproject.toml index 4366a52e..eea6030d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,6 @@ [build-system] -requires = ["setuptools-scm>=3.2.0", +requires = ["setuptools>=64", + "setuptools_scm>=8" "setuptools_scm_git_archive", "numpy>=2.0.0", "cython>=0.29", @@ -9,8 +10,7 @@ build-backend = "setuptools.build_meta" [project] name = "pygom" -#dynamic = ["version"] -version = "0.1.8a" +dynamic = ["version"] dependencies = [ "dask[complete]>=0.13.0", "graphviz>=0.4.9", @@ -43,11 +43,13 @@ classifiers = [ "Operating System :: OS Independent", ] +[tool.setuptools_scm] +version_file = "pygom/_version.py" + [tool.setuptools.packages.find] where = ["src"] [tool.setuptools.dynamic] -# version = {attr = "0.1.8a"} # TODO: change to git tag readme = {file = ["README.rst"]} [project.urls] From 58e7dc14464f5e7019afc181cce55d619765010c Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 23:24:34 +0100 Subject: [PATCH 067/123] Missing a comma --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index eea6030d..eec4aac9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] requires = ["setuptools>=64", - "setuptools_scm>=8" + "setuptools_scm>=8", "setuptools_scm_git_archive", "numpy>=2.0.0", "cython>=0.29", From ec55fa5c9fafd74f74627321bf36432bb439668c Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 23:29:30 +0100 Subject: [PATCH 068/123] Change the command to run the test suite. --- .github/workflows/main.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0360dff0..67fa6a58 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -73,22 +73,17 @@ jobs: Get-Command rc.exe | Format-Table -AutoSize echo "::add-path::$(Get-Command rc.exe | Split-Path)" - - name: Install dependencies + - name: Install pip run: | python -m pip install --upgrade pip - pip install -r requirements.txt - - name: Build and install package for c files - run: | - python setup.py build - python setup.py install - name: Fix matplotlib backend for MacOS if: startsWith(runner.os, 'macOS') run: | mkdir ~/.matplotlib echo "backend: TkAgg" >> ~/.matplotlib/matplotlibrc - - name: Test and coverage - run: python setup.py test + - name: Run tests + run: python -m unittest discover --start-directory tests build_wheels: name: Build wheels on ${{ matrix.os }} From 5992ea587be204d0ac5bec83906d789fa194c6ed Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 23:31:54 +0100 Subject: [PATCH 069/123] Make sure we have PyGOM installed. --- .github/workflows/main.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 67fa6a58..938ad280 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -82,6 +82,11 @@ jobs: run: | mkdir ~/.matplotlib echo "backend: TkAgg" >> ~/.matplotlib/matplotlibrc + + - name: install PyGOM + run | + pip install . + - name: Run tests run: python -m unittest discover --start-directory tests From dc76233be0449c6ab46ae03b17b4632b6ebd32b6 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 23:40:47 +0100 Subject: [PATCH 070/123] Fix the YML file --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 938ad280..cde60fc2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -84,7 +84,7 @@ jobs: echo "backend: TkAgg" >> ~/.matplotlib/matplotlibrc - name: install PyGOM - run | + run: | pip install . - name: Run tests From e12fd2580ef04f9e0d1bd710795068ccb984c17a Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 23:44:04 +0100 Subject: [PATCH 071/123] Set the anylinux base and only build wheels for 3.9 up --- pyproject.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index eec4aac9..af3c61ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,3 +55,12 @@ readme = {file = ["README.rst"]} [project.urls] Homepage = "http://ukhsa-collaboration.github.io/pygom/md/intro.html" Issues = "https://github.com/ukhsa-collaboration/pygom/issues" + +# Options for wheel building with cibuildwheel +[tool.cibuildwheel] +# Normal options, etc. +manylinux-x86_64-image = "manylinux2014" + +[[tool.cibuildwheel.overrides]] +select = "cp3{9}-*" +manylinux-x86_64-image = "manylinux2010" From 8076f9fd1caba083462269ac2395b2d336744d05 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 23:49:00 +0100 Subject: [PATCH 072/123] Restrict the python versions the wheels are built for. --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cde60fc2..da4eca26 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -96,6 +96,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] #, macos-13, macos-14] + python-version: ["3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v4 From add68c3305441a666d08a6b4a0c8b49f56b49d7c Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 23:51:40 +0100 Subject: [PATCH 073/123] Remove the version file option. --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index af3c61ff..adac022a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,8 +43,8 @@ classifiers = [ "Operating System :: OS Independent", ] -[tool.setuptools_scm] -version_file = "pygom/_version.py" +#[tool.setuptools_scm] +#version_file = "pygom/_version.py" [tool.setuptools.packages.find] where = ["src"] From 9d3accc72c46f664000924012014fcb7a0e0a357 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Fri, 2 Aug 2024 23:57:37 +0100 Subject: [PATCH 074/123] Can we get away with a lower version of numpy (so we can build anylinux wheels)? --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index adac022a..1f86b582 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ requires = ["setuptools>=64", "setuptools_scm>=8", "setuptools_scm_git_archive", - "numpy>=2.0.0", + "numpy>=1.24.4", "cython>=0.29", "setuptools>=61.0", "scipy>=1.12.0"] @@ -62,5 +62,5 @@ Issues = "https://github.com/ukhsa-collaboration/pygom/issues" manylinux-x86_64-image = "manylinux2014" [[tool.cibuildwheel.overrides]] -select = "cp3{9}-*" +select = "cp3{8,9}-*" manylinux-x86_64-image = "manylinux2010" From 77e7c0c58c039289c4f7b97598b24baaf8df3aba Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 00:01:21 +0100 Subject: [PATCH 075/123] Can we get away with a lower version of scipy (so we can build anylinux wheels)? --- .github/workflows/main.yml | 1 - pyproject.toml | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index da4eca26..cde60fc2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -96,7 +96,6 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] #, macos-13, macos-14] - python-version: ["3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v4 diff --git a/pyproject.toml b/pyproject.toml index 1f86b582..ff43a45e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ requires = ["setuptools>=64", "numpy>=1.24.4", "cython>=0.29", "setuptools>=61.0", - "scipy>=1.12.0"] + "scipy>=1.10.1"] build-backend = "setuptools.build_meta" [project] @@ -15,10 +15,10 @@ dependencies = [ "dask[complete]>=0.13.0", "graphviz>=0.4.9", "matplotlib>=1.0.0", - "numpy>=2.0.0", + "numpy>=1.24.4", "pandas>=2.2.2", "python-dateutil>=2.0.0", - "scipy>=1.4.1", + "scipy>=1.10.1", "sympy>=1.0.0", "numpydoc>=0.6.0", "cython>=0.29" From 904398124a05775713e61d1abe2d57b7f09c2ae4 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 00:22:59 +0100 Subject: [PATCH 076/123] Windows only wheels? --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cde60fc2..2097e10a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -95,7 +95,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, windows-latest] #, macos-13, macos-14] + os: [windows-latest] #ubuntu-latest#, macos-13, macos-14] steps: - uses: actions/checkout@v4 From b729579655a5fe3cf1e18e64d0d0cf70fe60537d Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 00:34:18 +0100 Subject: [PATCH 077/123] Simplified CI, omitted wheel building. --- .github/workflows/main.yml | 85 ++++++++++++++------------------------ 1 file changed, 31 insertions(+), 54 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2097e10a..e29df470 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -56,33 +56,10 @@ jobs: - name: Check python version run: python -c "import sys; print(sys.version)" - - name: RC.exe for Windows - if: startsWith(runner.os, 'Windows') - run: | - function Invoke-VSDevEnvironment { - $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" - $installationPath = & $vswhere -prerelease -legacy -latest -property installationPath - $Command = Join-Path $installationPath "Common7\Tools\vsdevcmd.bat" - & "${env:COMSPEC}" /s /c "`"$Command`" -no_logo && set" | Foreach-Object { - if ($_ -match '^([^=]+)=(.*)') { - [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2]) - } - } - } - Invoke-VSDevEnvironment - Get-Command rc.exe | Format-Table -AutoSize - echo "::add-path::$(Get-Command rc.exe | Split-Path)" - - name: Install pip run: | python -m pip install --upgrade pip - - name: Fix matplotlib backend for MacOS - if: startsWith(runner.os, 'macOS') - run: | - mkdir ~/.matplotlib - echo "backend: TkAgg" >> ~/.matplotlib/matplotlibrc - - name: install PyGOM run: | pip install . @@ -90,34 +67,34 @@ jobs: - name: Run tests run: python -m unittest discover --start-directory tests - build_wheels: - name: Build wheels on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [windows-latest] #ubuntu-latest#, macos-13, macos-14] - - steps: - - uses: actions/checkout@v4 - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - # Used to host cibuildwheel - - uses: actions/setup-python@v5 - - - name: Install cibuildwheel - run: python -m pip install cibuildwheel==2.19.2 - - - name: Build wheels - run: python -m cibuildwheel --output-dir wheelhouse - # to supply options, put them in 'env', like: - # env: - # CIBW_SOME_OPTION: value - - - uses: actions/upload-artifact@v4 - with: - name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} - path: ./wheelhouse/*.whl +# build_wheels: +# name: Build wheels on ${{ matrix.os }} +# runs-on: ${{ matrix.os }} +# strategy: +# matrix: +# os: [windows-latest] #ubuntu-latest#, macos-13, macos-14] +# +# steps: +# - uses: actions/checkout@v4 +# +# - name: Install dependencies +# run: | +# python -m pip install --upgrade pip +# pip install -r requirements.txt +# +# # Used to host cibuildwheel +# - uses: actions/setup-python@v5 +# +# - name: Install cibuildwheel +# run: python -m pip install cibuildwheel==2.19.2 +# +# - name: Build wheels +# run: python -m cibuildwheel --output-dir wheelhouse +# # to supply options, put them in 'env', like: +# # env: +# # CIBW_SOME_OPTION: value +# +# - uses: actions/upload-artifact@v4 +# with: +# name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} +# path: ./wheelhouse/*.whl From bb39b980cd42a6d18ad1becbf3c3389eb802432c Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 07:23:34 +0100 Subject: [PATCH 078/123] Retry manylinux wheel building --- .github/workflows/main.yml | 62 +++++++++++++++++++------------------- pyproject.toml | 6 ++++ 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e29df470..2583132d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -67,34 +67,34 @@ jobs: - name: Run tests run: python -m unittest discover --start-directory tests -# build_wheels: -# name: Build wheels on ${{ matrix.os }} -# runs-on: ${{ matrix.os }} -# strategy: -# matrix: -# os: [windows-latest] #ubuntu-latest#, macos-13, macos-14] -# -# steps: -# - uses: actions/checkout@v4 -# -# - name: Install dependencies -# run: | -# python -m pip install --upgrade pip -# pip install -r requirements.txt -# -# # Used to host cibuildwheel -# - uses: actions/setup-python@v5 -# -# - name: Install cibuildwheel -# run: python -m pip install cibuildwheel==2.19.2 -# -# - name: Build wheels -# run: python -m cibuildwheel --output-dir wheelhouse -# # to supply options, put them in 'env', like: -# # env: -# # CIBW_SOME_OPTION: value -# -# - uses: actions/upload-artifact@v4 -# with: -# name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} -# path: ./wheelhouse/*.whl + build_wheels: + name: Build wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] #windows-latest], macos-13, macos-14] + + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + # Used to host cibuildwheel + - uses: actions/setup-python@v5 + + - name: Install cibuildwheel + run: python -m pip install cibuildwheel==2.19.2 + + - name: Build wheels + run: python -m cibuildwheel --output-dir wheelhouse + # to supply options, put them in 'env', like: + # env: + # CIBW_SOME_OPTION: value + + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl diff --git a/pyproject.toml b/pyproject.toml index ff43a45e..19d78f87 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,6 +61,12 @@ Issues = "https://github.com/ukhsa-collaboration/pygom/issues" # Normal options, etc. manylinux-x86_64-image = "manylinux2014" +# Install blas & lapack on x86_64 +[tool.cibuildwheel.linux] +before-all = "yum -y update && yum -y install blas-devel lapack-devel" +before-test = "yum -y update && yum -y install openblas-devel lapack" + + [[tool.cibuildwheel.overrides]] select = "cp3{8,9}-*" manylinux-x86_64-image = "manylinux2010" From 8e84a6762c75db5d8b025394601527a7d701d991 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 07:35:40 +0100 Subject: [PATCH 079/123] Use openblas? --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 19d78f87..cb659811 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,8 +63,8 @@ manylinux-x86_64-image = "manylinux2014" # Install blas & lapack on x86_64 [tool.cibuildwheel.linux] -before-all = "yum -y update && yum -y install blas-devel lapack-devel" -before-test = "yum -y update && yum -y install openblas-devel lapack" +before-all = "yum -y update && yum -y install openblas-devel" +# before-test = "yum -y update && yum -y install openblas-devel lapack" [[tool.cibuildwheel.overrides]] From f85908d5a73b062c640c4f0bb71b159159866bcb Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 07:49:21 +0100 Subject: [PATCH 080/123] Do we need the runtimes too? --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cb659811..b02fcf44 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,10 +61,10 @@ Issues = "https://github.com/ukhsa-collaboration/pygom/issues" # Normal options, etc. manylinux-x86_64-image = "manylinux2014" -# Install blas & lapack on x86_64 +# Install blas on linux [tool.cibuildwheel.linux] -before-all = "yum -y update && yum -y install openblas-devel" -# before-test = "yum -y update && yum -y install openblas-devel lapack" +before-all = "yum -y update && yum -y install openblas-devel openblas" +before-test = "yum -y update && yum -y install openblas-devel openblas" [[tool.cibuildwheel.overrides]] From 53d6ed7cfd4c4cc74447384c255e5a2bc8e2d8ae Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 07:55:36 +0100 Subject: [PATCH 081/123] Try to only build amd64 wheels on Windows? --- .github/workflows/main.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2583132d..fab92235 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -72,7 +72,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest] #windows-latest], macos-13, macos-14] + os: [ubuntu-latest,windows-latest]#, macos-13, macos-14] steps: - uses: actions/checkout@v4 @@ -90,9 +90,8 @@ jobs: - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse - # to supply options, put them in 'env', like: - # env: - # CIBW_SOME_OPTION: value + env: + CIBW_SKIP: win32 - uses: actions/upload-artifact@v4 with: From ad99e3d8d979f59baacbdab3588ffb7f4479d3cd Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 08:13:11 +0100 Subject: [PATCH 082/123] Be more specific about what versons on what OS --- .github/workflows/main.yml | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fab92235..0503461b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -71,8 +71,44 @@ jobs: name: Build wheels on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: + # Ensure that a wheel builder finishes even if another fails + fail-fast: false matrix: - os: [ubuntu-latest,windows-latest]#, macos-13, macos-14] + include: + # Window 64 bit + - os: windows-latest + python: 39 + platform_id: win_amd64 + - os: windows-latest + python: 310 + platform_id: win_amd64 + - os: windows-latest + python: 311 + platform_id: win_amd64 + - os: windows-latest + python: 312 + platform_id: win_amd64 + + # Linux 64 bit manylinux2014 + - os: ubuntu-latest + python: 39 + platform_id: manylinux_x86_64 + manylinux_image: manylinux2014 + + # NumPy on Python 3.10 only supports 64bit and is only available with manylinux2014 + - os: ubuntu-latest + python: 310 + platform_id: manylinux_x86_64 + manylinux_image: manylinux2014 + + - os: ubuntu-latest + python: 311 + platform_id: manylinux_x86_64 + manylinux_image: manylinux2014 + - os: ubuntu-latest + python: 312 + platform_id: manylinux_x86_64 + manylinux_image: manylinux2014 steps: - uses: actions/checkout@v4 From 26081799d0a4605d051b81959fabec9830eafeae Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 08:34:43 +0100 Subject: [PATCH 083/123] Try a differnt way to provide blas --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b02fcf44..271d346c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,9 +63,9 @@ manylinux-x86_64-image = "manylinux2014" # Install blas on linux [tool.cibuildwheel.linux] -before-all = "yum -y update && yum -y install openblas-devel openblas" -before-test = "yum -y update && yum -y install openblas-devel openblas" - +#before-all = "yum -y update && yum -y install openblas-devel openblas" +#before-test = "yum -y update && yum -y install openblas-devel openblas" +before-all = "python -m pip install -r requirements/openblas.txt && python -c "import scipy_openblas32; print(scipy_openblas32.get_pkg_config())" > {project}/scipy-openblas.pc" [[tool.cibuildwheel.overrides]] select = "cp3{8,9}-*" From 8474c337c9af522364b4e9d00558eddb59a04b65 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 08:39:48 +0100 Subject: [PATCH 084/123] Wilth better escaping --- pyproject.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 271d346c..ab17fc16 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,7 +65,10 @@ manylinux-x86_64-image = "manylinux2014" [tool.cibuildwheel.linux] #before-all = "yum -y update && yum -y install openblas-devel openblas" #before-test = "yum -y update && yum -y install openblas-devel openblas" -before-all = "python -m pip install -r requirements/openblas.txt && python -c "import scipy_openblas32; print(scipy_openblas32.get_pkg_config())" > {project}/scipy-openblas.pc" +before-all = """ +python -m pip install -r requirements/openblas.txt +python -c "import scipy_openblas32; print(scipy_openblas32.get_pkg_config())" > {project}/scipy-openblas.pc +""" [[tool.cibuildwheel.overrides]] select = "cp3{8,9}-*" From f88369f94cb5e341a2cae22a404870673cf980b0 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 08:42:45 +0100 Subject: [PATCH 085/123] Actually specify the blas version. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ab17fc16..58bfb709 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,7 +66,7 @@ manylinux-x86_64-image = "manylinux2014" #before-all = "yum -y update && yum -y install openblas-devel openblas" #before-test = "yum -y update && yum -y install openblas-devel openblas" before-all = """ -python -m pip install -r requirements/openblas.txt +python -m pip install scipy-openblas32==0.3.27.63.1 python -c "import scipy_openblas32; print(scipy_openblas32.get_pkg_config())" > {project}/scipy-openblas.pc """ From ab78470095fe6416805b683140bbed57df3591a1 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 09:05:18 +0100 Subject: [PATCH 086/123] Now install our own BLAS --- pyproject.toml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 58bfb709..c7792a09 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,12 +63,18 @@ manylinux-x86_64-image = "manylinux2014" # Install blas on linux [tool.cibuildwheel.linux] -#before-all = "yum -y update && yum -y install openblas-devel openblas" -#before-test = "yum -y update && yum -y install openblas-devel openblas" before-all = """ -python -m pip install scipy-openblas32==0.3.27.63.1 -python -c "import scipy_openblas32; print(scipy_openblas32.get_pkg_config())" > {project}/scipy-openblas.pc +# Note we can't just use the version from yum as it doesn't have a pkgconfig +git clone https://github.com/xianyi/OpenBLAS.git +cd OpenBLAS +make -j8 +make PREFIX=/usr/local/OpenBLAS install +export PKG_CONFIG_PATH=/usr/local/OpenBLAS/lib/pkgconfig """ +# +# "yum -y update && yum -y install openblas-devel openblas" +#before-test = "yum -y update && yum -y install openblas-devel openblas" + [[tool.cibuildwheel.overrides]] select = "cp3{8,9}-*" From 2670b05386eaab91cdfa8bd2092b6c1ad35515fa Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 09:35:26 +0100 Subject: [PATCH 087/123] Does it work with a pip install? --- pyproject.toml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c7792a09..057ef1eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,12 +64,13 @@ manylinux-x86_64-image = "manylinux2014" # Install blas on linux [tool.cibuildwheel.linux] before-all = """ +pip install scipy # Note we can't just use the version from yum as it doesn't have a pkgconfig -git clone https://github.com/xianyi/OpenBLAS.git -cd OpenBLAS -make -j8 -make PREFIX=/usr/local/OpenBLAS install -export PKG_CONFIG_PATH=/usr/local/OpenBLAS/lib/pkgconfig +#git clone https://github.com/xianyi/OpenBLAS.git +#cd OpenBLAS +#make -j8 +#make PREFIX=/usr/local/OpenBLAS install +#export PKG_CONFIG_PATH=/usr/local/OpenBLAS/lib/pkgconfig """ # # "yum -y update && yum -y install openblas-devel openblas" From 76d62dfcc3110e700920c9064400083d1c2340b4 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 09:52:35 +0100 Subject: [PATCH 088/123] make pip perfer a binary --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 057ef1eb..7783c328 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,8 @@ manylinux-x86_64-image = "manylinux2014" # Install blas on linux [tool.cibuildwheel.linux] before-all = """ -pip install scipy +python -m pip install --upgrade pip +pip install --prefer-binary scipy # Note we can't just use the version from yum as it doesn't have a pkgconfig #git clone https://github.com/xianyi/OpenBLAS.git #cd OpenBLAS From f1995c46860383e5039a84f1b1646f56ad94dcea Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 10:03:22 +0100 Subject: [PATCH 089/123] Is this because we have too high a scipy version specified? --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7783c328..53e48d06 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ dependencies = [ "numpy>=1.24.4", "pandas>=2.2.2", "python-dateutil>=2.0.0", - "scipy>=1.10.1", + "scipy>=1.7.1", "sympy>=1.0.0", "numpydoc>=0.6.0", "cython>=0.29" @@ -64,8 +64,8 @@ manylinux-x86_64-image = "manylinux2014" # Install blas on linux [tool.cibuildwheel.linux] before-all = """ -python -m pip install --upgrade pip -pip install --prefer-binary scipy +#python -m pip install --upgrade pip +#pip install --prefer-binary scipy # Note we can't just use the version from yum as it doesn't have a pkgconfig #git clone https://github.com/xianyi/OpenBLAS.git #cd OpenBLAS From f53b48a36cb0b48d95cf543722f9bd22cf0190fe Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 10:06:31 +0100 Subject: [PATCH 090/123] Need to specify in the build section too. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 53e48d06..4ee18bc1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ requires = ["setuptools>=64", "numpy>=1.24.4", "cython>=0.29", "setuptools>=61.0", - "scipy>=1.10.1"] + "scipy>=1.7.1"] build-backend = "setuptools.build_meta" [project] From c59f5b048f2851b4ae1182f6db085e1be7e12009 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 10:29:39 +0100 Subject: [PATCH 091/123] Revert to pkgconfig --- pyproject.toml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4ee18bc1..94de8893 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ requires = ["setuptools>=64", "numpy>=1.24.4", "cython>=0.29", "setuptools>=61.0", - "scipy>=1.7.1"] + "scipy>=1.10.1"] build-backend = "setuptools.build_meta" [project] @@ -18,7 +18,7 @@ dependencies = [ "numpy>=1.24.4", "pandas>=2.2.2", "python-dateutil>=2.0.0", - "scipy>=1.7.1", + "scipy>=1.10.1", "sympy>=1.0.0", "numpydoc>=0.6.0", "cython>=0.29" @@ -64,6 +64,7 @@ manylinux-x86_64-image = "manylinux2014" # Install blas on linux [tool.cibuildwheel.linux] before-all = """ +yum -y update && yum -y install pkgconfig openblas-devel openblas #python -m pip install --upgrade pip #pip install --prefer-binary scipy # Note we can't just use the version from yum as it doesn't have a pkgconfig @@ -74,7 +75,7 @@ before-all = """ #export PKG_CONFIG_PATH=/usr/local/OpenBLAS/lib/pkgconfig """ # -# "yum -y update && yum -y install openblas-devel openblas" +# "yum -y update && yum -y install pkgconfig openblas-devel openblas" #before-test = "yum -y update && yum -y install openblas-devel openblas" From d9d12c68f742d63dc37bb9c68c329c3a65d40809 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 10:34:23 +0100 Subject: [PATCH 092/123] Set a version of scipy that manylinux wheels exist for. --- pyproject.toml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 94de8893..47cac0c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ requires = ["setuptools>=64", "numpy>=1.24.4", "cython>=0.29", "setuptools>=61.0", - "scipy>=1.10.1"] + "scipy>=1.14.0"] build-backend = "setuptools.build_meta" [project] @@ -18,7 +18,7 @@ dependencies = [ "numpy>=1.24.4", "pandas>=2.2.2", "python-dateutil>=2.0.0", - "scipy>=1.10.1", + "scipy>=1.14.0", "sympy>=1.0.0", "numpydoc>=0.6.0", "cython>=0.29" @@ -64,9 +64,10 @@ manylinux-x86_64-image = "manylinux2014" # Install blas on linux [tool.cibuildwheel.linux] before-all = """ -yum -y update && yum -y install pkgconfig openblas-devel openblas +#yum -y update && yum -y install pkgconfig openblas-devel openblas + #python -m pip install --upgrade pip -#pip install --prefer-binary scipy +pip install --prefer-binary scipy>=1.14.0 # Note we can't just use the version from yum as it doesn't have a pkgconfig #git clone https://github.com/xianyi/OpenBLAS.git #cd OpenBLAS From a5a1619a7dfca18b0e739e2119ec75f99ee2a30a Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 10:48:41 +0100 Subject: [PATCH 093/123] Can we get a scipy wheel inside the container? --- pyproject.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 47cac0c2..c8d11d23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ requires = ["setuptools>=64", "numpy>=1.24.4", "cython>=0.29", "setuptools>=61.0", - "scipy>=1.14.0"] + "scipy>=1.10.1"] build-backend = "setuptools.build_meta" [project] @@ -18,7 +18,7 @@ dependencies = [ "numpy>=1.24.4", "pandas>=2.2.2", "python-dateutil>=2.0.0", - "scipy>=1.14.0", + "scipy>=1.10.1", "sympy>=1.0.0", "numpydoc>=0.6.0", "cython>=0.29" @@ -66,10 +66,10 @@ manylinux-x86_64-image = "manylinux2014" before-all = """ #yum -y update && yum -y install pkgconfig openblas-devel openblas -#python -m pip install --upgrade pip -pip install --prefer-binary scipy>=1.14.0 +python -m pip install --upgrade pip +pip install --prefer-binary scipy>=1.10.1 # Note we can't just use the version from yum as it doesn't have a pkgconfig -#git clone https://github.com/xianyi/OpenBLAS.git +#git clone https://github.com/OpenMathLib/OpenBLAS.git #cd OpenBLAS #make -j8 #make PREFIX=/usr/local/OpenBLAS install From 49ed7631b7d2fb5f53a196a05e4f32858bdf24e3 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 10:52:13 +0100 Subject: [PATCH 094/123] Do we only get one line? --- pyproject.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c8d11d23..f4824de8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,8 +66,7 @@ manylinux-x86_64-image = "manylinux2014" before-all = """ #yum -y update && yum -y install pkgconfig openblas-devel openblas -python -m pip install --upgrade pip -pip install --prefer-binary scipy>=1.10.1 +python -m pip install --upgrade pip && pip install --prefer-binary scipy>=1.10.1 # Note we can't just use the version from yum as it doesn't have a pkgconfig #git clone https://github.com/OpenMathLib/OpenBLAS.git #cd OpenBLAS From dc8c20ce2c1ab8cbd5298a6e2ef7c223c0a01672 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 10:54:31 +0100 Subject: [PATCH 095/123] With pip only --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f4824de8..8aa58850 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,7 +66,7 @@ manylinux-x86_64-image = "manylinux2014" before-all = """ #yum -y update && yum -y install pkgconfig openblas-devel openblas -python -m pip install --upgrade pip && pip install --prefer-binary scipy>=1.10.1 +pip install --prefer-binary scipy>=1.10.1 # Note we can't just use the version from yum as it doesn't have a pkgconfig #git clone https://github.com/OpenMathLib/OpenBLAS.git #cd OpenBLAS From f57b05287b0bd37599fb7de91cf4eb9699510a0a Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 11:12:44 +0100 Subject: [PATCH 096/123] Return to suppling our own Blas --- .github/workflows/main.yml | 6 +++--- pyproject.toml | 14 ++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0503461b..b1f2be3c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -122,12 +122,12 @@ jobs: - uses: actions/setup-python@v5 - name: Install cibuildwheel - run: python -m pip install cibuildwheel==2.19.2 + run: python -m pip install cibuildwheel>=2.19.2 - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse - env: - CIBW_SKIP: win32 + #env: + # CIBW_SKIP: win32 - uses: actions/upload-artifact@v4 with: diff --git a/pyproject.toml b/pyproject.toml index 8aa58850..ce6ac057 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,13 +66,15 @@ manylinux-x86_64-image = "manylinux2014" before-all = """ #yum -y update && yum -y install pkgconfig openblas-devel openblas -pip install --prefer-binary scipy>=1.10.1 +#python -m pip install --upgrade pip +#pip install --prefer-binary scipy>=1.10.1 + # Note we can't just use the version from yum as it doesn't have a pkgconfig -#git clone https://github.com/OpenMathLib/OpenBLAS.git -#cd OpenBLAS -#make -j8 -#make PREFIX=/usr/local/OpenBLAS install -#export PKG_CONFIG_PATH=/usr/local/OpenBLAS/lib/pkgconfig +git clone https://github.com/OpenMathLib/OpenBLAS.git +cd OpenBLAS +make -j8 +make PREFIX=/usr/local/OpenBLAS install +export PKG_CONFIG_PATH=/usr/local/OpenBLAS/lib/pkgconfig """ # # "yum -y update && yum -y install pkgconfig openblas-devel openblas" From 64af40ec4a2774383f3e7198c1d488956b67db9a Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 11:19:40 +0100 Subject: [PATCH 097/123] Ensure the python versions targetted in the CI translate to CIBW --- .github/workflows/main.yml | 5 +++-- pyproject.toml | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b1f2be3c..ce8be7c4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -126,8 +126,9 @@ jobs: - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse - #env: - # CIBW_SKIP: win32 + env: + CIBW_BUILD: ${{ matrix.python[0] }}-${{ matrix.buildplat[1] }}* + CIBW_ARCHS: ${{ matrix.buildplat[2] }} - uses: actions/upload-artifact@v4 with: diff --git a/pyproject.toml b/pyproject.toml index ce6ac057..c2c2f426 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,11 +70,11 @@ before-all = """ #pip install --prefer-binary scipy>=1.10.1 # Note we can't just use the version from yum as it doesn't have a pkgconfig -git clone https://github.com/OpenMathLib/OpenBLAS.git -cd OpenBLAS -make -j8 -make PREFIX=/usr/local/OpenBLAS install -export PKG_CONFIG_PATH=/usr/local/OpenBLAS/lib/pkgconfig +#git clone https://github.com/OpenMathLib/OpenBLAS.git +#cd OpenBLAS +#make -j8 +#make PREFIX=/usr/local/OpenBLAS install +#export PKG_CONFIG_PATH=/usr/local/OpenBLAS/lib/pkgconfig """ # # "yum -y update && yum -y install pkgconfig openblas-devel openblas" From 21fa9acc571bb0c23c2cfe579ca5c07d648e9ab6 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 11:24:26 +0100 Subject: [PATCH 098/123] Correct the CI variables --- .github/workflows/main.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ce8be7c4..bc4a9d4b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,22 +91,22 @@ jobs: # Linux 64 bit manylinux2014 - os: ubuntu-latest - python: 39 + python: cp39 platform_id: manylinux_x86_64 manylinux_image: manylinux2014 # NumPy on Python 3.10 only supports 64bit and is only available with manylinux2014 - os: ubuntu-latest - python: 310 + python: cp310 platform_id: manylinux_x86_64 manylinux_image: manylinux2014 - os: ubuntu-latest - python: 311 + python: cp311 platform_id: manylinux_x86_64 manylinux_image: manylinux2014 - os: ubuntu-latest - python: 312 + python: cp312 platform_id: manylinux_x86_64 manylinux_image: manylinux2014 @@ -127,8 +127,8 @@ jobs: - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse env: - CIBW_BUILD: ${{ matrix.python[0] }}-${{ matrix.buildplat[1] }}* - CIBW_ARCHS: ${{ matrix.buildplat[2] }} + CIBW_BUILD: ${{ matrix.python }}-${{ matrix.platform_id }}* + - uses: actions/upload-artifact@v4 with: From 74c9ff0369dd84d96abb59bc84432371d643eab7 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 11:33:13 +0100 Subject: [PATCH 099/123] Drop wheel building for Python 3.9 on Linux --- .github/workflows/main.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bc4a9d4b..8dbde7af 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -89,11 +89,11 @@ jobs: python: 312 platform_id: win_amd64 - # Linux 64 bit manylinux2014 - - os: ubuntu-latest - python: cp39 - platform_id: manylinux_x86_64 - manylinux_image: manylinux2014 +# # Linux 64 bit manylinux2014 +# - os: ubuntu-latest +# python: cp39 +# platform_id: manylinux_x86_64 +# manylinux_image: manylinux2014 # NumPy on Python 3.10 only supports 64bit and is only available with manylinux2014 - os: ubuntu-latest From a58a8ed21eb9011bf7dd35f3d3878351852b8028 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 11:48:31 +0100 Subject: [PATCH 100/123] Fix the python versions for windows wheels --- .github/workflows/main.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8dbde7af..1b986dbe 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -65,7 +65,7 @@ jobs: pip install . - name: Run tests - run: python -m unittest discover --start-directory tests + run: python -m unittest discover -s {project}/tests build_wheels: name: Build wheels on ${{ matrix.os }} @@ -77,16 +77,16 @@ jobs: include: # Window 64 bit - os: windows-latest - python: 39 + python: cp39 platform_id: win_amd64 - os: windows-latest - python: 310 + python: cp310 platform_id: win_amd64 - os: windows-latest - python: 311 + python: cp311 platform_id: win_amd64 - os: windows-latest - python: 312 + python: cp312 platform_id: win_amd64 # # Linux 64 bit manylinux2014 @@ -128,6 +128,7 @@ jobs: run: python -m cibuildwheel --output-dir wheelhouse env: CIBW_BUILD: ${{ matrix.python }}-${{ matrix.platform_id }}* + CIBW_TEST_COMMAND: python -W default -m unittest discover -s {project}/tests - uses: actions/upload-artifact@v4 From 1f3e6aa914b2bb02352277b9918a6fb086f98a6e Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 11:56:44 +0100 Subject: [PATCH 101/123] A bit of testing for the wheels --- .github/workflows/main.yml | 4 ++-- pyproject.toml | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1b986dbe..790ba0cb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -65,7 +65,7 @@ jobs: pip install . - name: Run tests - run: python -m unittest discover -s {project}/tests + run: python -m unittest discover --verbose --start-directory tests build_wheels: name: Build wheels on ${{ matrix.os }} @@ -128,7 +128,7 @@ jobs: run: python -m cibuildwheel --output-dir wheelhouse env: CIBW_BUILD: ${{ matrix.python }}-${{ matrix.platform_id }}* - CIBW_TEST_COMMAND: python -W default -m unittest discover -s {project}/tests + CIBW_TEST_COMMAND: python -W default -m unittest discover --start-directory {project}/tests - uses: actions/upload-artifact@v4 diff --git a/pyproject.toml b/pyproject.toml index c2c2f426..e1bbbd96 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,9 @@ build-backend = "setuptools.build_meta" name = "pygom" dynamic = ["version"] dependencies = [ + "setuptools>=64", + "setuptools_scm>=8", + "setuptools_scm_git_archive" "dask[complete]>=0.13.0", "graphviz>=0.4.9", "matplotlib>=1.0.0", From 1ab70b20b45e1d413369027773dcf2ec5113326e Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 11:58:25 +0100 Subject: [PATCH 102/123] Fix the missing comma --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e1bbbd96..af5b41be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ dynamic = ["version"] dependencies = [ "setuptools>=64", "setuptools_scm>=8", - "setuptools_scm_git_archive" + "setuptools_scm_git_archive", "dask[complete]>=0.13.0", "graphviz>=0.4.9", "matplotlib>=1.0.0", From 003c6db4a51796693dd3e760cb84e4e0f8512ab7 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 14:32:22 +0100 Subject: [PATCH 103/123] Tidy the CI and pyproject scripts --- .github/workflows/main.yml | 43 +++++++++++++++++++------------------- pyproject.toml | 25 +--------------------- 2 files changed, 22 insertions(+), 46 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 790ba0cb..40cd20b2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,21 +27,21 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/cache@v1 + - uses: actions/cache@v4 if: startsWith(runner.os, 'Linux') with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- - - uses: actions/cache@v1 + - uses: actions/cache@v4 if: startsWith(runner.os, 'macOS') with: path: ~/Library/Caches/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- - - uses: actions/cache@v1 + - uses: actions/cache@v4 if: startsWith(runner.os, 'Windows') with: path: ~\AppData\Local\pip\Cache @@ -49,7 +49,7 @@ jobs: restore-keys: | ${{ runner.os }}-pip- - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -68,7 +68,7 @@ jobs: run: python -m unittest discover --verbose --start-directory tests build_wheels: - name: Build wheels on ${{ matrix.os }} + name: Build wheels on ${{ matrix.platform_id }} for Python v${{ matrix.python[1] }} runs-on: ${{ matrix.os }} strategy: # Ensure that a wheel builder finishes even if another fails @@ -77,36 +77,33 @@ jobs: include: # Window 64 bit - os: windows-latest - python: cp39 + python: [cp39, "3.9"] platform_id: win_amd64 - os: windows-latest - python: cp310 + python: [cp310, "3.10"] platform_id: win_amd64 - os: windows-latest - python: cp311 + python: [cp311, "3.11"] platform_id: win_amd64 - os: windows-latest - python: cp312 + python: [cp312, "3.12"] platform_id: win_amd64 -# # Linux 64 bit manylinux2014 -# - os: ubuntu-latest -# python: cp39 -# platform_id: manylinux_x86_64 -# manylinux_image: manylinux2014 + # Python 3.9 in the manylinux build environment requires our dependencies to be + # built from source so we won't supply a wheel for 3.9 (source build will prevent lib + # version conflicts). # NumPy on Python 3.10 only supports 64bit and is only available with manylinux2014 - os: ubuntu-latest - python: cp310 + python: [cp310, "3.10"] platform_id: manylinux_x86_64 manylinux_image: manylinux2014 - - os: ubuntu-latest - python: cp311 + python: [cp311, "3.11"] platform_id: manylinux_x86_64 manylinux_image: manylinux2014 - os: ubuntu-latest - python: cp312 + python: [cp312, "3.12"] platform_id: manylinux_x86_64 manylinux_image: manylinux2014 @@ -120,18 +117,20 @@ jobs: # Used to host cibuildwheel - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python[1] }} - name: Install cibuildwheel run: python -m pip install cibuildwheel>=2.19.2 - - name: Build wheels + - name: Build and test the wheels run: python -m cibuildwheel --output-dir wheelhouse env: - CIBW_BUILD: ${{ matrix.python }}-${{ matrix.platform_id }}* + CIBW_BUILD: ${{ matrix.python[0] }}-${{ matrix.platform_id }}* CIBW_TEST_COMMAND: python -W default -m unittest discover --start-directory {project}/tests - + # Upload the results - uses: actions/upload-artifact@v4 with: - name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + name: cibw-wheels-${{ matrix.platform_id }}-${{ matrix.python[0] }} path: ./wheelhouse/*.whl diff --git a/pyproject.toml b/pyproject.toml index af5b41be..6bdde66a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ build-backend = "setuptools.build_meta" [project] name = "pygom" +requires-python = ">= 3.9" dynamic = ["version"] dependencies = [ "setuptools>=64", @@ -63,27 +64,3 @@ Issues = "https://github.com/ukhsa-collaboration/pygom/issues" [tool.cibuildwheel] # Normal options, etc. manylinux-x86_64-image = "manylinux2014" - -# Install blas on linux -[tool.cibuildwheel.linux] -before-all = """ -#yum -y update && yum -y install pkgconfig openblas-devel openblas - -#python -m pip install --upgrade pip -#pip install --prefer-binary scipy>=1.10.1 - -# Note we can't just use the version from yum as it doesn't have a pkgconfig -#git clone https://github.com/OpenMathLib/OpenBLAS.git -#cd OpenBLAS -#make -j8 -#make PREFIX=/usr/local/OpenBLAS install -#export PKG_CONFIG_PATH=/usr/local/OpenBLAS/lib/pkgconfig -""" -# -# "yum -y update && yum -y install pkgconfig openblas-devel openblas" -#before-test = "yum -y update && yum -y install openblas-devel openblas" - - -[[tool.cibuildwheel.overrides]] -select = "cp3{8,9}-*" -manylinux-x86_64-image = "manylinux2010" From 7954fd409b12a6db074f8da176673d6836f673ee Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 14:43:18 +0100 Subject: [PATCH 104/123] Tidy the CI more and add src distributions & pypi --- .../{main.yml => distribute_package.yml} | 90 ++++++++----------- .github/workflows/test_package.yml | 67 ++++++++++++++ 2 files changed, 103 insertions(+), 54 deletions(-) rename .github/workflows/{main.yml => distribute_package.yml} (63%) create mode 100644 .github/workflows/test_package.yml diff --git a/.github/workflows/main.yml b/.github/workflows/distribute_package.yml similarity index 63% rename from .github/workflows/main.yml rename to .github/workflows/distribute_package.yml index 40cd20b2..901a235a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/distribute_package.yml @@ -1,4 +1,4 @@ -name: pygom +name: create PyGOM distributions on: push: @@ -13,60 +13,7 @@ on: - master - dev -env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest] #, macos-13, macos-14] - python-version: ["3.9", "3.10", "3.11"] - - steps: - - uses: actions/checkout@v4 - - - uses: actions/cache@v4 - if: startsWith(runner.os, 'Linux') - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - uses: actions/cache@v4 - if: startsWith(runner.os, 'macOS') - with: - path: ~/Library/Caches/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - uses: actions/cache@v4 - if: startsWith(runner.os, 'Windows') - with: - path: ~\AppData\Local\pip\Cache - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Check python version - run: python -c "import sys; print(sys.version)" - - - name: Install pip - run: | - python -m pip install --upgrade pip - - - name: install PyGOM - run: | - pip install . - - - name: Run tests - run: python -m unittest discover --verbose --start-directory tests - build_wheels: name: Build wheels on ${{ matrix.platform_id }} for Python v${{ matrix.python[1] }} runs-on: ${{ matrix.os }} @@ -134,3 +81,38 @@ jobs: with: name: cibw-wheels-${{ matrix.platform_id }}-${{ matrix.python[0] }} path: ./wheelhouse/*.whl + + build_sdist: + name: Build source distribution + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build sdist + run: pipx run build --sdist + + - uses: actions/upload-artifact@v4 + with: + name: cibw-sdist + path: dist/*.tar.gz + + upload_pypi: + needs: [build_wheels, build_sdist] + runs-on: ubuntu-latest + environment: pypi + permissions: + id-token: write + # Upload to PyPI on every tag starting with 'v' + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + steps: + - uses: actions/download-artifact@v4 + with: + # unpacks all CIBW artifacts into dist/ + pattern: cibw-* + path: dist + merge-multiple: true + + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + # Testing only at this point + repository-url: https://test.pypi.org/legacy/ \ No newline at end of file diff --git a/.github/workflows/test_package.yml b/.github/workflows/test_package.yml new file mode 100644 index 00000000..0c2a6cb1 --- /dev/null +++ b/.github/workflows/test_package.yml @@ -0,0 +1,67 @@ +name: create PyGOM distributions + +on: + push: + branches: + - master + - dev + - feature/* + - bugfix/* + + pull_request: + branches: + - master + - dev + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest] #, macos-13, macos-14] + python-version: ["3.9", "3.10", "3.11"] + + steps: + - uses: actions/checkout@v4 + + - uses: actions/cache@v4 + if: startsWith(runner.os, 'Linux') + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + - uses: actions/cache@v4 + if: startsWith(runner.os, 'macOS') + with: + path: ~/Library/Caches/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + - uses: actions/cache@v4 + if: startsWith(runner.os, 'Windows') + with: + path: ~\AppData\Local\pip\Cache + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Check python version + run: python -c "import sys; print(sys.version)" + + - name: Install pip + run: | + python -m pip install --upgrade pip + + - name: install PyGOM + run: | + pip install . + + - name: Run tests + run: python -m unittest discover --verbose --start-directory tests + + #TODO: Could also do something about coverage here too \ No newline at end of file From 00519ff9ee3535a72f1cffcb2788915a549e40e3 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 14:46:08 +0100 Subject: [PATCH 105/123] Unbreak the pyproject file --- pyproject.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6bdde66a..c2fa7c22 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,8 +10,9 @@ build-backend = "setuptools.build_meta" [project] name = "pygom" -requires-python = ">= 3.9" dynamic = ["version"] +requires-python = ">= 3.9" + dependencies = [ "setuptools>=64", "setuptools_scm>=8", @@ -38,8 +39,6 @@ authors = [ description = "ODE modeling in Python." readme = "README.md" -requires-python = ">=3.8" - classifiers = [ "Programming Language :: Python :: 3", From e5e2d7cb906b0d4835a20b8356e9d53611f67027 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 17:00:18 +0100 Subject: [PATCH 106/123] Attempt to fix version numbering. --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c2fa7c22..304c45c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [build-system] requires = ["setuptools>=64", "setuptools_scm>=8", - "setuptools_scm_git_archive", +# "setuptools_scm_git_archive", "numpy>=1.24.4", "cython>=0.29", "setuptools>=61.0", @@ -46,7 +46,7 @@ classifiers = [ "Operating System :: OS Independent", ] -#[tool.setuptools_scm] +[tool.setuptools_scm] #version_file = "pygom/_version.py" [tool.setuptools.packages.find] From 20a20f4c3136ccb8172177764d60e888f34a3d8a Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 17:42:08 +0100 Subject: [PATCH 107/123] Change the git repo fetch depth to fix version number in CI. --- .github/workflows/distribute_package.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index 901a235a..d2694d30 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -56,6 +56,8 @@ jobs: steps: - uses: actions/checkout@v4 + # We need quite a deep fetch so that we get the versioning right + fetch-depth: 500 - name: Install dependencies run: | @@ -87,6 +89,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + # We need quite a deep fetch so that we get the versioning right + fetch-depth: 500 - name: Build sdist run: pipx run build --sdist From 109fa9cfac7ccc11535b400c43ce0d0bc73dd99a Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 17:44:21 +0100 Subject: [PATCH 108/123] Fix the YML syntax --- .github/workflows/distribute_package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index d2694d30..3edfafed 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -56,8 +56,8 @@ jobs: steps: - uses: actions/checkout@v4 - # We need quite a deep fetch so that we get the versioning right - fetch-depth: 500 + # We need quite a deep fetch so that we get the versioning right + fetch-depth: 500 - name: Install dependencies run: | From dd2ccf4764727256c958e32b2b25bc3ccc852962 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 17:45:38 +0100 Subject: [PATCH 109/123] In both places --- .github/workflows/distribute_package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index 3edfafed..e372fa16 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -89,8 +89,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - # We need quite a deep fetch so that we get the versioning right - fetch-depth: 500 + # We need quite a deep fetch so that we get the versioning right + fetch-depth: 500 - name: Build sdist run: pipx run build --sdist From de46605d93851938d0556c5ea936a528a4cfc0c6 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 17:47:49 +0100 Subject: [PATCH 110/123] Don't forget the "with:" in the syntax! --- .github/workflows/distribute_package.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index e372fa16..10f146e6 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -56,8 +56,9 @@ jobs: steps: - uses: actions/checkout@v4 - # We need quite a deep fetch so that we get the versioning right - fetch-depth: 500 + with: + # We need quite a deep fetch so that we get the versioning right + fetch-depth: 500 - name: Install dependencies run: | @@ -89,8 +90,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - # We need quite a deep fetch so that we get the versioning right - fetch-depth: 500 + with: + # We need quite a deep fetch so that we get the versioning right + fetch-depth: 500 - name: Build sdist run: pipx run build --sdist From 1c69dc63ffc91ad8ad3ab0943ab7ef4d4ff83b88 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Sat, 3 Aug 2024 20:11:54 +0100 Subject: [PATCH 111/123] Include tags in the fetch. --- .github/workflows/distribute_package.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index 10f146e6..6fe9eabd 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -58,7 +58,8 @@ jobs: - uses: actions/checkout@v4 with: # We need quite a deep fetch so that we get the versioning right - fetch-depth: 500 + fetch-depth: 500 + fetch-tags: true - name: Install dependencies run: | @@ -92,7 +93,8 @@ jobs: - uses: actions/checkout@v4 with: # We need quite a deep fetch so that we get the versioning right - fetch-depth: 500 + fetch-depth: 500 + fetch-tags: true - name: Build sdist run: pipx run build --sdist From 81c164fb2dc4e50ab4ea1109e4aa5beb5adac94f Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 14:35:56 +0100 Subject: [PATCH 112/123] Fix the horrible default PR template to make it fit the repo better. --- .github/pull_request_template.md | 46 ++++++++++---------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7ffaaf4c..a7399590 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -7,46 +7,28 @@ Replace this text with a description of the pull request including the issue num This is an itemised checklist for the QA process within UKHSA and represents the bare minimum a QA should be. -Full instructions on reviewing work can be found at Confluence on the [ONS QA of code guidance](https://best-practice-and-impact.github.io/qa-of-code-guidance/intro.html) page. - **To the reviewer:** Check the boxes once you have completed the checks below. -- [ ] It runs - - Can you get the code run to completion in a new instance and from top to bottom in the case of notebooks, or in a new R session? - - Can original analysis results be accurately & easily reproduced from the code? -- [] tests pass -- [] CI is successful +- [ ] CI is successful + - Did the test suite run sucessfully? + This is a basic form of Smoke Testing - [ ] Data and security - - Use nbstripout to prevent Jupyter notebook output being committed to git repositories - - Files containing individual user's secret files and config files are not in repo, however examples of these files and setup instructions are included in the repo. - - Secrets include s3 bucket names, login credentials, and organisation information. These can be handled using secrets.yml - - If you are unsure whether an item should be secret please discuss with repo owner - - The changes do not include unreleased policy or official information. + - Files containing individual user's secret files and config files are not in repo. + - No private or identifiable data has been added to the repo. + - [ ] Sensible - - Does the code execute the task accurately? This is a subjective challenge. + - Does the code execute the task accurately? + - Is the code tidy, commented and parsimonious? - Does the code do what the comments and readme say it does\*? - - Is the code robust enough to handle missing or challenging data? + - Is the code covered by useful unit tests? + - [ ] Documentation - - The purpose of the code is clearly defined, whether in a markdown chunk at the top of a notebook or in a README - - Assumptions of the analysis & input data are clearly displayed to the reader, whether in a markdown chunk at the top of a notebook or in a README + - The purpose of the code is clearly defined? + - If reasonable, has an exaple of the code been given in a notebook in the docs? - Comments are included in the code so the reader can follow why the code behaves in the way it does - - Teams with high quality documentation are better able to implement technical practices more readily and perform better as a whole (DORA, 2021). - - Is the code written in a standard way? (In a hurry this may be a nice to have, but if at all possible, this standard from the beginning can cut long term costs dramatically) - - Code is modular, storing functions & classes in the src and being imported into a notebook or script - - Projects should be based on the UKHSA repo template developed to work with cookiecutter - - Variable, function & module names should be intuitive to the reader - - For example, intuitive names include df_geo_lookup & non-intuitive names include foobar - - Common and useful checks for coding we use broadly across UKHSA include: - - Rstyler - - lintr - - black - - flake8 -- [ ] Pair coding review completed (optional, but highly recommended for QA in a hurry) - - Pair programming is a way of working and reviewing that can result in the same standard of work being completed 40%-50% faster (Williams et al., 2000, Nosek, 1998) and is better than solo programming for tasks involving efficient knowledge transferring and for working on highly connected systems (Dawande et al., 2008). - - Have the assignee and reviewer been on a video call or in person together during the code development in a line by line writing and review process? - -\* If the comments or readme do not have enough information, this check fails. + - Is the code written in a standard way (does it pass linting)? + - Variable, function & module names should be intuitive to the reader? ## How to QA this PR From a70fca089f3b992e8bcc8f19f5e648516507df6a Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 14:50:48 +0100 Subject: [PATCH 113/123] Update the doc building action --- .github/workflows/book.yml | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 7e9a3eca..4212fb6c 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -30,23 +30,21 @@ jobs: uses: ts-graphviz/setup-graphviz@v1 # install python - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v4 with: - python-version: 3.8 + python-version: 3.10 - # install dependencies - - name: Install dependencies + # set up pygom + - name: Build and install pygom run: | python -m pip install --upgrade pip - pip install -r requirements.txt - pip install -r docs/requirements.txt + pip install . - # set up pygom - - name: Build and install pygom + # install dependencies + - name: Install documentation dependencies run: | - python setup.py build - python setup.py install + pip install -r docs/requirements.txt # build the book # TODO check which flags are needed, -W From 3089346d9b06f2d7c534b7958c3f9aa46c611e2d Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 14:54:59 +0100 Subject: [PATCH 114/123] Update the book buiding to separate dev and master --- .github/workflows/book.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 4212fb6c..894ecf4c 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -54,8 +54,16 @@ jobs: # deploy book to github-pages - name: GitHub Pages - uses: peaceiris/actions-gh-pages@v3.6.1 + uses: peaceiris/actions-gh-pages@v4 + if: github.ref == 'refs/heads/main' with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: docs/_build/html - + # deploy book to github-pages dev + - name: GitHub Pages dev + uses: peaceiris/actions-gh-pages@v4 + if: github.ref == 'refs/heads/dev' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: docs/_build/html + destination_dir: dev From e20034556392f206f21878815b05554ed91e294b Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 15:55:59 +0100 Subject: [PATCH 115/123] The version of Python needs to be a string to separate 3.1 from 3.10. --- .github/workflows/book.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 894ecf4c..2440f8c7 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -33,7 +33,7 @@ jobs: - name: Set up Python 3.10 uses: actions/setup-python@v4 with: - python-version: 3.10 + python-version: '3.10' # set up pygom - name: Build and install pygom From 9db03c762ace9cc452f462e5c7d8538d5ccf7a8c Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 16:03:52 +0100 Subject: [PATCH 116/123] Update so that dev branch pushes end up with an upload to pypi testing --- .github/workflows/distribute_package.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index 6fe9eabd..4d2f389b 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -105,13 +105,13 @@ jobs: path: dist/*.tar.gz upload_pypi: + name: Upload release to PyPI needs: [build_wheels, build_sdist] runs-on: ubuntu-latest - environment: pypi + environment: + name: pypi permissions: id-token: write - # Upload to PyPI on every tag starting with 'v' - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') steps: - uses: actions/download-artifact@v4 with: @@ -119,8 +119,18 @@ jobs: pattern: cibw-* path: dist merge-multiple: true + + # This is the live push to PyPI on tagging the master branch + - uses: pypa/gh-action-pypi-publish@release/v1 + # Upload to PyPI on every tag starting with 'v' + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + with: + repository-url: https://pypi.org/p/pygom + # Upload to PyPI *testing* every dev branch commit - uses: pypa/gh-action-pypi-publish@release/v1 + # Upload to testing only if we are on the dev branch + if: github.ref == 'refs/heads/dev' with: # Testing only at this point repository-url: https://test.pypi.org/legacy/ \ No newline at end of file From 3d5a7f62546badfdb56b9b5e0af6f2ef76dc2722 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 17:14:53 +0100 Subject: [PATCH 117/123] Update readme for new release. --- README.md | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 34300123..7ac5ee83 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,41 @@ # PyGOM - Python Generic ODE Model [![pypi version](https://img.shields.io/pypi/v/pygom.svg)](https://pypi.python.org/pypi/pygom) -[![Documentation Status](https://readthedocs.org/projects/pygom/badge/?version=master)](https://pygom.readthedocs.io/en/master/?badge=master) -[![licence](https://img.shields.io/pypi/l/pygom?color=green)](https://raw.githubusercontent.com/PublicHealthEngland/pygom/master/LICENSE.txt) -[![Github actions](https://github.com/PublicHealthEngland/pygom/workflows/pygom/badge.svg)](https://github.com/PublicHealthEngland/pygom/actions/) -[![Jupyter Book Badge](https://jupyterbook.org/badge.svg)](https://hwilliams-phe.github.io/pygom/intro.html) +[![licence](https://img.shields.io/pypi/l/pygom?color=green)](https://raw.githubusercontent.com/ukhsa-collaboration/pygom/master/LICENSE.txt) +[![Github actions](https://github.com/ukhsa-collaboration/pygom/workflows/pygom/badge.svg)](https://github.com/ukhsa-collaboration/pygom/actions/) +[![Jupyter Book Badge](https://jupyterbook.org/badge.svg)](http://ukhsa-collaboration.github.io/pygom/md/intro.html) A generic framework for Ordinary Differential Equation (ODE) models, especially compartmental type systems. This package provides a simple interface for users to construct ODE models backed by a comprehensive and easy to use tool–box implementing functions to easily perform common operations such as parameter estimation and solving for deterministic or stochastic time evolution. With both the algebraic and numeric calculations performed automatically (but still accessible), the end user is free to focus on model development. +Full documentation for this package is avalible on the [documentation](http://ukhsa-collaboration.github.io/pygom/md/intro.html) page. ## Installation +The easiest way to install a copy of PyGOM is via PyPI and pip + + pip install pygom -You can download a local copy of the PyGOM source files from this GitHub repository: +Alternatively, you can download a local copy of the PyGOM source files from this GitHub repository: git clone https://github.com/ukhsa-collaboration/pygom.git Please be aware that there may be redundant files within the package as it is under active development. > [!NOTE] -> The latest fully reviewed version of PyGOM will be on the `master` branch and we generally recommend that users install this version. However, the current version being prepared for release (featuring up-to-date documentation) is hosted on the `feature/prep-doc` branch. +> The latest fully reviewed version of PyGOM will be on the `master` branch and we generally recommend +> that users install this version. However, the latest version being prepared for release is hosted on +> the `dev` branch. -When running the following command line commands, ensure that your current working directory is the one where the PyGOM source files were downloaded to. This should be found from your home directory: +When running the following command line commands, ensure that your current working directory is the one +where the PyGOM source files were downloaded to. This should be found from your home directory: cd pygom -Activate the relevant branch for installation via Git Bash, if you have been recruited to test code for the -new release then this is the `feature/prep-doc` branch: +Activate the relevant branch for installation via Git Bash. for example if you want +new release then this is the `dev` branch: - git checkout feature/prep-doc + git checkout dev Package dependencies can be found in the file, `requirements.txt`. An easy way to install these to create a new [conda](https://conda.io/docs) environment in Anaconda Prompt via: @@ -48,17 +54,17 @@ Alternatively, you may add dependencies to your own environment through conda: pip install -r requirements.txt -The final prerequisite, if you are working on a Windows machine, is that you will also need to install: +The final prerequisites, if you are working on a Windows machine, is that you will also need to install: - [Graphviz](https://graphviz.org/) - Microsoft Visual C++ 14.0 or greater, which you can get with [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) You should now be able to install the PyGOM package via command line: - python setup.py install + pip install . and test that installation has completed successfully - python setup.py test + python -m unittest discover --verbose --start-directory tests This will run a few test cases and can take some minutes to complete. @@ -88,7 +94,7 @@ Please be aware that if the module tests fails, then the documentation for the p ## Contributors -Thomas Finnie (Thomas.Finnie@phe.gov.uk) +Thomas Finnie (Thomas.Finnie@ukhsa.gov.uk) Edwin Tye @@ -101,6 +107,7 @@ Martin Grunnill Joseph Gibson ## Version +0.1.8 Updated and much better documentation. 0.1.7 Add Approximate Bayesian Computation (ABC) as a method of fitting to data From d7148d55865aeae0979cebfb1440a98e8e75b6a2 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 17:51:05 +0100 Subject: [PATCH 118/123] Fix versioning for dev commits to test.pypi.org --- .github/workflows/distribute_package.yml | 8 ++++++++ pyproject.toml | 10 +++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index 4d2f389b..ea0b2475 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -66,6 +66,14 @@ jobs: python -m pip install --upgrade pip pip install -r requirements.txt + # setuptools_scm workaround for https://github.com/pypa/setuptools_scm/issues/455 + - name: Disable local version identifier on develop CI + if: github.ref == 'refs/heads/dev' + run: | + echo 'local_scheme = "no-local-version"' >> pyproject.toml + git diff --color=always + git update-index --assume-unchanged pyproject.toml + # Used to host cibuildwheel - uses: actions/setup-python@v5 with: diff --git a/pyproject.toml b/pyproject.toml index 304c45c5..b9bd9eb0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,9 +46,6 @@ classifiers = [ "Operating System :: OS Independent", ] -[tool.setuptools_scm] -#version_file = "pygom/_version.py" - [tool.setuptools.packages.find] where = ["src"] @@ -63,3 +60,10 @@ Issues = "https://github.com/ukhsa-collaboration/pygom/issues" [tool.cibuildwheel] # Normal options, etc. manylinux-x86_64-image = "manylinux2014" + +# '[tool.setuptools.scm]' needs to be the last line because +# we do an append operation in the deploy.yaml GitHub Actions workflow +# so that we are able to push to test.pypi.org with a proper version +# number +[tool.setuptools_scm] +#version_file = "pygom/_version.py" From d19a68cd1a8c7b3a6b35e5bea29fb47914c51d4a Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 18:29:33 +0100 Subject: [PATCH 119/123] Fix metadata --- pyproject.toml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b9bd9eb0..bc779d84 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,8 +42,17 @@ readme = "README.md" classifiers = [ "Programming Language :: Python :: 3", - "License :: OSI Approved :: GPL2", - "Operating System :: OS Independent", + "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Mathematics", + "Topic :: Scientific/Engineering :: Physics", + "Development Status :: 5 - Production/Stable" ] [tool.setuptools.packages.find] From d54499b9b78ff11aa0939f5ec2d7c756e604d195 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 20:42:40 +0100 Subject: [PATCH 120/123] The update needs to happen _inside_ the manylinux build container. --- .github/workflows/distribute_package.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index ea0b2475..06ec3c48 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -66,14 +66,6 @@ jobs: python -m pip install --upgrade pip pip install -r requirements.txt - # setuptools_scm workaround for https://github.com/pypa/setuptools_scm/issues/455 - - name: Disable local version identifier on develop CI - if: github.ref == 'refs/heads/dev' - run: | - echo 'local_scheme = "no-local-version"' >> pyproject.toml - git diff --color=always - git update-index --assume-unchanged pyproject.toml - # Used to host cibuildwheel - uses: actions/setup-python@v5 with: @@ -87,7 +79,9 @@ jobs: env: CIBW_BUILD: ${{ matrix.python[0] }}-${{ matrix.platform_id }}* CIBW_TEST_COMMAND: python -W default -m unittest discover --start-directory {project}/tests - + # setuptools_scm workaround for https://github.com/pypa/setuptools_scm/issues/455 + CIBW_BEFORE_BUILD: ${{ github.ref == 'refs/heads/dev' && 'echo ''local_scheme = "no-local-version"'' >> pyproject.toml\n git diff --color=always\n git update-index --assume-unchanged pyproject.toml\n' || '' }} + # Upload the results - uses: actions/upload-artifact@v4 with: From ad2727e6c622505ae38eeed61adbe43aa77739af Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 20:50:16 +0100 Subject: [PATCH 121/123] Disable of local version also needs to hapen for source distro --- .github/workflows/distribute_package.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index 06ec3c48..48309bb9 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -98,6 +98,14 @@ jobs: fetch-depth: 500 fetch-tags: true + # setuptools_scm workaround for https://github.com/pypa/setuptools_scm/issues/455 + - name: Disable local version identifier on develop CI + if: github.ref == 'refs/heads/dev' + run: | + echo 'local_scheme = "no-local-version"' >> pyproject.toml + git diff --color=always + git update-index --assume-unchanged pyproject.toml + - name: Build sdist run: pipx run build --sdist From 7697464106004bcce57cc0fcac6936e1e25b76a6 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 20:56:02 +0100 Subject: [PATCH 122/123] Newlines do not work within the CIBW env varible --- .github/workflows/distribute_package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index 48309bb9..4dd811f9 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -80,7 +80,7 @@ jobs: CIBW_BUILD: ${{ matrix.python[0] }}-${{ matrix.platform_id }}* CIBW_TEST_COMMAND: python -W default -m unittest discover --start-directory {project}/tests # setuptools_scm workaround for https://github.com/pypa/setuptools_scm/issues/455 - CIBW_BEFORE_BUILD: ${{ github.ref == 'refs/heads/dev' && 'echo ''local_scheme = "no-local-version"'' >> pyproject.toml\n git diff --color=always\n git update-index --assume-unchanged pyproject.toml\n' || '' }} + CIBW_BEFORE_BUILD: ${{ github.ref == 'refs/heads/dev' && 'echo ''local_scheme = "no-local-version"'' >> pyproject.toml && git diff --color=always && git update-index --assume-unchanged pyproject.toml' || '' }} # Upload the results - uses: actions/upload-artifact@v4 From 39955978b7ab2bf6e29db8c1651288955dec2654 Mon Sep 17 00:00:00 2001 From: Thomas Finnie Date: Mon, 5 Aug 2024 21:54:03 +0100 Subject: [PATCH 123/123] Account for the different behaviour of echo on Windows and Linux --- .github/workflows/distribute_package.yml | 10 ++++++++++ .github/workflows/test_package.yml | 8 ++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/distribute_package.yml b/.github/workflows/distribute_package.yml index 4dd811f9..7fef265c 100644 --- a/.github/workflows/distribute_package.yml +++ b/.github/workflows/distribute_package.yml @@ -74,13 +74,23 @@ jobs: - name: Install cibuildwheel run: python -m pip install cibuildwheel>=2.19.2 + # Need to duplicate these two lines as it seems Windows and Linux echo treats qutotes differently - name: Build and test the wheels + if: matrix.os == 'ubuntu-latest' run: python -m cibuildwheel --output-dir wheelhouse env: CIBW_BUILD: ${{ matrix.python[0] }}-${{ matrix.platform_id }}* CIBW_TEST_COMMAND: python -W default -m unittest discover --start-directory {project}/tests # setuptools_scm workaround for https://github.com/pypa/setuptools_scm/issues/455 CIBW_BEFORE_BUILD: ${{ github.ref == 'refs/heads/dev' && 'echo ''local_scheme = "no-local-version"'' >> pyproject.toml && git diff --color=always && git update-index --assume-unchanged pyproject.toml' || '' }} + - name: Build and test the wheels + if: matrix.os == 'windows-latest' + run: python -m cibuildwheel --output-dir wheelhouse + env: + CIBW_BUILD: ${{ matrix.python[0] }}-${{ matrix.platform_id }}* + CIBW_TEST_COMMAND: python -W default -m unittest discover --start-directory {project}/tests + # setuptools_scm workaround for https://github.com/pypa/setuptools_scm/issues/455 + CIBW_BEFORE_BUILD: ${{ github.ref == 'refs/heads/dev' && 'echo local_scheme = "no-local-version" >> pyproject.toml && git diff --color=always && git update-index --assume-unchanged pyproject.toml' || '' }} # Upload the results - uses: actions/upload-artifact@v4 diff --git a/.github/workflows/test_package.yml b/.github/workflows/test_package.yml index 0c2a6cb1..500f8913 100644 --- a/.github/workflows/test_package.yml +++ b/.github/workflows/test_package.yml @@ -56,12 +56,16 @@ jobs: - name: Install pip run: | python -m pip install --upgrade pip + + - name: Install coverage + run: | + python -m pip install codecov - name: install PyGOM run: | pip install . - name: Run tests - run: python -m unittest discover --verbose --start-directory tests + run: coverage run -m unittest discover --verbose --start-directory tests - #TODO: Could also do something about coverage here too \ No newline at end of file + \ No newline at end of file