diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml
index 46040a1ae..45f89248b 100644
--- a/.github/workflows/pypi.yml
+++ b/.github/workflows/pypi.yml
@@ -7,7 +7,7 @@ on:
jobs:
publish:
- uses: N3PDF/workflows/.github/workflows/python-poetry-pypi.yml@v2
+ uses: NNPDF/workflows/.github/workflows/python-poetry-pypi.yml@v2
secrets:
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
with:
diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml
index 2eaf74cdc..b118179fc 100644
--- a/.github/workflows/unittests.yml
+++ b/.github/workflows/unittests.yml
@@ -9,7 +9,7 @@ jobs:
python-version: ["3.9", "3.10", "3.11", "3.12"]
fail-fast: false
- uses: N3PDF/workflows/.github/workflows/python-poetry-tests.yml@v2
+ uses: NNPDF/workflows/.github/workflows/python-poetry-tests.yml@v2
with:
python-version: ${{ matrix.python-version }}
poetry-extras: "-E mark -E box"
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 8d65e5c90..6a799f3f3 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -19,7 +19,7 @@ repos:
- id: pycln
args: [--config=pyproject.toml]
- repo: https://github.com/psf/black-pre-commit-mirror
- rev: 24.4.0
+ rev: 24.4.2
hooks:
- id: black
- repo: https://github.com/asottile/blacken-docs
@@ -62,6 +62,6 @@ repos:
files: ^crates/ekore/.*\.rs$
args: []
- repo: https://github.com/pre-commit/pre-commit
- rev: v3.7.0
+ rev: v3.7.1
hooks:
- id: validate_manifest
diff --git a/benchmarks/ekore/benchmark_ad.py b/benchmarks/ekore/benchmark_pegasus_ad_us_as2.py
similarity index 87%
rename from benchmarks/ekore/benchmark_ad.py
rename to benchmarks/ekore/benchmark_pegasus_ad_us_as2.py
index ac0b50ad0..ebc53e3ae 100644
--- a/benchmarks/ekore/benchmark_ad.py
+++ b/benchmarks/ekore/benchmark_pegasus_ad_us_as2.py
@@ -1,4 +1,7 @@
-"""Benchmark the NLO anomalous dimensions against PEGASUS"""
+"""Benchmark the unpolarized NLO anomalous dimensions against PEGASUS.
+
+Recall that we obtained our representation not from PEGASUS, but derived it
+ourselves (see comment there)."""
import numpy as np
import pytest
@@ -8,39 +11,6 @@
from eko.constants import CA, CF, TR, zeta2, zeta3
-@pytest.mark.isolated
-def benchmark_melling_g3_pegasus():
- for N in [1, 2, 3, 4, 1 + 1j, 1 - 1j, 2 + 1j, 3 + 1j]:
- check_melling_g3_pegasus(N)
-
-
-def check_melling_g3_pegasus(N):
- S1 = h.S1(N)
- N1 = N + 1.0
- N2 = N + 2.0
- N3 = N + 3.0
- N4 = N + 4.0
- N5 = N + 5.0
- N6 = N + 6.0
- S11 = S1 + 1.0 / N1
- S12 = S11 + 1.0 / N2
- S13 = S12 + 1.0 / N3
- S14 = S13 + 1.0 / N4
- S15 = S14 + 1.0 / N5
- S16 = S15 + 1.0 / N6
-
- SPMOM = (
- 1.0000 * (zeta2 - S1 / N) / N
- - 0.9992 * (zeta2 - S11 / N1) / N1
- + 0.9851 * (zeta2 - S12 / N2) / N2
- - 0.9005 * (zeta2 - S13 / N3) / N3
- + 0.6621 * (zeta2 - S14 / N4) / N4
- - 0.3174 * (zeta2 - S15 / N5) / N5
- + 0.0699 * (zeta2 - S16 / N6) / N6
- )
- np.testing.assert_allclose(h.g_functions.mellin_g3(N, S1), SPMOM)
-
-
@pytest.mark.isolated
def benchmark_gamma_ns_1_pegasus():
# remember that singlet has pole at N=1
@@ -54,7 +24,6 @@ def check_gamma_1_pegasus(N, NF):
ZETA2 = zeta2
ZETA3 = zeta3
- # N = np.random.rand(1) + np.random.rand(1) * 1j
S1 = h.S1(N)
S2 = h.S2(N)
diff --git a/benchmarks/ekore/benchmark_pegasus_mellin.py b/benchmarks/ekore/benchmark_pegasus_mellin.py
new file mode 100644
index 000000000..addefe421
--- /dev/null
+++ b/benchmarks/ekore/benchmark_pegasus_mellin.py
@@ -0,0 +1,41 @@
+"""Benchmark the Mellin transforms against PEGASUS."""
+
+import numpy as np
+import pytest
+
+import ekore.anomalous_dimensions.unpolarized.space_like.as2 as ad_as2
+import ekore.harmonics as h
+from eko.constants import CA, CF, TR, zeta2, zeta3
+
+
+@pytest.mark.isolated
+def benchmark_melling_g3_pegasus():
+ for N in [1, 2, 3, 4, 1 + 1j, 1 - 1j, 2 + 1j, 3 + 1j]:
+ check_melling_g3_pegasus(N)
+
+
+def check_melling_g3_pegasus(N):
+ S1 = h.S1(N)
+ N1 = N + 1.0
+ N2 = N + 2.0
+ N3 = N + 3.0
+ N4 = N + 4.0
+ N5 = N + 5.0
+ N6 = N + 6.0
+ S11 = S1 + 1.0 / N1
+ S12 = S11 + 1.0 / N2
+ S13 = S12 + 1.0 / N3
+ S14 = S13 + 1.0 / N4
+ S15 = S14 + 1.0 / N5
+ S16 = S15 + 1.0 / N6
+
+ SPMOM = (
+ 1.0000 * (zeta2 - S1 / N) / N
+ - 0.9992 * (zeta2 - S11 / N1) / N1
+ + 0.9851 * (zeta2 - S12 / N2) / N2
+ - 0.9005 * (zeta2 - S13 / N3) / N3
+ + 0.6621 * (zeta2 - S14 / N4) / N4
+ - 0.3174 * (zeta2 - S15 / N5) / N5
+ + 0.0699 * (zeta2 - S16 / N6) / N6
+ )
+ np.testing.assert_allclose(h.g_functions.mellin_g3(N, S1), SPMOM)
diff --git a/benchmarks/ekore/benchmark_pegasus_ome_ps_as2.py b/benchmarks/ekore/benchmark_pegasus_ome_ps_as2.py
new file mode 100644
index 000000000..66b471c57
--- /dev/null
+++ b/benchmarks/ekore/benchmark_pegasus_ome_ps_as2.py
@@ -0,0 +1,199 @@
+"""Benchmark the polarized NNLO OME against PEGASUS"""
+
+import numpy as np
+import pytest
+
+import ekore.harmonics as h
+import ekore.operator_matrix_elements.polarized.space_like.as2 as ome_as2
+from eko.constants import CA, CF, TR, zeta2, zeta3
+
+
+@pytest.mark.isolated
+def benchmark_pegasus_ome_ps_as2():
+ # remember that singlet has pole at N=1
+ for N in [2, 3, 4, +1j, -1j, +1j, +1j]:
+ for NF in [3, 4, 5]:
+ check_pegasus_ome_ps_as2_s(N, NF)
+
+
+def check_pegasus_ome_ps_as2_s(N, NF):
+ # Test against pegasus implementation by Ignacio Borsa
+ ZETA2 = zeta2
+ ZETA3 = zeta3
+
+ S1 = h.S1(N)
+ S2 = h.S2(N)
+ S3 = h.S3(N)
+ #
+ NM = N - 1.0
+ N1 = N + 1.0
+ N2 = N + 2.0
+ NI = 1.0 / N
+ NMI = 1.0 / NM
+ N1I = 1.0 / N1
+ N2I = 1.0 / N2
+ #
+ S1M = S1 - NI
+ S2M = S2 - NI * NI
+ S3M = S3 - NI**3
+ S11 = S1 + N1I
+ S21 = S2 + N1I * N1I
+ S31 = S3 + N1I**3
+ S22 = S21 + N2I * N2I
+ ACG3 = h.g_functions.mellin_g3(N1, S11)
+ #
+ # CALL BET(N1,V1)
+ # CALL BET1(N1,V2)
+ # CALL BET2(N1,V3)
+ # CALL BET3(N1,V4)
+ V1 = (
+ h.polygamma.cern_polygamma((N1 + 1.0) / 2.0, 0)
+ - h.polygamma.cern_polygamma(N1 / 2.0, 0)
+ ) / 2.0
+ V2 = (
+ h.polygamma.cern_polygamma((N1 + 1.0) / 2.0, 1)
+ - h.polygamma.cern_polygamma(N1 / 2.0, 1)
+ ) / 4.0
+ V3 = (
+ h.polygamma.cern_polygamma((N1 + 1.0) / 2.0, 2)
+ - h.polygamma.cern_polygamma(N1 / 2.0, 2)
+ ) / 8.0
+ #
+ #
+ # ..The moments of the OME's DA_Hq^{PS,(2)} and DA_Hg^{S,(2)} given in
+ # Eqs. (138) and (111) of BBDKS. Note that for the former, an
+ # additional finite renormalization is needed to go from the Larin
+ # to the the M scheme
+ #
+ #
+ # ... Anomalous dimension terms
+ #
+ G0QG_HAT = -8 * TR * NM / N / N1
+ #
+ G0GQ = -4 * CF * N2 / N / N1
+ #
+ G0QQ = -CF * (2 * (2.0 + 3.0 * N + 3.0 * N**2) / N / N1 - 8.0 * S1)
+ #
+ # ... Polinomials in N
+ POL1 = (
+ 12 * N**8 + 52 * N**7 + 60 * N**6 - 25 * N**4 - 2 * N**3 + 3 * N**2 + 8 * N + 4
+ )
+ #
+ POL2 = (
+ 2.0 * N**8
+ + 10.0 * N**7
+ + 22.0 * N**6
+ + 36.0 * N**5
+ + 29.0 * N**4
+ + 4.0 * N**3
+ + 33.0 * N**2
+ + 12.0 * N
+ + 4
+ )
+ #
+ POLR3 = 15 * N**6 + 45 * N**5 + 374 * N**4 + 601 * N**3 + 161 * N**2 - 24 * N + 36
+ #
+ POLR8 = (
+ -15 * N**8
+ - 60 * N**7
+ - 82 * N**6
+ - 44 * N**5
+ - 15 * N**4
+ - 4 * N**2
+ - 12 * N
+ - 8
+ )
+ #
+ # ... Finite renormalization term from Larin to M scheme
+ #
+ ZQQPS = -CF * TR * 8 * N2 * (N**2 - N - 1.0) / N**3 / N1**3
+ #
+ A2HQ = (
+ -4
+ * CF
+ * TR
+ * N2
+ / N**2
+ / N1**2
+ * (NM * (2 * S2 + ZETA2) - (4 * N**3 - 4 * N**2 - 3 * N - 1) / N**2 / N1**2)
+ + ZETA2 / 8 * G0QG_HAT * G0GQ
+ )
+ #
+ #
+ A2HG = (
+ CF
+ * TR
+ * (
+ 4.0
+ / 3
+ * NM
+ / N
+ / N1
+ * (-4.0 * S3 + S1**3 + 3.0 * S1 * S2 + 6.0 * S1 * ZETA2)
+ - 4
+ * (N**4 + 17.0 * N**3 + 43.0 * N**2 + 33.0 * N + 2)
+ * S2
+ / N**2
+ / N1**2
+ / N2
+ - 4 * (3.0 * N**2 + 3.0 * N - 2) * S1**2 / N**2 / N1 / N2
+ - 2 * NM * (3.0 * N**2 + 3.0 * N + 2) * ZETA2 / N**2 / N1**2
+ - 4 * (N**3 - 2.0 * N**2 - 22.0 * N - 36) * S1 / N**2 / N1 / N2
+ - 2 * POL1 / N**4 / N1**4 / N2
+ )
+ + CA
+ * TR
+ * (
+ 4 * (N**2 + 4.0 * N + 5) * S1**2 / N / N1**2 / N2
+ + 4 * (7.0 * N**3 + 24.0 * N**2 + 15.0 * N - 16) * S2 / N**2 / N1**2 / N2
+ + 8 * NM * N2 * ZETA2 / N**2 / N1**2
+ + 4 * (N**4 + 4.0 * N**3 - N**2 - 10.0 * N + 2) * S1 / N / N1**3 / N2
+ - 4 * POL2 / N**4 / N1**4 / N2
+ - 16 * NM / N / N1**2 * V2
+ + 4
+ * NM
+ / 3.0
+ / N
+ / N1
+ * (
+ 12.0 * ACG3
+ + 3.0 * V3
+ - 8.0 * S3
+ - S1**3
+ - 9.0 * S1 * S2
+ - 12.0 * S1 * V2
+ - 12.0 * V1 * ZETA2
+ - 3.0 * ZETA3
+ )
+ )
+ # ... added simplified Gamma0_gg+2*beta0
+ + 1 / 8 * G0QG_HAT * (8 * CA * (-2.0 / N / N1 + S1) - G0QQ)
+ )
+ #
+ # ..The moments of the OME's DA_{gq,H}^{S,(2)} and DA_{gg,H}^{S,(2)}
+ # given in Eqs. (175) and (188) of Bierenblaum et al.
+ #
+ A2GQ = (
+ CF
+ * TR
+ * N2
+ * (
+ 8 * (22.0 + 41.0 * N + 28.0 * N**2) / 27.0 / N / N1**3
+ - 8 * (2.0 + 5.0 * N) * S1 / 9.0 / N / N1**2
+ + 4 * (S1**2 + S2) / 3.0 / N / N1
+ )
+ )
+ #
+ A2GG = (
+ CA
+ * TR
+ * (2 * POLR3 / 27.0 / N**3 / N1**3 - 4 * (47.0 + 56.0 * N) * S1 / 27.0 / N1)
+ + CF * TR * POLR8 / N**4 / N1**4
+ )
+
+ cache = h.cache.reset()
+ omeS2 = ome_as2.A_singlet(N, cache, 0.0, NF)
+ np.testing.assert_allclose(omeS2[0, 0], A2GG, err_msg=f"gg,{N=}")
+ np.testing.assert_allclose(omeS2[0, 1], A2GQ, err_msg=f"gq,{N=}")
+ np.testing.assert_allclose(omeS2[2, 1], A2HQ + NF * ZQQPS, err_msg=f"hq,{N=}")
+ np.testing.assert_allclose(omeS2[2, 0], A2HG, err_msg=f"hg,{N=}")
diff --git a/crates/Cargo.lock b/crates/Cargo.lock
index b6d5d084d..0e6acc14f 100644
--- a/crates/Cargo.lock
+++ b/crates/Cargo.lock
@@ -36,7 +36,6 @@ name = "eko"
version = "0.1.0"
dependencies = [
"ekore",
- "katexit",
"num",
]
@@ -46,7 +45,6 @@ version = "0.1.0"
dependencies = [
"float-cmp",
"hashbrown",
- "katexit",
"num",
]
@@ -69,17 +67,6 @@ dependencies = [
"allocator-api2",
]
-[[package]]
-name = "katexit"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb1304c448ce2c207c2298a34bc476ce7ae47f63c23fa2b498583b26be9bc88c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "num"
version = "0.4.1"
@@ -162,41 +149,6 @@ version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
-[[package]]
-name = "proc-macro2"
-version = "1.0.66"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "syn"
-version = "1.0.109"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
-
[[package]]
name = "version_check"
version = "0.9.4"
diff --git a/crates/eko/Cargo.toml b/crates/eko/Cargo.toml
index 50aee6504..731e1399c 100644
--- a/crates/eko/Cargo.toml
+++ b/crates/eko/Cargo.toml
@@ -3,11 +3,13 @@ name = "eko"
version = "0.1.0"
edition = "2021"
+[package.metadata.docs.rs]
+rustdoc-args = [ "--html-in-header", "../katex-header.html" ]
+
[lib]
name = "ekors"
crate-type = ["cdylib"]
[dependencies]
num = "0.4.1"
-katexit = "0.1.4"
ekore = { version = "0.1.0", path = "../ekore" }
diff --git a/crates/eko/src/mellin.rs b/crates/eko/src/mellin.rs
index 5afc96f5f..f2f968fe4 100644
--- a/crates/eko/src/mellin.rs
+++ b/crates/eko/src/mellin.rs
@@ -6,7 +6,6 @@
use num::complex::Complex;
use std::f64::consts::PI;
-#[cfg_attr(doc, katexit::katexit)]
/// Talbot inversion path.
///
/// Implements the algorithm presented in [\[Abate\]](crate::bib::Abate).
diff --git a/crates/ekore/Cargo.toml b/crates/ekore/Cargo.toml
index ef8499dba..9dfdb7515 100644
--- a/crates/ekore/Cargo.toml
+++ b/crates/ekore/Cargo.toml
@@ -5,10 +5,12 @@ edition = "2021"
description = "EKO expressions"
license = "GPL-3.0-or-later"
+[package.metadata.docs.rs]
+rustdoc-args = [ "--html-in-header", "../katex-header.html" ]
+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
num = "0.4.1"
float-cmp = "0.9.0"
-katexit = "0.1.4"
hashbrown = "0.14"
diff --git a/crates/ekore/src/constants.rs b/crates/ekore/src/constants.rs
index 6f345de27..39d69f975 100644
--- a/crates/ekore/src/constants.rs
+++ b/crates/ekore/src/constants.rs
@@ -1,24 +1,20 @@
//! Global constants.
-#[cfg_attr(doc, katexit::katexit)]
/// The number of colors.
///
/// Defaults to $N_C = 3$.
pub const NC: u8 = 3;
-#[cfg_attr(doc, katexit::katexit)]
/// The normalization of fundamental generators.
///
/// Defaults to $T_R = 1/2$.
pub const TR: f64 = 1.0 / 2.0;
-#[cfg_attr(doc, katexit::katexit)]
/// Second Casimir constant in the adjoint representation.
///
/// Defaults to $C_A = N_C = 3$.
pub const CA: f64 = NC as f64;
-#[cfg_attr(doc, katexit::katexit)]
/// Second Casimir constant in the fundamental representation.
///
/// Defaults to $C_F = \frac{N_C^2-1}{2N_C} = 4/3$.
diff --git a/crates/ekore/src/harmonics/cache.rs b/crates/ekore/src/harmonics/cache.rs
index 3bae9755c..d3e9142a5 100644
--- a/crates/ekore/src/harmonics/cache.rs
+++ b/crates/ekore/src/harmonics/cache.rs
@@ -5,7 +5,6 @@ use num::{complex::Complex, Zero};
use crate::harmonics::{g_functions, w1, w2, w3};
-#[cfg_attr(doc, katexit::katexit)]
/// List of available elements.
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum K {
diff --git a/crates/ekore/src/harmonics/polygamma.rs b/crates/ekore/src/harmonics/polygamma.rs
index c6e8f9a39..be1bf2cc2 100644
--- a/crates/ekore/src/harmonics/polygamma.rs
+++ b/crates/ekore/src/harmonics/polygamma.rs
@@ -3,7 +3,6 @@
use num::{complex::Complex, Zero};
use std::f64::consts::PI;
-#[cfg_attr(doc, katexit::katexit)]
/// Compute the polygamma functions $\psi_k(z)$.
///
/// Reimplementation of ``WPSIPG`` (C317) in [CERNlib](http://cernlib.web.cern.ch/cernlib/) given by [[KOLBIG1972221]][crate::bib::KOLBIG1972221].
diff --git a/crates/katex-header.html b/crates/katex-header.html
new file mode 100644
index 000000000..ff018b9c3
--- /dev/null
+++ b/crates/katex-header.html
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/poetry.lock b/poetry.lock
index 9a187b67b..0e7243979 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
[[package]]
name = "alabaster"
@@ -1043,13 +1043,13 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"]
[[package]]
name = "jinja2"
-version = "3.1.3"
+version = "3.1.4"
description = "A very fast and expressive template engine."
optional = false
python-versions = ">=3.7"
files = [
- {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
- {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
+ {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
+ {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
]
[package.dependencies]
@@ -2358,6 +2358,7 @@ files = [
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
+ {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
@@ -2365,8 +2366,16 @@ files = [
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
+ {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
+ {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
+ {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
+ {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
+ {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
+ {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
+ {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
+ {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
@@ -2383,6 +2392,7 @@ files = [
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
+ {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
@@ -2390,6 +2400,7 @@ files = [
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
+ {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
diff --git a/pyproject.toml.patch b/pyproject.toml.patch
index 7fb6fd672..8e9119a23 100644
--- a/pyproject.toml.patch
+++ b/pyproject.toml.patch
@@ -1,5 +1,5 @@
diff --git a/pyproject.toml b/pyproject.toml
-index 31be6cb0..b4ec7c95 100644
+index 7404d871..a1e3ae66 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,20 @@
@@ -25,12 +25,13 @@ index 31be6cb0..b4ec7c95 100644
[tool.poetry]
name = "eko"
-@@ -124,6 +138,11 @@ asv-publish = "asv publish --config benchmarks/asv.conf.json"
+@@ -124,6 +138,12 @@ asv-publish = "asv publish --config benchmarks/asv.conf.json"
asv-show = "asv show --config benchmarks/asv.conf.json"
asv-clean = { "shell" = "rm -rf benchmarks/env benchmarks/html benchmarks/results" }
asv = ["asv-run", "asv-publish", "asv-preview"]
+compile = "pip install -e crates/eko/"
-+rdocs = "cargo doc --workspace --manifest-path crates/Cargo.toml --no-deps"
++rdocs.cmd = "cargo doc --workspace --manifest-path crates/Cargo.toml --no-deps"
++rdocs.env = { RUSTDOCFLAGS = "--html-in-header katex-header.html" }
+rdocs-view = "xdg-open crates/target/doc/ekors/index.html"
+rdocs-clean = "rm -rf crates/target/doc/"
+rtest = "cargo test --workspace --manifest-path crates/Cargo.toml"
diff --git a/rustify.sh b/rustify.sh
index 27339c00d..7e99996f0 100755
--- a/rustify.sh
+++ b/rustify.sh
@@ -1,7 +1,9 @@
#!/usr/bin/bash
+# git diff --merge-base master pyproject.toml > pyproject.toml.patch
patch -p1 src/eko/evolution_operator/__init__.py.patch
patch -p1