lme-python 0.1.2__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lme_python-0.1.4/.github/workflows/benchmarks.yml +234 -0
- lme_python-0.1.4/.github/workflows/repo-metadata.yml +35 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/.gitignore +4 -0
- lme_python-0.1.4/BENCHMARKS.md +183 -0
- lme_python-0.1.4/CHANGELOG.md +72 -0
- lme_python-0.1.4/CONTRIBUTING.md +91 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/Cargo.lock +1 -1
- {lme_python-0.1.2 → lme_python-0.1.4}/Cargo.toml +31 -2
- lme_python-0.1.4/GUIDE.md +412 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/PKG-INFO +1 -1
- lme_python-0.1.4/README.md +98 -0
- lme_python-0.1.4/RELEASING.md +185 -0
- lme_python-0.1.4/benches/bench_math.rs +898 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/COMPARISONS.md +12 -12
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/glmm_cbpp.R +4 -4
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/glmm_grouseticks.R +4 -4
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_pastes.R +4 -4
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/sleepstudy.R +4 -4
- lme_python-0.1.4/docs/benchmarks/app.js +207 -0
- lme_python-0.1.4/docs/benchmarks/index.html +92 -0
- lme_python-0.1.4/docs/benchmarks/styles.css +305 -0
- lme_python-0.1.4/docs/index.html +63 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/python/Cargo.lock +2 -2
- {lme_python-0.1.2 → lme_python-0.1.4}/python/Cargo.toml +1 -1
- lme_python-0.1.4/python/PYTHON_GUIDE.md +265 -0
- lme_python-0.1.4/python/examples/glmer_cbpp.py +92 -0
- lme_python-0.1.4/python/examples/glmer_grouseticks.py +99 -0
- lme_python-0.1.4/python/examples/lm_basics.py +84 -0
- lme_python-0.1.4/python/examples/lmer_sleepstudy.py +96 -0
- lme_python-0.1.4/python/examples/model_comparison.py +117 -0
- lme_python-0.1.4/python/src/lib.rs +642 -0
- lme_python-0.1.4/python/tests/test_basic.py +406 -0
- lme_python-0.1.4/scripts/build_benchmark_site.py +210 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/scripts/plot_comparisons.py +2 -2
- lme_python-0.1.4/scripts/run_cross_language_benchmarks.py +348 -0
- lme_python-0.1.4/scripts/sync_github_repo_metadata.py +161 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/src/family.rs +2 -2
- {lme_python-0.1.2 → lme_python-0.1.4}/src/glmm_math.rs +57 -9
- {lme_python-0.1.2 → lme_python-0.1.4}/src/lib.rs +198 -18
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_confint_simulate.rs +51 -1
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_glmm.rs +47 -0
- lme_python-0.1.2/CHANGELOG.md +0 -21
- lme_python-0.1.2/GUIDE.md +0 -490
- lme_python-0.1.2/README.md +0 -101
- lme_python-0.1.2/benches/bench_math.rs +0 -240
- lme_python-0.1.2/python/PYTHON_GUIDE.md +0 -322
- lme_python-0.1.2/python/src/lib.rs +0 -201
- lme_python-0.1.2/python/tests/test_basic.py +0 -164
- {lme_python-0.1.2 → lme_python-0.1.4}/.github/workflows/ci.yml +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/.github/workflows/python-release.yml +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/LICENSE +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/comparison_chart.png +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/glmm_cbpp.jl +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/glmm_cbpp.py +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/glmm_cbpp.rs +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/glmm_grouseticks.jl +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/glmm_grouseticks.py +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/glmm_grouseticks.rs +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_dyestuff.R +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_dyestuff.jl +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_dyestuff.py +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_dyestuff.rs +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_pastes.jl +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_pastes.py +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_pastes.rs +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_penicillin.R +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_penicillin.jl +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_penicillin.py +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/lmm_penicillin.rs +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/sleepstudy.jl +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/sleepstudy.py +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/sleepstudy.rs +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/sleepstudy_ml.R +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/sleepstudy_ml.jl +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/sleepstudy_ml.py +0 -0
- {lme_python-0.1.2/examples → lme_python-0.1.4/comparisons}/sleepstudy_ml.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/pyproject.toml +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/scripts/ast_explorations/test_fiasto.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/scripts/ast_explorations/test_fiasto_offset.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/scripts/dump_dyestuff.R +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/scripts/dump_pastes.R +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/scripts/make_penicillin_csv.py +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/src/anova.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/src/formula.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/src/kenward_roger.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/src/math.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/src/model_matrix.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/src/optimizer.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/src/robust.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/src/satterthwaite.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/cbpp_binary.csv +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/dyestuff.csv +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/glmm_binomial.json +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/glmm_poisson.json +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/grouseticks.csv +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/intercept_only.json +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/mock_crossed.json +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/mock_ml.json +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/pastes.csv +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/penicillin.csv +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/penicillin.json +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/random_slopes.json +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/data/sleepstudy.csv +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/generate_mock_data.py +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/generate_test_data.R +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_anova.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_conditional_real.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_coverage_edge_cases.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_coverage_gaps.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_crossed_mock.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_e2e_lmer.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_edge_cases.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_errors.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_formula.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_gaps.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_intercept_only.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_kenward_roger.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_ml_optimization.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_no_intercept.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_numerical_parity.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_predict.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_random_slopes.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_robust.rs +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_sandwich_math.R +0 -0
- {lme_python-0.1.2 → lme_python-0.1.4}/tests/test_satterthwaite.rs +0 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
name: Benchmarks
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
warmups:
|
|
7
|
+
description: Warmup runs per benchmark command
|
|
8
|
+
required: true
|
|
9
|
+
default: "1"
|
|
10
|
+
repeats:
|
|
11
|
+
description: Measured runs per benchmark command
|
|
12
|
+
required: true
|
|
13
|
+
default: "3"
|
|
14
|
+
push:
|
|
15
|
+
tags:
|
|
16
|
+
- "v*"
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: write
|
|
20
|
+
pages: write
|
|
21
|
+
id-token: write
|
|
22
|
+
|
|
23
|
+
env:
|
|
24
|
+
CARGO_TERM_COLOR: always
|
|
25
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
26
|
+
JULIA_VERSION: "1.10.11"
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
criterion:
|
|
30
|
+
name: Criterion Benchmarks
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v6
|
|
34
|
+
|
|
35
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
36
|
+
|
|
37
|
+
- name: Install OpenBLAS
|
|
38
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
39
|
+
|
|
40
|
+
- name: Cache cargo registry and build outputs
|
|
41
|
+
uses: actions/cache@v5
|
|
42
|
+
with:
|
|
43
|
+
path: |
|
|
44
|
+
~/.cargo/registry
|
|
45
|
+
~/.cargo/git
|
|
46
|
+
target
|
|
47
|
+
key: ${{ runner.os }}-bench-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
48
|
+
restore-keys: ${{ runner.os }}-bench-cargo-
|
|
49
|
+
|
|
50
|
+
- name: Run Criterion benchmarks
|
|
51
|
+
run: cargo bench
|
|
52
|
+
|
|
53
|
+
- name: Package Criterion baseline
|
|
54
|
+
run: |
|
|
55
|
+
mkdir -p benchmark-results
|
|
56
|
+
tar -czf "benchmark-results/criterion-${{ github.sha }}.tar.gz" target/criterion
|
|
57
|
+
|
|
58
|
+
- name: Upload Criterion artifact
|
|
59
|
+
uses: actions/upload-artifact@v7
|
|
60
|
+
with:
|
|
61
|
+
name: criterion-${{ github.sha }}
|
|
62
|
+
path: benchmark-results/criterion-${{ github.sha }}.tar.gz
|
|
63
|
+
|
|
64
|
+
- name: Attach Criterion artifact to GitHub Release
|
|
65
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
66
|
+
env:
|
|
67
|
+
GH_TOKEN: ${{ github.token }}
|
|
68
|
+
run: |
|
|
69
|
+
gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1 || {
|
|
70
|
+
if [[ "${GITHUB_REF_NAME}" == *-* ]]; then
|
|
71
|
+
gh release create "${GITHUB_REF_NAME}" --title "${GITHUB_REF_NAME}" --prerelease --latest=false
|
|
72
|
+
else
|
|
73
|
+
gh release create "${GITHUB_REF_NAME}" --title "${GITHUB_REF_NAME}"
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
gh release upload "${GITHUB_REF_NAME}" "benchmark-results/criterion-${{ github.sha }}.tar.gz" --clobber
|
|
77
|
+
|
|
78
|
+
cross-language:
|
|
79
|
+
name: Cross-Language Benchmarks
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
env:
|
|
82
|
+
BENCH_WARMUPS: ${{ github.event_name == 'workflow_dispatch' && inputs.warmups || '1' }}
|
|
83
|
+
BENCH_REPEATS: ${{ github.event_name == 'workflow_dispatch' && inputs.repeats || '3' }}
|
|
84
|
+
R_LIBS_USER: ${{ github.workspace }}/.r-lib
|
|
85
|
+
steps:
|
|
86
|
+
- uses: actions/checkout@v6
|
|
87
|
+
|
|
88
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
89
|
+
|
|
90
|
+
- uses: actions/setup-python@v6
|
|
91
|
+
with:
|
|
92
|
+
python-version: "3.11"
|
|
93
|
+
|
|
94
|
+
- name: Install system dependencies
|
|
95
|
+
run: |
|
|
96
|
+
sudo apt-get update
|
|
97
|
+
sudo apt-get install -y libopenblas-dev libcurl4-openssl-dev libssl-dev libxml2-dev r-base
|
|
98
|
+
curl -fsSL "https://julialang-s3.julialang.org/bin/linux/x64/1.10/julia-${JULIA_VERSION}-linux-x86_64.tar.gz" -o /tmp/julia.tar.gz
|
|
99
|
+
sudo tar -xzf /tmp/julia.tar.gz -C /opt
|
|
100
|
+
sudo ln -sf "/opt/julia-${JULIA_VERSION}/bin/julia" /usr/local/bin/julia
|
|
101
|
+
Rscript --version
|
|
102
|
+
julia --version
|
|
103
|
+
|
|
104
|
+
- name: Cache cargo registry and build outputs
|
|
105
|
+
uses: actions/cache@v5
|
|
106
|
+
with:
|
|
107
|
+
path: |
|
|
108
|
+
~/.cargo/registry
|
|
109
|
+
~/.cargo/git
|
|
110
|
+
target
|
|
111
|
+
key: ${{ runner.os }}-crosslang-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
112
|
+
restore-keys: ${{ runner.os }}-crosslang-cargo-
|
|
113
|
+
|
|
114
|
+
- name: Install Python benchmark dependencies
|
|
115
|
+
run: python -m pip install maturin polars pandas statsmodels
|
|
116
|
+
|
|
117
|
+
- name: Build Python wheel
|
|
118
|
+
run: maturin build --release --manifest-path python/Cargo.toml
|
|
119
|
+
|
|
120
|
+
- name: Install Python bindings
|
|
121
|
+
run: python -m pip install --force-reinstall python/target/wheels/*.whl
|
|
122
|
+
|
|
123
|
+
- name: Install R benchmark dependencies
|
|
124
|
+
run: |
|
|
125
|
+
mkdir -p "$R_LIBS_USER"
|
|
126
|
+
Rscript -e 'install.packages("lme4", repos="https://cloud.r-project.org", lib=Sys.getenv("R_LIBS_USER"))'
|
|
127
|
+
|
|
128
|
+
- name: Install Julia benchmark dependencies
|
|
129
|
+
run: julia -e 'using Pkg; Pkg.add(["CSV", "DataFrames", "MixedModels"])'
|
|
130
|
+
|
|
131
|
+
- name: Build Rust examples
|
|
132
|
+
run: cargo build --release --examples
|
|
133
|
+
|
|
134
|
+
- name: Run cross-language benchmark script
|
|
135
|
+
id: cross_language_run
|
|
136
|
+
run: |
|
|
137
|
+
mkdir -p benchmark-results
|
|
138
|
+
set +e
|
|
139
|
+
python scripts/run_cross_language_benchmarks.py \
|
|
140
|
+
--warmups "$BENCH_WARMUPS" \
|
|
141
|
+
--repeats "$BENCH_REPEATS" \
|
|
142
|
+
--output "benchmark-results/cross-language-${{ github.sha }}.json" \
|
|
143
|
+
--skip-rust-build
|
|
144
|
+
status=$?
|
|
145
|
+
echo "status=$status" >> "$GITHUB_OUTPUT"
|
|
146
|
+
exit 0
|
|
147
|
+
|
|
148
|
+
- name: Upload cross-language artifact
|
|
149
|
+
if: always()
|
|
150
|
+
uses: actions/upload-artifact@v7
|
|
151
|
+
with:
|
|
152
|
+
name: cross-language-${{ github.sha }}
|
|
153
|
+
path: benchmark-results/cross-language-${{ github.sha }}.json
|
|
154
|
+
|
|
155
|
+
- name: Attach cross-language artifact to GitHub Release
|
|
156
|
+
if: always() && startsWith(github.ref, 'refs/tags/')
|
|
157
|
+
env:
|
|
158
|
+
GH_TOKEN: ${{ github.token }}
|
|
159
|
+
run: |
|
|
160
|
+
gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1 || {
|
|
161
|
+
if [[ "${GITHUB_REF_NAME}" == *-* ]]; then
|
|
162
|
+
gh release create "${GITHUB_REF_NAME}" --title "${GITHUB_REF_NAME}" --prerelease --latest=false
|
|
163
|
+
else
|
|
164
|
+
gh release create "${GITHUB_REF_NAME}" --title "${GITHUB_REF_NAME}"
|
|
165
|
+
fi
|
|
166
|
+
}
|
|
167
|
+
gh release upload "${GITHUB_REF_NAME}" "benchmark-results/cross-language-${{ github.sha }}.json" --clobber
|
|
168
|
+
|
|
169
|
+
- name: Fail if cross-language benchmarks failed
|
|
170
|
+
if: steps.cross_language_run.outputs.status != '0'
|
|
171
|
+
run: |
|
|
172
|
+
echo "Cross-language benchmark script failed with exit code ${{ steps.cross_language_run.outputs.status }}." >&2
|
|
173
|
+
exit 1
|
|
174
|
+
|
|
175
|
+
pages:
|
|
176
|
+
name: Publish Benchmark Dashboard
|
|
177
|
+
runs-on: ubuntu-latest
|
|
178
|
+
needs:
|
|
179
|
+
- criterion
|
|
180
|
+
- cross-language
|
|
181
|
+
if: needs.criterion.result == 'success' && needs.cross-language.result == 'success' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))
|
|
182
|
+
environment:
|
|
183
|
+
name: github-pages
|
|
184
|
+
url: ${{ steps.deploy.outputs.page_url }}
|
|
185
|
+
steps:
|
|
186
|
+
- uses: actions/checkout@v6
|
|
187
|
+
|
|
188
|
+
- uses: actions/setup-python@v6
|
|
189
|
+
with:
|
|
190
|
+
python-version: "3.11"
|
|
191
|
+
|
|
192
|
+
- name: Download cross-language artifact
|
|
193
|
+
uses: actions/download-artifact@v5
|
|
194
|
+
with:
|
|
195
|
+
name: cross-language-${{ github.sha }}
|
|
196
|
+
path: site-input
|
|
197
|
+
|
|
198
|
+
- name: Resolve release URL
|
|
199
|
+
id: release_url
|
|
200
|
+
run: |
|
|
201
|
+
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
|
|
202
|
+
echo "value=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
|
|
203
|
+
else
|
|
204
|
+
echo "value=" >> "$GITHUB_OUTPUT"
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
- name: Build benchmark dashboard
|
|
208
|
+
run: |
|
|
209
|
+
set -euo pipefail
|
|
210
|
+
mkdir -p site
|
|
211
|
+
cp -R docs/. site/
|
|
212
|
+
mkdir -p site/benchmarks/data
|
|
213
|
+
cross_json="$(find site-input -name 'cross-language-*.json' -print -quit)"
|
|
214
|
+
python scripts/build_benchmark_site.py \
|
|
215
|
+
--cross-language-json "$cross_json" \
|
|
216
|
+
--output-dir "site/benchmarks/data" \
|
|
217
|
+
--run-url "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" \
|
|
218
|
+
--release-url "${{ steps.release_url.outputs.value }}" \
|
|
219
|
+
--criterion-asset-name "criterion-${GITHUB_SHA}.tar.gz" \
|
|
220
|
+
--cross-language-asset-name "cross-language-${GITHUB_SHA}.json" \
|
|
221
|
+
--ref-name "${GITHUB_REF_NAME}"
|
|
222
|
+
|
|
223
|
+
- uses: actions/configure-pages@v5
|
|
224
|
+
with:
|
|
225
|
+
token: ${{ secrets.REPO_ADMIN_TOKEN != '' && secrets.REPO_ADMIN_TOKEN || github.token }}
|
|
226
|
+
enablement: ${{ secrets.REPO_ADMIN_TOKEN != '' }}
|
|
227
|
+
|
|
228
|
+
- uses: actions/upload-pages-artifact@v3
|
|
229
|
+
with:
|
|
230
|
+
path: site
|
|
231
|
+
|
|
232
|
+
- name: Deploy to GitHub Pages
|
|
233
|
+
id: deploy
|
|
234
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Sync Repository Metadata
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
paths:
|
|
7
|
+
- Cargo.toml
|
|
8
|
+
- scripts/sync_github_repo_metadata.py
|
|
9
|
+
- .github/workflows/repo-metadata.yml
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
sync:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Verify admin token is configured
|
|
22
|
+
env:
|
|
23
|
+
REPO_ADMIN_TOKEN: ${{ secrets.REPO_ADMIN_TOKEN }}
|
|
24
|
+
run: |
|
|
25
|
+
if [ -z "$REPO_ADMIN_TOKEN" ]; then
|
|
26
|
+
echo "REPO_ADMIN_TOKEN is not set."
|
|
27
|
+
echo "Create a fine-grained PAT or GitHub App token with repository Administration: write."
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
- name: Sync repository metadata
|
|
32
|
+
env:
|
|
33
|
+
REPO_ADMIN_TOKEN: ${{ secrets.REPO_ADMIN_TOKEN }}
|
|
34
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
35
|
+
run: python scripts/sync_github_repo_metadata.py
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Benchmarks
|
|
2
|
+
|
|
3
|
+
This repository includes Criterion benchmarks for the Rust crate. Performance is an important selling point of `lme-rs`, but the benchmark suite should be described accurately: it is useful and non-trivial, yet it is not comprehensive enough to support blanket speed claims on its own.
|
|
4
|
+
|
|
5
|
+
## Current benchmark coverage
|
|
6
|
+
|
|
7
|
+
The existing benchmark target is [benches/bench_math.rs](benches/bench_math.rs).
|
|
8
|
+
|
|
9
|
+
It currently covers these benchmark families:
|
|
10
|
+
|
|
11
|
+
- formula parsing for representative random-slope, nested, and crossed formulas
|
|
12
|
+
- model-matrix construction for representative random-slope, nested, and crossed datasets
|
|
13
|
+
- internal REML deviance evaluation on a fixture-backed random-slopes model
|
|
14
|
+
- isolated large-scale REML deviance evaluation on a synthetic sparse model (`50k` observations)
|
|
15
|
+
- end-to-end `lmer()` fitting on `sleepstudy`
|
|
16
|
+
- end-to-end weighted `lmer_weighted()` fitting on fixture-backed and large synthetic cases
|
|
17
|
+
- end-to-end `glmer()` fitting on `grouseticks` and `cbpp`
|
|
18
|
+
- population-level and conditional prediction on a larger repeated `sleepstudy` frame
|
|
19
|
+
- response-scale and conditional response-scale GLMM prediction on repeated Poisson and Binomial frames
|
|
20
|
+
- GLMM post-fit helpers such as Wald confidence intervals
|
|
21
|
+
- end-to-end `lmer()` fitting on a large synthetic random-intercept model (`100k` observations)
|
|
22
|
+
- end-to-end large crossed-effects and nested-effects fits
|
|
23
|
+
- parameterized size and complexity sweeps for random-intercept, crossed-effects, and nested-effects fits
|
|
24
|
+
- inference helpers: `with_robust_se()`, `with_satterthwaite()`, `with_kenward_roger()`, and ANOVA paths
|
|
25
|
+
|
|
26
|
+
That is enough to catch obvious regressions in the parser, design-matrix path, core math path, several end-to-end fits, and a meaningful slice of the inference and post-fit surface.
|
|
27
|
+
|
|
28
|
+
## What the current suite does well
|
|
29
|
+
|
|
30
|
+
- Exercises both internal evaluation and public API entry points.
|
|
31
|
+
- Covers multiple stages of the modeling pipeline instead of only full-model fits.
|
|
32
|
+
- Covers both LMM and GLMM workflows.
|
|
33
|
+
- Includes both fixture-backed and synthetic large-scale cases.
|
|
34
|
+
- Includes nested and crossed random-effects structures.
|
|
35
|
+
- Includes weighted-model coverage.
|
|
36
|
+
- Includes parameterized size and complexity sweeps instead of only a few one-off scales.
|
|
37
|
+
- Includes several inference-heavy operations that are materially more expensive than fitting alone.
|
|
38
|
+
- Uses Criterion, which gives stable repeated measurements and report generation.
|
|
39
|
+
|
|
40
|
+
## What it does not cover yet
|
|
41
|
+
|
|
42
|
+
The current benchmark suite is still narrow in a few important ways.
|
|
43
|
+
|
|
44
|
+
### Missing comparisons
|
|
45
|
+
|
|
46
|
+
The repo now includes automated cross-language timing for representative example workloads through [scripts/run_cross_language_benchmarks.py](scripts/run_cross_language_benchmarks.py), including Rust, Python, R, and Julia runs where the required runtimes are installed.
|
|
47
|
+
|
|
48
|
+
What it still does not provide is a fully normalized cross-ecosystem benchmark harness with carefully matched optimizer settings, dataset loading rules, and machine-locked baselines for publication-grade claims.
|
|
49
|
+
|
|
50
|
+
### Missing workload diversity
|
|
51
|
+
|
|
52
|
+
It does not yet isolate or compare:
|
|
53
|
+
|
|
54
|
+
- prediction throughput on large crossed and nested structures
|
|
55
|
+
- weighted GLMM-style workflows if those are added later
|
|
56
|
+
- GLMM inference and post-fit helper costs beyond the currently benchmarked paths
|
|
57
|
+
- confidence interval and simulation throughput across multiple model sizes
|
|
58
|
+
|
|
59
|
+
### Missing benchmark dimensions
|
|
60
|
+
|
|
61
|
+
It does not currently sweep over controlled workload dimensions such as:
|
|
62
|
+
|
|
63
|
+
- number of observations
|
|
64
|
+
- number of groups
|
|
65
|
+
- random intercept vs random slope structure
|
|
66
|
+
- family and link combinations
|
|
67
|
+
- dense-like vs sparse-like random-effect structure
|
|
68
|
+
|
|
69
|
+
## Cross-language benchmark methodology
|
|
70
|
+
|
|
71
|
+
If you want to make public performance claims against R, Python, or Julia, use a fixed methodology and record it alongside the results. The repo now automates example-level cross-language timing, but the methodology still matters because the ecosystems do not all expose exactly the same optimizers or post-fit APIs.
|
|
72
|
+
|
|
73
|
+
Recommended rules:
|
|
74
|
+
|
|
75
|
+
- run all languages on the same machine
|
|
76
|
+
- record CPU model, RAM, OS, compiler/interpreter versions, and BLAS backend
|
|
77
|
+
- use fixed datasets and fixed formulas
|
|
78
|
+
- compare like with like: REML vs REML, ML vs ML, same family, same link, same random-effects structure
|
|
79
|
+
- exclude file I/O from timed sections unless I/O is the thing being compared
|
|
80
|
+
- warm up the runtime before collecting measurements
|
|
81
|
+
- run multiple repetitions and report medians or confidence intervals, not a single best run
|
|
82
|
+
- note when optimizers are not directly comparable across ecosystems
|
|
83
|
+
- keep output artifacts or raw logs so later releases can be compared to the same baseline
|
|
84
|
+
|
|
85
|
+
For this repo, the most defensible cross-language benchmark set would start with the same reference datasets already used in `comparisons/COMPARISONS.md`:
|
|
86
|
+
|
|
87
|
+
- `sleepstudy`
|
|
88
|
+
- `dyestuff`
|
|
89
|
+
- `pastes`
|
|
90
|
+
- `penicillin`
|
|
91
|
+
- `cbpp`
|
|
92
|
+
- `grouseticks`
|
|
93
|
+
|
|
94
|
+
## How to run the benchmarks
|
|
95
|
+
|
|
96
|
+
Run from the repository root:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
cargo bench
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
To compile the benchmarks without executing them:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
cargo bench --no-run
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Criterion will emit reports under `target/criterion/`.
|
|
109
|
+
|
|
110
|
+
For automated cross-language timing, run:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
python scripts/run_cross_language_benchmarks.py
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
This script writes JSON output with runtime versions, machine metadata, and per-command timing summaries.
|
|
117
|
+
|
|
118
|
+
The repository also includes a dedicated workflow in [.github/workflows/benchmarks.yml](.github/workflows/benchmarks.yml) that:
|
|
119
|
+
|
|
120
|
+
- runs Criterion benchmarks
|
|
121
|
+
- archives `target/criterion`
|
|
122
|
+
- runs the cross-language benchmark script
|
|
123
|
+
- uploads the resulting artifacts in CI
|
|
124
|
+
- attaches them to GitHub Releases on tag pushes
|
|
125
|
+
- publishes the latest benchmark dashboard to GitHub Pages at `https://x4g4p3x.github.io/lme-rs/benchmarks/`
|
|
126
|
+
|
|
127
|
+
## Latest published results
|
|
128
|
+
|
|
129
|
+
The latest published benchmark artifacts are attached to the [v0.1.3 release](https://github.com/x4g4p3x/lme-rs/releases/tag/v0.1.3).
|
|
130
|
+
|
|
131
|
+
That release currently includes:
|
|
132
|
+
|
|
133
|
+
- `criterion-e8a82e0b97b88c5549bc61e89c22dc12c9060a02.tar.gz`
|
|
134
|
+
- `cross-language-e8a82e0b97b88c5549bc61e89c22dc12c9060a02.json`
|
|
135
|
+
|
|
136
|
+
The cross-language JSON includes representative timings for:
|
|
137
|
+
|
|
138
|
+
- `sleepstudy`
|
|
139
|
+
- `pastes`
|
|
140
|
+
- `cbpp`
|
|
141
|
+
- `grouseticks`
|
|
142
|
+
|
|
143
|
+
across:
|
|
144
|
+
|
|
145
|
+
- Rust
|
|
146
|
+
- Python
|
|
147
|
+
- R
|
|
148
|
+
- Julia
|
|
149
|
+
|
|
150
|
+
Treat those numbers as versioned release artifacts, not as universal constants. They were produced on GitHub-hosted runners with the workflow's pinned toolchain setup, so they are useful for release-to-release comparison and public transparency, but not as machine-independent proof of absolute speed.
|
|
151
|
+
|
|
152
|
+
If you want to cite benchmark results in release notes or external docs, prefer linking the release asset directly instead of copying raw numbers into the README. That keeps the landing page stable while still making the measured outputs inspectable.
|
|
153
|
+
|
|
154
|
+
## How to interpret results
|
|
155
|
+
|
|
156
|
+
Use the existing suite primarily for:
|
|
157
|
+
|
|
158
|
+
- detecting regressions after changes to fitting logic
|
|
159
|
+
- tracking the cost of core LMM and GLMM paths over time
|
|
160
|
+
- sanity-checking large synthetic scaling cases
|
|
161
|
+
|
|
162
|
+
Do not use the current suite alone as evidence that `lme-rs` is universally faster than `lme4`, `statsmodels`, or `MixedModels.jl`.
|
|
163
|
+
|
|
164
|
+
## Recommended next extensions
|
|
165
|
+
|
|
166
|
+
If performance is going to remain a central public claim, the benchmark suite should be extended. The highest-value additions are:
|
|
167
|
+
|
|
168
|
+
1. Version-to-version regression tracking with saved benchmark outputs in CI or release notes.
|
|
169
|
+
2. More controlled cross-language benchmark cases with tighter optimizer comparability notes.
|
|
170
|
+
3. Prediction and post-fit sweeps for larger crossed and nested structures than the current medium-scale cases.
|
|
171
|
+
4. More explicit GLMM post-fit benchmarks beyond fitting, prediction, and Wald intervals.
|
|
172
|
+
5. Benchmarks that isolate optimizer iteration cost separately from formula parsing and matrix construction.
|
|
173
|
+
|
|
174
|
+
## Recommendation for this repo today
|
|
175
|
+
|
|
176
|
+
The current benchmarking is meaningful, but not comprehensive.
|
|
177
|
+
|
|
178
|
+
That means:
|
|
179
|
+
|
|
180
|
+
- yes, keep performance as a selling point
|
|
181
|
+
- no, avoid absolute claims without extending the suite further
|
|
182
|
+
- yes, run benchmarks for performance-sensitive changes before release
|
|
183
|
+
- yes, extend the benchmark surface if performance is going to stay front-and-center in the README and release notes
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.4] - 2026-03-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Formula-string entry point `lm()` and corresponding Python binding for fitting ordinary least squares models using DataFrames.
|
|
13
|
+
- New Python examples directory `python/examples` with five runnable demonstration scripts mapping to common mixed-modeling workflows.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Renamed `examples/` directory to `comparisons/` to clarify that it contains cross-language parity scripts, updating all build and documentation references accordingly.
|
|
18
|
+
- Promoted Kenward-Roger degrees of freedom from "provisional" status after validating numerical parity (within 0.01 df) against R's `pbkrtest`.
|
|
19
|
+
|
|
20
|
+
## [0.1.3] - 2026-03-12
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Expanded the benchmark suite to cover parsing, matrix construction, prediction paths, inference helpers, weighted fits, Kenward-Roger timing, and size sweeps.
|
|
25
|
+
- Added automated cross-language benchmark scripting and a GitHub workflow that saves benchmark artifacts in CI and on release tags.
|
|
26
|
+
- Added `CONTRIBUTING.md`, `RELEASING.md`, and `BENCHMARKS.md` to document contributor setup, release flow, and benchmark methodology.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Reworked the README, Rust guide, Python guide, and comparison documentation to better reflect current capabilities, limitations, and release workflow.
|
|
31
|
+
- Switched the crate homepage to the docs.rs site and expanded repository metadata sync for GitHub description, topics, and website fields.
|
|
32
|
+
- Hardened the benchmark automation and example scripts so cross-language benchmark runs complete consistently on GitHub Actions.
|
|
33
|
+
|
|
34
|
+
## [0.1.2] - 2026-03-09
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- Fixed a NaN deviance issue in the fitting path.
|
|
39
|
+
- Expanded Python test coverage for the 0.1.2 release.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- Aligned `Cargo.lock` with the 0.1.2 version bump.
|
|
44
|
+
|
|
45
|
+
## [0.1.1] - 2026-03-09
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- Bumped the crate and Python extension versions for the 0.1.1 release.
|
|
50
|
+
- Updated lockfiles to remove yanked dependencies.
|
|
51
|
+
- Fixed missing documentation warnings needed for publishing.
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- Hardened the GitHub Actions and wheel build pipeline across Linux, macOS, and Windows.
|
|
56
|
+
- Restored missing dependencies and build flags needed for OpenBLAS-based wheel builds.
|
|
57
|
+
- Fixed several maturin and PyO3 packaging workflow issues for the Python release path.
|
|
58
|
+
|
|
59
|
+
## [0.1.0] - 2026-03-08
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
|
|
63
|
+
- **Core LMM** - `lmer()` with REML and ML estimation, matching R's `lme4` to 4 decimal places
|
|
64
|
+
- **GLMM** - `glmer()` with Poisson, Binomial, Gaussian, and Gamma families via Laplace approximation
|
|
65
|
+
- **Predictions** - `predict()`, `predict_conditional()`, `predict_response()`, `predict_conditional_response()` with `allow_new_levels` support
|
|
66
|
+
- **Inference** - Satterthwaite and Kenward-Roger degrees of freedom, robust sandwich standard errors
|
|
67
|
+
- **Model comparison** - `anova()` for likelihood ratio tests between nested models
|
|
68
|
+
- **Diagnostics** - `confint()` for Wald confidence intervals, `simulate()` for parametric bootstrap
|
|
69
|
+
- **Formula parser** - Wilkinson notation with nested (`a/b`), crossed (`a + b`), and correlated slope+intercept (`x | group`) random effects
|
|
70
|
+
- **Sparse matrix architecture** - Compressed sparse column format with sparse Cholesky for large datasets
|
|
71
|
+
- **Python bindings** - `lme_python` package via PyO3/maturin with `lmer()`, `glmer()`, `predict()`
|
|
72
|
+
- **Documentation** - `GUIDE.md`, `PYTHON_GUIDE.md`, and cross-language `COMPARISONS.md`
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
This repository contains:
|
|
6
|
+
|
|
7
|
+
- the Rust crate in the repository root
|
|
8
|
+
- the Python bindings in `python/`
|
|
9
|
+
- cross-language comparison scripts in `comparisons/`
|
|
10
|
+
- regression fixtures and integration tests in `tests/`
|
|
11
|
+
|
|
12
|
+
## Local setup
|
|
13
|
+
|
|
14
|
+
### Rust
|
|
15
|
+
|
|
16
|
+
Install a stable Rust toolchain via [rustup](https://rustup.rs).
|
|
17
|
+
|
|
18
|
+
Useful commands:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cargo build
|
|
22
|
+
cargo test
|
|
23
|
+
cargo test --doc
|
|
24
|
+
cargo fmt --check
|
|
25
|
+
cargo clippy -- -D warnings
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Python bindings
|
|
29
|
+
|
|
30
|
+
If you are changing `python/` or verifying the Python package locally:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
cd python
|
|
34
|
+
python -m venv .venv
|
|
35
|
+
|
|
36
|
+
# Windows
|
|
37
|
+
.venv\Scripts\activate
|
|
38
|
+
|
|
39
|
+
# macOS / Linux
|
|
40
|
+
source .venv/bin/activate
|
|
41
|
+
|
|
42
|
+
pip install maturin polars pytest
|
|
43
|
+
maturin develop --release
|
|
44
|
+
pytest
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Working on numerical changes
|
|
48
|
+
|
|
49
|
+
If you change fitting logic, optimizer behavior, variance calculations, or inference code:
|
|
50
|
+
|
|
51
|
+
- add or update Rust tests in `tests/`
|
|
52
|
+
- prefer fixture-backed tests for parity-sensitive behavior
|
|
53
|
+
- update `comparisons/COMPARISONS.md` when the reference output changes materially
|
|
54
|
+
- validate hard cases against R `lme4` where practical
|
|
55
|
+
|
|
56
|
+
Relevant files and directories:
|
|
57
|
+
|
|
58
|
+
- `src/` for the crate implementation
|
|
59
|
+
- `tests/data/` for fixture inputs
|
|
60
|
+
- `tests/generate_test_data.R` for R-backed fixture generation
|
|
61
|
+
- `comparisons/` for cross-language parity scripts (R, Python/statsmodels, Julia)
|
|
62
|
+
|
|
63
|
+
## Working on documentation
|
|
64
|
+
|
|
65
|
+
When documentation changes affect user-visible behavior, keep these files aligned:
|
|
66
|
+
|
|
67
|
+
- `README.md` for the repository landing page
|
|
68
|
+
- `GUIDE.md` for Rust usage
|
|
69
|
+
- `python/PYTHON_GUIDE.md` for Python usage
|
|
70
|
+
- `CHANGELOG.md` for release-facing notes
|
|
71
|
+
|
|
72
|
+
Do not describe a feature as supported unless it is exposed by the public API and covered by tests or concrete examples.
|
|
73
|
+
|
|
74
|
+
## Repository metadata sync
|
|
75
|
+
|
|
76
|
+
The GitHub About box is synced from `Cargo.toml` using:
|
|
77
|
+
|
|
78
|
+
- `.github/workflows/repo-metadata.yml`
|
|
79
|
+
- `scripts/sync_github_repo_metadata.py`
|
|
80
|
+
|
|
81
|
+
If you change `package.description`, `homepage`, `keywords`, or `categories`, the metadata workflow will update the GitHub repository metadata on the next run.
|
|
82
|
+
|
|
83
|
+
## Pull request expectations
|
|
84
|
+
|
|
85
|
+
Keep changes focused. For non-trivial changes, include:
|
|
86
|
+
|
|
87
|
+
- the user-visible behavior change
|
|
88
|
+
- the tests you ran
|
|
89
|
+
- any compatibility or migration note if behavior changed
|
|
90
|
+
|
|
91
|
+
If a change is provisional or only partially mirrors R behavior, document that explicitly instead of implying full parity.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "lme-rs"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.4"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
authors = ["Martin Huck <x4g4p3x@users.noreply.github.com>"]
|
|
6
6
|
description = "Rust port of R's lme4: linear mixed-effects models with 1:1 numerical compatibility"
|
|
7
7
|
license = "MIT"
|
|
8
8
|
repository = "https://github.com/x4g4p3x/lme-rs"
|
|
9
|
-
homepage = "https://
|
|
9
|
+
homepage = "https://docs.rs/lme-rs/latest/lme_rs/"
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
keywords = ["statistics", "lme4", "mixed-effects", "glmm", "regression"]
|
|
12
12
|
categories = ["science", "mathematics"]
|
|
@@ -38,6 +38,35 @@ debug = true
|
|
|
38
38
|
|
|
39
39
|
[[bench]]
|
|
40
40
|
name = "bench_math"
|
|
41
|
+
harness = false
|
|
42
|
+
|
|
43
|
+
[[example]]
|
|
44
|
+
name = "glmm_cbpp"
|
|
45
|
+
path = "comparisons/glmm_cbpp.rs"
|
|
46
|
+
|
|
47
|
+
[[example]]
|
|
48
|
+
name = "glmm_grouseticks"
|
|
49
|
+
path = "comparisons/glmm_grouseticks.rs"
|
|
50
|
+
|
|
51
|
+
[[example]]
|
|
52
|
+
name = "lmm_dyestuff"
|
|
53
|
+
path = "comparisons/lmm_dyestuff.rs"
|
|
54
|
+
|
|
55
|
+
[[example]]
|
|
56
|
+
name = "lmm_pastes"
|
|
57
|
+
path = "comparisons/lmm_pastes.rs"
|
|
58
|
+
|
|
59
|
+
[[example]]
|
|
60
|
+
name = "lmm_penicillin"
|
|
61
|
+
path = "comparisons/lmm_penicillin.rs"
|
|
62
|
+
|
|
63
|
+
[[example]]
|
|
64
|
+
name = "sleepstudy"
|
|
65
|
+
path = "comparisons/sleepstudy.rs"
|
|
66
|
+
|
|
67
|
+
[[example]]
|
|
68
|
+
name = "sleepstudy_ml"
|
|
69
|
+
path = "comparisons/sleepstudy_ml.rs"
|
|
41
70
|
|
|
42
71
|
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
|
43
72
|
ndarray-linalg = { version = "0.17", features = ["intel-mkl-static"] }
|