5 Commits

Author SHA1 Message Date
a4b4e5e8fa chore: clean up 2026-04-23 20:24:10 +02:00
04d5478ee4 style: cargo fmt 2026-04-23 20:23:13 +02:00
480467ac32 chore: added cliff.toml, release.toml and rustfmt.toml 2026-04-23 20:22:27 +02:00
dc47964310 added benchmark 2026-03-23 14:55:18 +01:00
61a5507f5c remove notepad 2026-03-23 14:21:23 +01:00
14 changed files with 151 additions and 95 deletions

3
.gitignore vendored
View File

@@ -4,3 +4,6 @@
/temp
.justfile
*.svg
NOTEPAD.md
/.claude

View File

@@ -10,6 +10,10 @@ bench = false
name = "batch"
harness = false
[[bench]]
name = "gaussian"
harness = false
[dependencies]
approx = { version = "0.5.1", optional = true }

10
Justfile Normal file
View File

@@ -0,0 +1,10 @@
alias b := bench
store:
cargo bench -- --save-baseline base
bench:
cargo bench -- --baseline base
flame:
cargo flamegraph --root --example atp

View File

@@ -1,16 +0,0 @@
# History
```rust
let mut history = History::new();
let agent_a = history.new_agent();
let agent_b = history.new_agent_with_prior(Prior::new(Gaussian::default(), BETA, GAMMA));
```
```rust
trait Team {
fn players(&self) -> impl Iterator<Item = P>;
fn weights(&self) -> impl Iterator<Item = f64>;
fn score(&self) -> u16;
}
```

50
benches/gaussian.rs Normal file
View File

@@ -0,0 +1,50 @@
use criterion::{Criterion, criterion_group, criterion_main};
use trueskill_tt::gaussian::Gaussian;
fn benchmark_gaussian_arithmetic(criterion: &mut Criterion) {
// Define test Gaussians
let g1 = Gaussian::from_ms(25.0, 25.0 / 3.0);
let g2 = Gaussian::from_ms(0.0, 1.0);
let g3 = Gaussian::from_ms(1.0, 1.0);
// Benchmark addition
criterion.bench_function("Gaussian::add", |bencher| {
bencher.iter(|| g1 + g2);
});
// Benchmark subtraction
criterion.bench_function("Gaussian::sub", |bencher| {
bencher.iter(|| g1 - g3);
});
// Benchmark multiplication
criterion.bench_function("Gaussian::mul", |bencher| {
bencher.iter(|| g1 * g2);
});
// Benchmark division
criterion.bench_function("Gaussian::div", |bencher| {
bencher.iter(|| g1 / g2);
});
// Benchmark natural parameter conversions
criterion.bench_function("Gaussian::pi", |bencher| {
bencher.iter(|| g1.pi());
});
criterion.bench_function("Gaussian::tau", |bencher| {
bencher.iter(|| g1.tau());
});
// Benchmark combined pi/tau operations (used in mul/div)
criterion.bench_function("Gaussian::pi_tau_combined", |bencher| {
bencher.iter(|| {
let pi = g1.pi();
let tau = g1.tau();
(pi, tau)
});
});
}
criterion_group!(benches, benchmark_gaussian_arithmetic);
criterion_main!(benches);

65
cliff.toml Normal file
View File

@@ -0,0 +1,65 @@
# git-cliff ~ configuration file
# https://git-cliff.org/docs/configuration
[changelog]
# A Tera template to be rendered as the changelog's header.
# See https://keats.github.io/tera/docs/#introduction
header = """
# Changelog\n
All notable changes to this project will be documented in this file.\n
"""
# A Tera template to be rendered for each release in the changelog.
# See https://keats.github.io/tera/docs/#introduction
body = """
{% if version %}\
## {{ version | trim_start_matches(pat="v") }} - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## Unreleased
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits %}
- {{ commit.message | split(pat="\n") | first | trim_end }}\
{% endfor %}
{% endfor %}\n
"""
# A Tera template to be rendered as the changelog's footer.
# See https://keats.github.io/tera/docs/#introduction
footer = """
<!-- generated by git-cliff -->
"""
# Remove leading and trailing whitespaces from the changelog's body.
trim = true
[git]
# Parse commits according to the conventional commits specification.
# See https://www.conventionalcommits.org
conventional_commits = false
# Exclude commits that do not match the conventional commits specification.
filter_unconventional = false
# Split commits on newlines, treating each line as an individual commit.
split_commits = false
# An array of regex based parsers for extracting data from the commit message.
# Assigns commits to groups.
# Optionally sets the commit's scope and can decide to exclude commits from further processing.
commit_parsers = [
{ message = "^feat", group = "Features" },
{ message = "^fix", group = "Bug Fixes" },
{ message = "^doc", group = "Documentation" },
{ message = "^perf", group = "Performance" },
{ message = "^refactor", group = "Refactor" },
{ message = "^style", group = "Styling" },
{ message = "^test", group = "Testing" },
{ message = "^chore\\(release\\): prepare for", skip = true },
{ message = "^chore", group = "Miscellaneous Tasks" },
{ body = ".*security", group = "Security" },
{ body = ".*", group = "Other (unconventional)" },
]
# Exclude commits that are not matched by any commit parser.
filter_commits = false
# Order releases topologically instead of chronologically.
topo_order = false
# Order of commits in each group/release within the changelog.
# Allowed values: newest, oldest
sort_commits = "oldest"

View File

@@ -159,10 +159,12 @@ fn main() {
}
mod csv {
use std::fs::File;
use std::io::{self, BufRead, BufReader, Lines};
use std::ops;
use std::path::Path;
use std::{
fs::File,
io::{self, BufRead, BufReader, Lines},
ops,
path::Path,
};
pub struct Reader {
header_map: Vec<String>,

View File

@@ -1,64 +0,0 @@
vars: {
d2-config: {
layout-engine: elk
# Terminal theme code
theme-id: 300
}
}
History: {
shape: class
agents: "HashMap<Index, Agent>"
batches: "Vec<Batch>"
}
Batch: {
shape: class
skills: "HashMap<Index, Skill>"
events: "Vec<Event>"
time: "i64"
p_draw: "f64"
}
Event: {
shape: class
teams: "Vec<Team>"
weights: "Vec<Vec<f64>>"
evidence: "f64"
}
Team: {
shape: class
items: "Vec<Item>"
output: "f64"
}
Item: {
shape: class
agent: "Index"
likelihood: "Gaussian"
}
Skill: {
shape: class
forward: "Gaussian"
backward: "Gaussian"
likelihood: "Gaussian"
elapsed: "i64"
online: "Gaussian"
}
History -> Batch
Batch -> Skill
Batch -> Event
Event -> Team
Team -> Item

1
release.toml Normal file
View File

@@ -0,0 +1 @@
pre-release-hook = ["git", "cliff", "-o", "CHANGELOG.md", "--tag", "{{version}}"]

2
rustfmt.toml Normal file
View File

@@ -0,0 +1,2 @@
imports_granularity = "Crate"
group_imports = "StdExternalCrate"

View File

@@ -391,9 +391,8 @@ pub(crate) fn compute_elapsed(last_time: i64, actual_time: i64) -> i64 {
mod tests {
use approx::assert_ulps_eq;
use crate::{IndexMap, agent::Agent, drift::ConstantDrift, player::Player};
use super::*;
use crate::{IndexMap, agent::Agent, drift::ConstantDrift, player::Player};
#[test]
fn test_one_event_each() {

View File

@@ -203,9 +203,8 @@ impl<'a, D: Drift> Game<'a, D> {
mod tests {
use ::approx::assert_ulps_eq;
use crate::{ConstantDrift, GAMMA, Gaussian, N_INF, Player};
use super::*;
use crate::{ConstantDrift, GAMMA, Gaussian, N_INF, Player};
#[test]
fn test_1vs1() {

View File

@@ -433,9 +433,8 @@ impl<D: Drift> History<D> {
mod tests {
use approx::assert_ulps_eq;
use crate::{ConstantDrift, EPSILON, Game, Gaussian, ITERATIONS, IndexMap, P_DRAW, Player};
use super::*;
use crate::{ConstantDrift, EPSILON, Game, Gaussian, ITERATIONS, IndexMap, P_DRAW, Player};
#[test]
fn test_init() {

View File

@@ -1,8 +1,10 @@
use std::borrow::{Borrow, ToOwned};
use std::cmp::Reverse;
use std::collections::HashMap;
use std::f64::consts::{FRAC_1_SQRT_2, FRAC_2_SQRT_PI, SQRT_2};
use std::hash::Hash;
use std::{
borrow::{Borrow, ToOwned},
cmp::Reverse,
collections::HashMap,
f64::consts::{FRAC_1_SQRT_2, FRAC_2_SQRT_PI, SQRT_2},
hash::Hash,
};
pub mod agent;
#[cfg(feature = "approx")]