Skip to content

Commit 920a546

Browse files
docs(readme): reorder headline, fix dangling refs, restore batch disclosure
Three small follow-ups after the volfi-cut pass: 1. Headline reordered. The body no longer carries volfi's weight (it was cut from the three speed tables and the v×Δ subsection), so the headline should not lead with the volfi finding either. Lead sentence is now voltic + LBR at the f64 floor with 48x SIMD throughput and mpmath verification; the volfi tail is demoted to a second paragraph that points readers to the accuracy table. 2. Dangling footnote markers and missing cross-reference fixed. The trailing [^1][^2] on the CLY-3D NaN line was rendering as "12" after the surrounding sections were cut. Footnote markers relocated: [^1] (mpmath oracle independence) attached to the headline mpmath sentence, [^2] (znver5 hardware caveat) attached to the speed-table description where it belongs. The ATM-dense NaN prose now also points at Accuracy: known gaps, matching the CLY-3D form. 3. implied_vol_with_context_batch disclosure restored. The previous pass removed the hard numbers entirely; this re-adds the honest one-liner: ~20% of rows catastrophic on CLY-3D with max sigma error 0.85, only correct on pre-filtered interior input. Matches the disclosure register the rest of the doc has. Signed-off-by: Ryan Stewart <47729789+RyanJamesStewart@users.noreply.github.com>
1 parent 042a393 commit 920a546

1 file changed

Lines changed: 6 additions & 6 deletions

File tree

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ Requires a **nightly Rust toolchain** (`std::simd`, `#![feature(portable_simd)]`
2323

2424
## Headline
2525

26-
voltic and py_lets_be_rational sit at the f64 inversion floor across 100,000 SplitMix64-seeded options. volfi has a silent ~0.91% catastrophic-precision tail in the deep wings of the moneyness-vega plane (3-4% failure rate inside each deep-wing band; max σ error 3.3e-1).
26+
voltic sits at the f64 inversion floor across 100,000 SplitMix64-seeded options, tied with py_lets_be_rational on accuracy and 48 times faster at f64x8 SIMD throughput. Verification is an independent 200-bit mpmath oracle (`bench/python/oracle_mpmath.py`) that inverts each option's f64-rounded BS price to the floor it can be inverted to; the f64 solvers' errors are reported relative to that floor. Oracle self-consistency at 7.5e-56 passes the 1e-40 acceptance threshold by 16 orders of magnitude.[^1]
2727

28-
Verification: an independent 200-bit mpmath oracle (`bench/python/oracle_mpmath.py`) inverts each option's f64-rounded BS price to the floor it can be inverted to; the f64 solvers' errors are reported relative to that floor. Oracle self-consistency at 7.5e-56 passes the 1e-40 acceptance threshold by 16 orders of magnitude.
28+
The accuracy table below also surfaces a ~0.91% catastrophic-precision tail in volfi at the deep wings of the moneyness-vega plane (3-4% failure rate inside each deep-wing band; max σ error 3.3e-1).
2929

3030
### Accuracy per band (100,000 SplitMix64-seeded options, mpmath-200-bit oracle)
3131

@@ -53,7 +53,7 @@ The volfi finding is reproduced via volfi's own `otm_context` API and volfi-self
5353
| py_lets_be_rational (LBR scalar) | Python+C++ scalar loop | 100,000 | 3,475.3 | 0.348 | 1.54e-11 | 0 |
5454
| py_vollib_vectorized | Python+C++ numpy-vectorized | 100,000 | 405.6 | 0.041 | 2.04e-11 | 0 |
5555

56-
All rows on the same SplitMix64-seeded dataset (`bench/data.rs`, seed `0x5EEDBEEFCAFEF00D`). The voltic Rust rows are 1M options (median of 7 timed passes after warmup, `cargo run --release --bin bench`); the Python comparison rows are a 100k subsample (Python is per-option-slower so 1M wall time would be 3+ s for LBR scalar). Same dataset, same RNG draw, first 100k rows.
56+
All rows on the same SplitMix64-seeded dataset (`bench/data.rs`, seed `0x5EEDBEEFCAFEF00D`). The voltic Rust rows are 1M options (median of 7 timed passes after warmup, `cargo run --release --bin bench`); the Python comparison rows are a 100k subsample (Python is per-option-slower so 1M wall time would be 3+ s for LBR scalar). Same dataset, same RNG draw, first 100k rows.[^2]
5757

5858
Voltic's one-shot `implied_vol_fast` is about 48 times faster than LBR scalar and about 5.5 times faster than py_vollib_vectorized, with zero catastrophic errors and zero NaN.
5959

@@ -69,7 +69,7 @@ The CLY-3D grid (51,321 deep-OTM-weighted points; defined in Cui, Liu, Yao 2021
6969

7070
voltic, LBR, and py_vollib_vectorized all sit at 1.539e-9 max abs σ error (the f64 reverse-Black floor at the deep-OTM near-expiry corner). voltic is 36.7 times faster than LBR scalar and 4.2 times faster than py_vollib_vectorized.
7171

72-
Voltic's 13 NaN are rows where `σ_true = VOL_MIN = 0.01` exactly, excluded by the open-interval domain. See [Accuracy: known gaps](#accuracy-known-gaps).[^1][^2]
72+
Voltic's 13 NaN are rows where `σ_true = VOL_MIN = 0.01` exactly, excluded by the open-interval domain. See [Accuracy: known gaps](#accuracy-known-gaps).
7373

7474
### Benchmarks: ATM-dense (near-at-the-money grid)
7575

@@ -81,7 +81,7 @@ Real options markets are densest at the money. The SplitMix64 dataset (1M synthe
8181
| py_lets_be_rational (scalar) | 5,315 | 3.338e-03 | 0 |
8282
| py_vollib_vectorized | 498 | 3.338e-03 | 0 |
8383

84-
voltic and LBR sit at the same max error (3.338e-3, governed by 2 deep-wing cases shared by all three solvers); voltic is 78 times faster than LBR scalar on the ATM regime. voltic's 288 NaN are rows where `σ_true = VOL_MIN = 0.01` exactly, excluded by voltic's open-interval domain.
84+
voltic and LBR sit at the same max error (3.338e-3, governed by 2 deep-wing cases shared by all three solvers); voltic is 78 times faster than LBR scalar on the ATM regime. voltic's 288 NaN are rows where `σ_true = VOL_MIN = 0.01` exactly, excluded by voltic's open-interval domain. See [Accuracy: known gaps](#accuracy-known-gaps).
8585

8686
---
8787

@@ -136,7 +136,7 @@ let iv = implied_vol_fast(&spot, &strike, &tte, &rate, &price, &kind);
136136

137137
### `OtmContext::new` + `implied_vol_with_context_batch`: throughput-prioritized split API
138138

139-
The `(k, T)`-only prelude is built once and reused across many price evaluations on the same `(strike, expiry)` node, e.g. vol-surface calibration, MC repricing on a fixed grid, scenario sweeps. About 34 to 40 ns/option per evaluation. This path skips the rational-fallback step `implied_vol_fast` uses, so it trades accuracy for speed: callers must already filter their input domain to the well-conditioned interior. Use `implied_vol_fast` for accuracy-critical paths.
139+
The `(k, T)`-only prelude is built once and reused across many price evaluations on the same `(strike, expiry)` node, e.g. vol-surface calibration, MC repricing on a fixed grid, scenario sweeps. About 34 to 40 ns/option per evaluation. This path skips the rational-fallback step `implied_vol_fast` uses, so on unfiltered grids it produces catastrophic errors (e.g. ~20% of rows on CLY-3D, max σ error 0.85); it is only correct on pre-filtered interior input. Use `implied_vol_fast` for accuracy-critical paths.
140140

141141
```rust
142142
use voltic::{OtmContext, implied_vol_with_context_batch};

0 commit comments

Comments
 (0)