Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ rustflags = [
]

[alias]
fit = "run -p multicalc --example curve_fit"
fit = "run -p multicalc-demos --example curve_fit"
smoke-eabi = "run -p embedded-smoke --release --target thumbv7em-none-eabi"
smoke-eabihf = "run -p embedded-smoke --release --target thumbv7em-none-eabihf"
smoke-m0 = "run -p embedded-smoke --release --no-default-features --target thumbv6m-none-eabi"
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,10 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Build examples
run: cargo build -p multicalc --examples
- name: Build headless demos
run: cargo build -p multicalc-demos --examples --no-default-features
- name: Run basics
run: bash scripts/run_examples.sh
- name: Build benches
run: cargo build -p multicalc --benches
# runs a clean `cargo package` build — the same packaging the Step 15
Expand Down
26 changes: 17 additions & 9 deletions .github/workflows/full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,10 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Build examples
run: cargo build -p multicalc --examples
- name: Build headless demos
run: cargo build -p multicalc-demos --examples --no-default-features
- name: Run basics
run: bash scripts/run_examples.sh
- name: Build benches
run: cargo build -p multicalc --benches
# runs a clean `cargo package` build — the same packaging the Step 15
Expand Down Expand Up @@ -197,18 +199,24 @@ jobs:
lcov.info
target/llvm-cov/html

viz:
name: viz adapter (host-only, non-PR)
demos:
name: demos crate (host-only, non-PR)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- name: Build (lib + examples)
run: cargo build -p multicalc-viz --examples
- name: Clippy
run: cargo clippy -p multicalc-viz --all-targets -- -D warnings
- name: Build (lib + examples, default features)
run: cargo build -p multicalc-demos --examples
- name: Check headless (no default features)
run: cargo check -p multicalc-demos --no-default-features
- name: Clippy (default features)
run: cargo clippy -p multicalc-demos --all-targets -- -D warnings
- name: Clippy (headless)
run: cargo clippy -p multicalc-demos --all-targets --no-default-features -- -D warnings
- name: No Rerun in the headless tree
run: "! cargo tree -p multicalc-demos --no-default-features -i rerun"
- name: Headless record smoke test
run: cargo test -p multicalc-viz
run: cargo test -p multicalc-demos
19 changes: 19 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ locally anyway, the setup lives in [ci/README.md](ci/README.md) (optional).
- **Docs**: public APIs get a doc example; behavior notes (NaN policy, iteration
budgets) live on the item.

## Where does a check go?

The workspace has several test and demo layers. Each has one job; adding a check means picking
the layer that matches and not duplicating another's.

| Layer | Purpose | Must not |
|---|---|---|
| doctests | one minimal runnable demo per public item | become the correctness suite |
| `src/**/test.rs` inline | white-box tests of `pub(crate)` internals only (LU/lmpar) | test public API |
| `tests/suite/` | **the** correctness suite: public API, edge cases, proptests | re-declare problems/helpers inline |
| `demos/examples/basics/` | copy-pasteable, headless, terminating demos; multicalc-only imports | exit 0 without ≥1 sanity `assert!`; touch a sink |
| `demos/examples/showcase/` | live Rerun demos; measured numbers only | panic on edge cases (errors render as demo states); hardcode a perf claim |
| `benches/` | timing; `.md` tables are labeled illustrative snapshots | present tables as verified claims |
| `tools/oracle` | cross-implementation goldens (numpy/mpmath/MINPACK) only | duplicate self-consistency tests |
| `tools/embedded-smoke` | on-target FP-path + stack/text budgets; goldens only via generated `fixtures.rs` | hand-write golden values |

Shared problem definitions and tolerance helpers live in `tools/testkit`, so a problem is
declared once and reused across `tests/suite/`, the oracle, and embedded-smoke.

## Releasing

Releases are automated from `main`:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["crates/multicalc", "tools/embedded-smoke", "tools/oracle", "showcase/viz"]
members = ["crates/multicalc", "tools/embedded-smoke", "tools/oracle", "tools/testkit", "demos"]
default-members = ["crates/multicalc"]
resolver = "3"

Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ derivatives, integrals, curve fitting and linear algebra; built and tested on fi
hardware targets. Exercise the same code from a 64-bit server CPU down to a bare-metal microcontroller.**

<p align="center">
<img src="https://github.com/kmolan/multicalc-rust/blob/main/showcase/viz/examples/support/ik_servo_showcase.gif" width="75%" alt="1 kHz 3-link arm running a full Levenberg-Marquardt solve every millisecond">
<img src="https://github.com/kmolan/multicalc-rust/blob/main/showcase/viz/examples/support/newton_fractal_showcase.gif" width="75%" alt="Morphing Newton fractal, every pixel a full Newton solve">
<img src="https://github.com/kmolan/multicalc-rust/blob/main/demos/examples/showcase/support/ik_servo_showcase.gif" width="75%" alt="1 kHz 3-link arm running a full Levenberg-Marquardt solve every millisecond">
<img src="https://github.com/kmolan/multicalc-rust/blob/main/demos/examples/showcase/support/newton_fractal_showcase.gif" width="75%" alt="Morphing Newton fractal, every pixel a full Newton solve">
</p>

*Two of four live [showcase demos](showcase/viz#showcases): a 1 kHz 3-link arm running a complete
*Two of four live [showcase demos](demos#live-showcases): a 1 kHz 3-link arm running a complete
Levenberg-Marquardt solve every millisecond, and a Newton fractal at ~4 million solves/sec on one
core — every number measured live.*

Expand Down Expand Up @@ -102,19 +102,19 @@ below.
- **[Full guide](crates/multicalc/README.md)**: Every feature with a runnable snippet, plus
notes on `no_std`, error handling, and heap allocation.
- **[API docs](https://docs.rs/multicalc)** on docs.rs.
- **[Examples](crates/multicalc/examples)**: Self-contained programs for each module. Run one
with `cargo run --example <name>`.
- **[Live showcases](showcase/viz#showcases)**: Four animated Rerun demos — a 1 kHz IK on a 3-link arm, a
- **[Examples](demos#start-here)**: Self-contained, self-checking programs for each module in the
`demos/` crate. Run one with `cargo run -p multicalc-demos --example <name>`.
- **[Live showcases](demos#live-showcases)**: Four animated Rerun demos — a 1 kHz IK on a 3-link arm, a
Newton fractal, Fourier epicycles drawing Ferris, and gradient-driven marbles — each streaming
live-measured speed and accuracy.
- **[Benchmarks](crates/multicalc/benches)**: Accuracy figures and measured latency.

## Repository layout

The published library crate lives in [`crates/multicalc`](crates/multicalc); the repository
root is a Cargo workspace. A second, dev-only crate,
[`tools/embedded-smoke`](tools/embedded-smoke), runs `multicalc` on the three bare-metal
Cortex-M targets under QEMU every PR.
root is a Cargo workspace. Runnable demos live in the dev-only [`demos/`](demos) crate (basics and
live Rerun showcases), and [`tools/embedded-smoke`](tools/embedded-smoke) runs `multicalc` on the
three bare-metal Cortex-M targets under QEMU every PR.

## Contributing

Expand Down
1 change: 1 addition & 0 deletions crates/multicalc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ libm = "0.2"
rand = "0.8"
criterion = "0.5"
proptest = "1.11"
multicalc-testkit = { path = "../../tools/testkit" }

[features]
default = []
Expand Down
12 changes: 6 additions & 6 deletions crates/multicalc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ Jacobians and Hessians, vector-field operators, and Taylor approximation in a `n
- A runnable example for every module, and a test suite covering each error path.

<p align="center">
<img src="https://github.com/kmolan/multicalc-rust/blob/main/showcase/viz/examples/support/ik_servo_showcase.gif" width="75%" alt="1 kHz 3-link arm running a full Levenberg-Marquardt solve every millisecond">
<img src="https://github.com/kmolan/multicalc-rust/blob/main/showcase/viz/examples/support/newton_fractal_showcase.gif" width="75%" alt="Morphing Newton fractal, every pixel a full Newton solve">
<img src="https://github.com/kmolan/multicalc-rust/blob/main/demos/examples/showcase/support/ik_servo_showcase.gif" width="75%" alt="1 kHz 3-link arm running a full Levenberg-Marquardt solve every millisecond">
<img src="https://github.com/kmolan/multicalc-rust/blob/main/demos/examples/showcase/support/newton_fractal_showcase.gif" width="75%" alt="Morphing Newton fractal, every pixel a full Newton solve">
</p>

*Two of four live [showcase demos](showcase/viz#showcases): a 1 kHz 3-link arm running a complete
*Two of four live [showcase demos](../../demos#live-showcases): a 1 kHz 3-link arm running a complete
Levenberg-Marquardt solve every millisecond, and a Newton fractal at ~4 million solves/sec on one
core — every number measured live.*

Expand Down Expand Up @@ -373,11 +373,11 @@ returns a `Vec<Vec<T>>` of the scalar (`Vec<Vec<f64>>` by default).

## Examples

Runnable, self-contained programs for each module live in [`examples/`](./examples). See
[examples/README.md](./examples/README.md). Run one with:
Runnable, self-contained programs for each module live in the [`demos/`](../../demos) crate. See
[demos/README.md](../../demos/README.md). Run one with:

```sh
cargo run --example <name>
cargo run -p multicalc-demos --example <name>
```

## Benchmarks
Expand Down
5 changes: 3 additions & 2 deletions crates/multicalc/benches/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ figures (wall-clock time per call).

Accuracy vs latency: every suite doc reports latency (wall-clock time per call); all five also
report accuracy (how close the result lands to the known value, or the drift of a conserved
quantity for the ODE systems). The examples in [`examples/`](../examples) reproduce those accuracy
tables, so the published figures stay honest.
quantity for the ODE systems). These docs are illustrative snapshots, not verified claims:
verified accuracy lives in the golden fixtures under [`tools/oracle`](../../../tools/oracle), and
runnable, self-checking demos live in [`demos/`](../../../demos).

## Running

Expand Down
8 changes: 4 additions & 4 deletions crates/multicalc/benches/linear_algebra.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ report wall-clock medians on the machine noted in [README.md](README.md).

## Accuracy

Measured by the [`linear_algebra`](../examples/linear_algebra.rs) and [`svd`](../examples/svd.rs)
stress-test examples on well- and ill-conditioned inputs. Unlike latency, these are deterministic
numerical errors and reproduce on any machine. Reconstruction is the entrywise error of the
factorization; the solve residual is $$\lVert Ax - b\rVert$$ for a known solution.
Measured by the [`linear_algebra`](../../../demos) and [`svd`](../../../demos) stress-test demos
on well- and ill-conditioned inputs. Unlike latency, these are deterministic numerical errors and
reproduce on any machine. Reconstruction is the entrywise error of the factorization; the solve
residual is $$\lVert Ax - b\rVert$$ for a known solution.

### LU and Cholesky (decompose + solve)

Expand Down
4 changes: 2 additions & 2 deletions crates/multicalc/benches/ode.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ reports wall-clock medians on the machine noted in [README.md](README.md).
## Accuracy

None of these systems has a closed-form solution, so accuracy is the drift of a conserved
quantity: `max |Q(t) − Q(0)|` over the trajectory (relative, for the N-body energy). The figures
below are reproduced by [`examples/ode.rs`](../examples/ode.rs) (`cargo run --example ode`).
quantity: `max |Q(t) − Q(0)|` over the trajectory (relative, for the N-body energy). The same
systems run in the [`ode`](../../../demos) demo (`cargo run -p multicalc-demos --example ode`).

| System | Invariant | RK4 drift | RK45 drift | Notes |
| ------------------------------ | --------------------- | --------- | ---------- | ----------------------------------------------------------- |
Expand Down
29 changes: 0 additions & 29 deletions crates/multicalc/examples/README.md

This file was deleted.

23 changes: 0 additions & 23 deletions crates/multicalc/tests/linear_algebra.rs

This file was deleted.

Loading
Loading