gerk


Namegerk JSON
Version 1.0.2 PyPI version JSON
download
home_pageNone
SummaryGeneralized Explicit Runge-Kutta
upload_time2024-11-14 15:30:36
maintainerNone
docs_urlNone
authorYasser Naji
requires_pythonNone
licenseNone
keywords runge-kutta runge kutta numerical integration approximation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Generalized Explicit Runge-Kutta (GERK)

A package for the curious mathematicians and engineers who want to experiment the Runge-Kutta method with their own coefficients.

[PyPI link](https://pypi.org/project/gerk/)

[GitHub link](https://github.com/yfnaji/Gerk)

## Motivation

I decided to create this package to give mathematicians or engineers the freedom to create and use the Runge-Kutta method of their choice,
as opposed to be being locked in to whatever a package provides you.

## Runge-Kutta Overview

Runge-Kutta methods aim to numerically solve ordinary differential equations of the form:

$$
\frac{\text{d}y}{\text{d}x}=f(x,y)
$$

with a given initial condition $(x_0, y_0)$. 

We define a member of the Runge-Kutta family with a *Butcher tableau*:

<img width="247" alt="genrk" src="https://github.com/yfnaji/Gerk/assets/59436765/c35b7df0-0080-41bf-8f1d-04a53ad9dac5">

The above tableau is often abbreviated to

<img width="103" alt="abbrk" src="https://github.com/yfnaji/Gerk/assets/59436765/561bd4fb-d488-44cf-9246-56cb392ad66d">

The Butcher tableau presents the categories of coefficients that will be used in our Runge-Kutta method.

The $n^\text{th}$ evaluation of the solution will be denoted as $(x_n, y_n)$. We also define $h$ as the time step i.e. the step size from the previous approximation to the next, and therefore

$$
x_{n+1} = x_{n} + h
$$

Before defining $y_n$, we must familiarize ourselves with the array $k$. We define the $i^{\text{th}}$ row of $k$ at $(x_n, y_n)$ as:

$$
k_i(x_n, y_n) = f\left(x_n + c_i h, y_n + \sum_{j=1}^{i-1} a_{ij}k_j(x_n, y_n)\right)
$$

where $f$ is the function defined in the differential equation above. Note the recursion in the second argument of $f$ where we sum rows preceding $k_{i}$ and apply a scale factor of $a_{ij}$.

We now have everything we need to calculate $y_{n+1}$:

$$
y_{n+1} = y_{n} + h \sum_{i=1}^{r}b_i k_{i}(x_n, y_n)
$$

The idea is to calculate various slopes at point $y_n$ to ascertain a weighted of the ascent (or descent) and add it to the previous approximation.

## What is Gerk?

Most packages for the Runge-Kutta method usually have the coefficients $a_{ij}$, $b_i$ and $c_i$ determined beforehand for known methods such as the *Forward-Euler method*, the *1/4 rule*, *the 3/8 rule* etc, but do not allow one to customerize their own Runge-Kutta.

Gerk is an easy interface to allow the user to determine their own coefficient values for the Runge-Kutta method.

## How to use Gerk

We can simply import `Gerk` in the following way:

```
from gerk import gerk
```

## Parameters

As seen in mathematics above, there is quite a bit information required to execute the Runge-Kutta method. This has been broken down into arguments to be passed into the `Gerk` class:

- `a` The $A$ matrix in the Butcher tableau. This **must** be a lower triangular matrix that is formatted as a list of lists that contain floats, or integers
- `b` The $b$ array. Must be a list of floats, decimals or integers
- `c` The $c$ array. Must be a list of floats, decimals or integers
- `initial` A `tuple` that acts as the coordinate of the initial condition values $(x_0, y_0)$
- `terminal` The value of $x$ for which we terminate the Runge-Kutta method
- `timesteps` The number of times steps you want to apply on the from the starting point $x_0$ to `final`. Must be an integer
- `func` The function expression to be numerically integrated
- `enforce_rules` (Optional) A boolean to enforce conventional Runge-Kutta rules

The function will output the time steps and approximated y values as a tuple of lists of floats.

## Conditions

There is no consensus to what conditions must hold regarding the coefficients you choose for your method, however, some known Runge-Kutta methods do consistently conform to some known conditions.

These conditions are

$$\sum_{i=1}^{r}b_i=1 \ \ \ \ \sum_{i=1}^{r}b_ic_i = 1/2 \ \ \ \ \sum_{j=1}^{r}a_{ij} = c_i$$

which can be enforced by the `enforce_rules` parameter, which is defaulted to `False`.

## Example

Let us numerically solve the following initial value problem:

$$
\frac{\text{d}y}{\text{d}x} = y
$$

with the initial value $(0, 1)$. We want to apply a Runge-Kutta method with the following Butcher tableau:

<img width="236" src="https://github.com/yfnaji/Gerk/assets/59436765/0105ab38-e0b3-4b97-b5d7-d3fcc1eddb2b">

The $A$ lower triangular matrix in the Butcher tableau above can be implemented in the following way:

```python
a = [
        [1/3],
        [-1/3, 1],
        [1, -1, 1]
]
```

Now for the `b` and `c` vectors:

```python
b = [1/8, 3/8, 3/8, 1/8]

c = [0, 1/3, 2/3, 1]
```

Finally, we can define the function with a lambda function:

```
func = lambda x, y: y
```

Now we are ready to run `gerk()` and plot its output:

```python
import matplotlib.pyplot as plt
from gerk import gerk

x, y = gerk(
        a=a, 
        b=b, 
        c=c, 
        initial=(0, 1), 
        timesteps=10000, 
        terminal=1,
        func=lambda x, y: y,
    )

plt.plot(x, y, color="r")
plt.show()
```

The code above yields the following graph:

<img width="500" alt="gerk_1" src=https://github.com/user-attachments/assets/b17a9a2b-8286-464a-a0aa-9a72f6f0a9d2>

## Adaptive Runge-Kutta Methods

There is an alternate way to utilise the Runge-Kutta method by employing an additional distinct $b$ array. The Butcher tableau for such methods take the form:

<img width="337" alt="adaptive_butcher" src="https://github.com/user-attachments/assets/855c531c-a75c-485b-9f30-2f6b2a379abe">

where $b_1$ and $b_2$ are the two distinct $b$ arrays.

This method is not too disimilar to the original Runge-Kutta method. We calculate the $k$'s in the same way as before, but there is an extra step when evaluating $y_{n+1}$. 

Although we do calculate $y_{n+1}$ in same way outlined above, we also calculate $\gamma_{n+1}$:

$$
y_{n+1} = y_{n} + h \sum_{i=1}^{r}b_{1i}\cdot k_{i}(x_n, y_n) \ \ \ \ \ \ \ \ \ \gamma_{n+1} = y_{n} + h \sum_{i=1}^{r} b_{2i}\cdot k_{i}(x_n, y_n)
$$

_Note_ that the calculation for $\gamma$ requires the use of $y_n$ and **not** $\gamma_n$.

For every time step, we calculate the following error:

$$
E := \left|y_{n+1}-\gamma_{n+1}\right|
$$

Now we define the tolerance, $\mathcal{E}$, which will act as the maximum acceptable value for $E$.

If $E<\mathcal{E}$, then we accept the value of $y_{n+1}$ and we increment $x_{n}$ by $h$ and start the process again for $x_{n+1}$ and $y_{n+1}$ as normal. 

However, if $E\geq\mathcal{E}$, we will need to adjust the value of $h$ and redo the calculation with this renewed time step value in an attempt to satisfy the condition $E<\mathcal{E}$. 

The value of $h$ will be adjusted as follows:

$$
h \rightarrow 0.9\cdot h \cdot\sqrt[n]{\frac{h}{\mathcal{E}}}
$$

where $n=\min\left(p,q\right)$, where $p$ and $q$ are the orders $^1$ of $b_i$ and $b^*_i$ respectively.

$^1$ A Runge-Kutta method with matrix $a_{ij}$ and arrays $b$ and $c$ has order $p$ if

$$
\sum_{i=1}^{p}b_i = 1 \ \ \ \ \sum_{i=1}^{p}b_ic_i = 1/2 \ \ \ \ \sum_{j=1}^{p}a_{ij} = c_i  \ \ \ \ 
$$

## Adaptive Runge-Kutta example

In this example, we will try to numerically integrate

$$
\frac{\text{d}y}{\text{d}x}=-2xy
$$

with initial conditions $(-1, e^{-1})$. Note that the exact solution is $y=e^{-x^2}$.

Here we will use the Bogacki–Shampine (BS23) method which has the following Butcher tableau:

<img width="247" alt="adapt_butcher" src="https://github.com/user-attachments/assets/95a88663-cfce-4654-ae14-5fcff6057da2">

For the adaptive Runge-Kutta method, we will use `adaptive_gerk()`. This method's paramters vary slightly from `gerk()`:

- `a` The $A$ matrix in the Butcher tableau. This **must** be a lower triangular matrix that is formatted as a list of lists that contain floats, or integers
- `b_1` The $b_1$ array. Must be a list of floats, decimals or integers
- `b_2` The $b_2$ array. Must be a list of floats, decimals or integers
- `c` The $c$ array. Must be a list of floats, decimals or integers
- `initial` A `tuple` that acts as the coordinate of the initial condition values $(x_0, y_0)$
- `terminal` The value of $x$ for which we terminate the Runge-Kutta method
- `timesteps` The number of times steps you want to apply on the from the starting point $x_0$ to `final`. Must be an integer
- `func` The function expression to be numerically integrated
- `enforce_rules` (Optional) A boolean to enforce conventional Runge-Kutta rules. Defaulted to `False`
- `tolerance` (Optional) A float representing the maximum threshold of the adaptive step. Defaulted to `1e-4`

Similar to `gerk()`, this function will output the time steps and approximated y values as a tuple of lists of floats.

```python
from math import exp
import matplotlib.pyplot as plt
from gerk import adaptive_gerk

a = [
    [1/2],
    [0, 3/4],
    [2/9, 1/3, 4/9]
]
b_1 = [2/9, 1/3, 4/9, 0]
b_2 = [7/24, 1/4, 1/3, 1/8]
c = [0, 1/2, 3/4, 1]

x, y = adaptive_gerk(
        a=a, 
        b_1=b_1, 
        b_2=b_2, 
        c=c, 
        initial=(-1, exp(-1)), 
        timesteps=10000, 
        terminal=1,
        func=lambda x, y: -2 * x * y,
    )

plt.plot(x, y, color="r")
plt.show()
```

The code above yields the following graph:

<img width="500" alt="gerk_2" src=https://github.com/user-attachments/assets/a472aafa-b096-444c-b0b7-86afb988a3c2>

## In the pipeline

* To further generalise the Runge-Kutta method with an indefinite number of $b$ and $c$ arrays
* Implement *Cython* for faster execution times
* More descriptive error messages
* Add unit tests
* Implement Stochastic Runge-Kutta method

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "gerk",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "runge-kutta, runge, kutta, numerical, integration, approximation",
    "author": "Yasser Naji",
    "author_email": "yfnaji@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/cc/b9/8b2aca607028c252fb2b1f604a2b8f6fc9aea3f89de25f623686574b54b9/gerk-1.0.2.tar.gz",
    "platform": null,
    "description": "# Generalized Explicit Runge-Kutta (GERK)\n\nA package for the curious mathematicians and engineers who want to experiment the Runge-Kutta method with their own coefficients.\n\n[PyPI link](https://pypi.org/project/gerk/)\n\n[GitHub link](https://github.com/yfnaji/Gerk)\n\n## Motivation\n\nI decided to create this package to give mathematicians or engineers the freedom to create and use the Runge-Kutta method of their choice,\nas opposed to be being locked in to whatever a package provides you.\n\n## Runge-Kutta Overview\n\nRunge-Kutta methods aim to numerically solve ordinary differential equations of the form:\n\n$$\n\\frac{\\text{d}y}{\\text{d}x}=f(x,y)\n$$\n\nwith a given initial condition $(x_0, y_0)$. \n\nWe define a member of the Runge-Kutta family with a *Butcher tableau*:\n\n<img width=\"247\" alt=\"genrk\" src=\"https://github.com/yfnaji/Gerk/assets/59436765/c35b7df0-0080-41bf-8f1d-04a53ad9dac5\">\n\nThe above tableau is often abbreviated to\n\n<img width=\"103\" alt=\"abbrk\" src=\"https://github.com/yfnaji/Gerk/assets/59436765/561bd4fb-d488-44cf-9246-56cb392ad66d\">\n\nThe Butcher tableau presents the categories of coefficients that will be used in our Runge-Kutta method.\n\nThe $n^\\text{th}$ evaluation of the solution will be denoted as $(x_n, y_n)$. We also define $h$ as the time step i.e. the step size from the previous approximation to the next, and therefore\n\n$$\nx_{n+1} = x_{n} + h\n$$\n\nBefore defining $y_n$, we must familiarize ourselves with the array $k$. We define the $i^{\\text{th}}$ row of $k$ at $(x_n, y_n)$ as:\n\n$$\nk_i(x_n, y_n) = f\\left(x_n + c_i h, y_n + \\sum_{j=1}^{i-1} a_{ij}k_j(x_n, y_n)\\right)\n$$\n\nwhere $f$ is the function defined in the differential equation above. Note the recursion in the second argument of $f$ where we sum rows preceding $k_{i}$ and apply a scale factor of $a_{ij}$.\n\nWe now have everything we need to calculate $y_{n+1}$:\n\n$$\ny_{n+1} = y_{n} + h \\sum_{i=1}^{r}b_i k_{i}(x_n, y_n)\n$$\n\nThe idea is to calculate various slopes at point $y_n$ to ascertain a weighted of the ascent (or descent) and add it to the previous approximation.\n\n## What is Gerk?\n\nMost packages for the Runge-Kutta method usually have the coefficients $a_{ij}$, $b_i$ and $c_i$ determined beforehand for known methods such as the *Forward-Euler method*, the *1/4 rule*, *the 3/8 rule* etc, but do not allow one to customerize their own Runge-Kutta.\n\nGerk is an easy interface to allow the user to determine their own coefficient values for the Runge-Kutta method.\n\n## How to use Gerk\n\nWe can simply import `Gerk` in the following way:\n\n```\nfrom gerk import gerk\n```\n\n## Parameters\n\nAs seen in mathematics above, there is quite a bit information required to execute the Runge-Kutta method. This has been broken down into arguments to be passed into the `Gerk` class:\n\n- `a` The $A$ matrix in the Butcher tableau. This **must** be a lower triangular matrix that is formatted as a list of lists that contain floats, or integers\n- `b` The $b$ array. Must be a list of floats, decimals or integers\n- `c` The $c$ array. Must be a list of floats, decimals or integers\n- `initial` A `tuple` that acts as the coordinate of the initial condition values $(x_0, y_0)$\n- `terminal` The value of $x$ for which we terminate the Runge-Kutta method\n- `timesteps` The number of times steps you want to apply on the from the starting point $x_0$ to `final`. Must be an integer\n- `func` The function expression to be numerically integrated\n- `enforce_rules` (Optional) A boolean to enforce conventional Runge-Kutta rules\n\nThe function will output the time steps and approximated y values as a tuple of lists of floats.\n\n## Conditions\n\nThere is no consensus to what conditions must hold regarding the coefficients you choose for your method, however, some known Runge-Kutta methods do consistently conform to some known conditions.\n\nThese conditions are\n\n$$\\sum_{i=1}^{r}b_i=1 \\ \\ \\ \\ \\sum_{i=1}^{r}b_ic_i = 1/2 \\ \\ \\ \\ \\sum_{j=1}^{r}a_{ij} = c_i$$\n\nwhich can be enforced by the `enforce_rules` parameter, which is defaulted to `False`.\n\n## Example\n\nLet us numerically solve the following initial value problem:\n\n$$\n\\frac{\\text{d}y}{\\text{d}x} = y\n$$\n\nwith the initial value $(0, 1)$. We want to apply a Runge-Kutta method with the following Butcher tableau:\n\n<img width=\"236\" src=\"https://github.com/yfnaji/Gerk/assets/59436765/0105ab38-e0b3-4b97-b5d7-d3fcc1eddb2b\">\n\nThe $A$ lower triangular matrix in the Butcher tableau above can be implemented in the following way:\n\n```python\na = [\n        [1/3],\n        [-1/3, 1],\n        [1, -1, 1]\n]\n```\n\nNow for the `b` and `c` vectors:\n\n```python\nb = [1/8, 3/8, 3/8, 1/8]\n\nc = [0, 1/3, 2/3, 1]\n```\n\nFinally, we can define the function with a lambda function:\n\n```\nfunc = lambda x, y: y\n```\n\nNow we are ready to run `gerk()` and plot its output:\n\n```python\nimport matplotlib.pyplot as plt\nfrom gerk import gerk\n\nx, y = gerk(\n        a=a, \n        b=b, \n        c=c, \n        initial=(0, 1), \n        timesteps=10000, \n        terminal=1,\n        func=lambda x, y: y,\n    )\n\nplt.plot(x, y, color=\"r\")\nplt.show()\n```\n\nThe code above yields the following graph:\n\n<img width=\"500\" alt=\"gerk_1\" src=https://github.com/user-attachments/assets/b17a9a2b-8286-464a-a0aa-9a72f6f0a9d2>\n\n## Adaptive Runge-Kutta Methods\n\nThere is an alternate way to utilise the Runge-Kutta method by employing an additional distinct $b$ array. The Butcher tableau for such methods take the form:\n\n<img width=\"337\" alt=\"adaptive_butcher\" src=\"https://github.com/user-attachments/assets/855c531c-a75c-485b-9f30-2f6b2a379abe\">\n\nwhere $b_1$ and $b_2$ are the two distinct $b$ arrays.\n\nThis method is not too disimilar to the original Runge-Kutta method. We calculate the $k$'s in the same way as before, but there is an extra step when evaluating $y_{n+1}$. \n\nAlthough we do calculate $y_{n+1}$ in same way outlined above, we also calculate $\\gamma_{n+1}$:\n\n$$\ny_{n+1} = y_{n} + h \\sum_{i=1}^{r}b_{1i}\\cdot k_{i}(x_n, y_n) \\ \\ \\ \\ \\ \\ \\ \\ \\ \\gamma_{n+1} = y_{n} + h \\sum_{i=1}^{r} b_{2i}\\cdot k_{i}(x_n, y_n)\n$$\n\n_Note_ that the calculation for $\\gamma$ requires the use of $y_n$ and **not** $\\gamma_n$.\n\nFor every time step, we calculate the following error:\n\n$$\nE := \\left|y_{n+1}-\\gamma_{n+1}\\right|\n$$\n\nNow we define the tolerance, $\\mathcal{E}$, which will act as the maximum acceptable value for $E$.\n\nIf $E<\\mathcal{E}$, then we accept the value of $y_{n+1}$ and we increment $x_{n}$ by $h$ and start the process again for $x_{n+1}$ and $y_{n+1}$ as normal. \n\nHowever, if $E\\geq\\mathcal{E}$, we will need to adjust the value of $h$ and redo the calculation with this renewed time step value in an attempt to satisfy the condition $E<\\mathcal{E}$. \n\nThe value of $h$ will be adjusted as follows:\n\n$$\nh \\rightarrow 0.9\\cdot h \\cdot\\sqrt[n]{\\frac{h}{\\mathcal{E}}}\n$$\n\nwhere $n=\\min\\left(p,q\\right)$, where $p$ and $q$ are the orders $^1$ of $b_i$ and $b^*_i$ respectively.\n\n$^1$ A Runge-Kutta method with matrix $a_{ij}$ and arrays $b$ and $c$ has order $p$ if\n\n$$\n\\sum_{i=1}^{p}b_i = 1 \\ \\ \\ \\ \\sum_{i=1}^{p}b_ic_i = 1/2 \\ \\ \\ \\ \\sum_{j=1}^{p}a_{ij} = c_i  \\ \\ \\ \\ \n$$\n\n## Adaptive Runge-Kutta example\n\nIn this example, we will try to numerically integrate\n\n$$\n\\frac{\\text{d}y}{\\text{d}x}=-2xy\n$$\n\nwith initial conditions $(-1, e^{-1})$. Note that the exact solution is $y=e^{-x^2}$.\n\nHere we will use the Bogacki\u2013Shampine (BS23) method which has the following Butcher tableau:\n\n<img width=\"247\" alt=\"adapt_butcher\" src=\"https://github.com/user-attachments/assets/95a88663-cfce-4654-ae14-5fcff6057da2\">\n\nFor the adaptive Runge-Kutta method, we will use `adaptive_gerk()`. This method's paramters vary slightly from `gerk()`:\n\n- `a` The $A$ matrix in the Butcher tableau. This **must** be a lower triangular matrix that is formatted as a list of lists that contain floats, or integers\n- `b_1` The $b_\uff11$ array. Must be a list of floats, decimals or integers\n- `b_2` The $b_2$ array. Must be a list of floats, decimals or integers\n- `c` The $c$ array. Must be a list of floats, decimals or integers\n- `initial` A `tuple` that acts as the coordinate of the initial condition values $(x_0, y_0)$\n- `terminal` The value of $x$ for which we terminate the Runge-Kutta method\n- `timesteps` The number of times steps you want to apply on the from the starting point $x_0$ to `final`. Must be an integer\n- `func` The function expression to be numerically integrated\n- `enforce_rules` (Optional) A boolean to enforce conventional Runge-Kutta rules. Defaulted to `False`\n- `tolerance` (Optional) A float representing the maximum threshold of the adaptive step. Defaulted to `1e-4`\n\nSimilar to `gerk()`, this function will output the time steps and approximated y values as a tuple of lists of floats.\n\n```python\nfrom math import exp\nimport matplotlib.pyplot as plt\nfrom gerk import adaptive_gerk\n\na = [\n    [1/2],\n    [0, 3/4],\n    [2/9, 1/3, 4/9]\n]\nb_1 = [2/9, 1/3, 4/9, 0]\nb_2 = [7/24, 1/4, 1/3, 1/8]\nc = [0, 1/2, 3/4, 1]\n\nx, y = adaptive_gerk(\n        a=a, \n        b_1=b_1, \n        b_2=b_2, \n        c=c, \n        initial=(-1, exp(-1)), \n        timesteps=10000, \n        terminal=1,\n        func=lambda x, y: -2 * x * y,\n    )\n\nplt.plot(x, y, color=\"r\")\nplt.show()\n```\n\nThe code above yields the following graph:\n\n<img width=\"500\" alt=\"gerk_2\" src=https://github.com/user-attachments/assets/a472aafa-b096-444c-b0b7-86afb988a3c2>\n\n## In the pipeline\n\n* To further generalise the Runge-Kutta method with an indefinite number of $b$ and $c$ arrays\n* Implement *Cython* for faster execution times\n* More descriptive error messages\n* Add unit tests\n* Implement Stochastic Runge-Kutta method\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Generalized Explicit Runge-Kutta",
    "version": "1.0.2",
    "project_urls": null,
    "split_keywords": [
        "runge-kutta",
        " runge",
        " kutta",
        " numerical",
        " integration",
        " approximation"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "dd4754e63ce147509fac4d7cabe0f923a8caf68f910184343e47d60a5e31a74f",
                "md5": "7dd9abe12194386c8d619c4dbd8a965e",
                "sha256": "08f881af5a9ceefe51d07b8dace8a316cfcfed6c5d28ab41342e99e4f6c22e3d"
            },
            "downloads": -1,
            "filename": "gerk-1.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7dd9abe12194386c8d619c4dbd8a965e",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 7631,
            "upload_time": "2024-11-14T15:30:35",
            "upload_time_iso_8601": "2024-11-14T15:30:35.127609Z",
            "url": "https://files.pythonhosted.org/packages/dd/47/54e63ce147509fac4d7cabe0f923a8caf68f910184343e47d60a5e31a74f/gerk-1.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ccb98b2aca607028c252fb2b1f604a2b8f6fc9aea3f89de25f623686574b54b9",
                "md5": "8bf06a33fab9d48725fb35fd6ee66486",
                "sha256": "048249fd7fc17d78187d558ec3c5bbf97ecb7508f203ac0969e000bb8978a667"
            },
            "downloads": -1,
            "filename": "gerk-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "8bf06a33fab9d48725fb35fd6ee66486",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 6809,
            "upload_time": "2024-11-14T15:30:36",
            "upload_time_iso_8601": "2024-11-14T15:30:36.921533Z",
            "url": "https://files.pythonhosted.org/packages/cc/b9/8b2aca607028c252fb2b1f604a2b8f6fc9aea3f89de25f623686574b54b9/gerk-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-14 15:30:36",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "gerk"
}
        
Elapsed time: 4.39331s