1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
//! Cross-engine validation: the OS/HGP and Rys ERI engines must be
//! **transparent** — same Coulomb integral, same `(a,b,c,d)` block layout — and
//! the `Auto` dispatch must equal whichever engine it picks.
//!
//! Pure Rust, no external library. These tests lock the
//! engine-to-engine agreement, the 8-fold symmetry and falsifiable layout from
//! independently built OS blocks, and the dispatch-boundary behaviour.
use integral::{select_engine, Basis, Engine, Shell};
use integral_math::am::n_cart;
#[test]
fn dispatch_policy_matches_5c_calibration() {
// The 2D crossover: OS/HGP
// wins down to deg 1 for l_total ≤ 4, then once deg ≥ 16 up through l_total
// 16; l_total ≥ 17 stays Rys (no measured OS win at high contraction there).
assert_eq!(select_engine(0, 1), Engine::OsHgp); // L0: OS even uncontracted
assert_eq!(select_engine(4, 1), Engine::OsHgp); // l_total 4, deg 1 → OS (was Rys)
assert_eq!(select_engine(8, 1), Engine::Rys); // l_total 8, deg 1 → Rys
assert_eq!(select_engine(8, 15), Engine::Rys); // below deg 16 → Rys
assert_eq!(select_engine(8, 16), Engine::OsHgp); // deg 16 (K≥2) → OS (was 81)
assert_eq!(select_engine(16, 16), Engine::OsHgp); // cap relaxed up to l_total 16
assert_eq!(select_engine(16, 1), Engine::Rys); // …but deg 1 still Rys there
assert_eq!(select_engine(17, usize::MAX), Engine::Rys); // l_total ≥ 17: always Rys
}
/// `|os − rys| ≤ atol + rtol·|rys|` with `atol = 1e-11`, `rtol = 1e-10`. The two
/// engines are independent f64 recurrences agreeing to ~1e-12 on dominant
/// elements; the atol floor absorbs benign near-cancellation on tiny components.
fn assert_close(os: &[f64], rys: &[f64], tag: &str) {
assert_eq!(os.len(), rys.len(), "{tag}: length mismatch");
const ATOL: f64 = 1e-11;
const RTOL: f64 = 1e-10;
let mut worst = 0.0_f64;
for (i, (o, r)) in os.iter().zip(rys.iter()).enumerate() {
let d = (o - r).abs();
worst = worst.max(d);
assert!(
d <= ATOL + RTOL * r.abs(),
"{tag}[{i}]: OS {o} vs Rys {r} (Δ={d:e})"
);
}
assert!(worst.is_finite(), "{tag}: non-finite Δ");
}
/// s (contracted), p, d, f on four distinct centres — every (ij|kl) block is
/// genuinely distinct, and several shells are contracted.
fn mixed_basis() -> Basis {
Basis::new(vec![
Shell::new(0, [0.0, 0.0, 0.0], vec![1.4, 0.5], vec![0.6, 0.5]).unwrap(), // s, 2 prim
Shell::new(1, [0.6, -0.3, 0.2], vec![0.9, 0.35], vec![0.55, 0.5]).unwrap(), // p, 2 prim
Shell::new(2, [-0.4, 0.7, -0.1], vec![1.1], vec![1.0]).unwrap(), // d
Shell::new(3, [0.2, 0.5, 0.8], vec![0.7], vec![1.0]).unwrap(), // f
])
}
#[test]
fn os_matches_rys_block_sweep() {
// A spread of quartets with mixed L on four distinct centres, including the
// mixed-high-L (dd|ff) case and contracted indices (shells 0 and 1).
let basis = mixed_basis();
let quartets = [
(0, 0, 0, 0),
(1, 0, 0, 0),
(0, 1, 0, 0),
(1, 1, 1, 1),
(2, 0, 1, 0),
(2, 1, 2, 1),
(0, 1, 2, 3), // (sp|df) — four different L
(3, 0, 2, 1),
(2, 2, 3, 3), // (dd|ff) — mixed high-L
(3, 3, 3, 3), // (ff|ff)
];
for (i, j, k, l) in quartets {
let os = basis.eri_block_with(Engine::OsHgp, i, j, k, l);
let rys = basis.eri_block_with(Engine::Rys, i, j, k, l);
let s = basis.shells();
assert_close(
&os,
&rys,
&format!("(l{} l{}|l{} l{})", s[i].l(), s[j].l(), s[k].l(), s[l].l()),
);
}
}
#[test]
fn os_matches_rys_diffuse_tight() {
// Extreme exponent ratio (1e3 / 1e-3) on a (pp|pp) quartet — the conditioning
// stress case. Both engines must still agree.
let basis = Basis::new(vec![
Shell::new(1, [0.0, 0.0, 0.0], vec![1.0e3], vec![1.0]).unwrap(),
Shell::new(1, [0.0, 0.0, 1.2], vec![1.0e-3], vec![1.0]).unwrap(),
]);
let os = basis.eri_block_with(Engine::OsHgp, 0, 1, 0, 1);
let rys = basis.eri_block_with(Engine::Rys, 0, 1, 0, 1);
assert_close(&os, &rys, "diffuse×tight (pp|pp)");
}
#[test]
fn os_matches_rys_high_contraction() {
// High contraction degree on every centre (the regime OS/HGP targets): a
// 6-primitive s and a 4-primitive p, so the (sp|sp) quartet contracts
// 6·4·6·4 = 576 primitive quartets behind a single early-contraction HRR.
let basis = Basis::new(vec![
Shell::new(
0,
[0.0, 0.0, 0.0],
vec![30.0, 10.0, 3.0, 1.0, 0.4, 0.15],
vec![0.02, 0.08, 0.2, 0.35, 0.3, 0.12],
)
.unwrap(),
Shell::new(
1,
[0.3, 0.2, 1.0],
vec![1.2, 0.6, 0.3, 0.12],
vec![0.3, 0.4, 0.25, 0.1],
)
.unwrap(),
]);
let os = basis.eri_block_with(Engine::OsHgp, 0, 1, 0, 1);
let rys = basis.eri_block_with(Engine::Rys, 0, 1, 0, 1);
assert_close(&os, &rys, "high-contraction (sp|sp)");
}
#[test]
fn eight_fold_symmetry_from_os_blocks() {
// The dense builder scatters one evaluation per unique quartet, so its
// shell-level symmetry is exact by construction. The genuine OS/HGP
// recurrence check therefore compares independently *computed* permuted
// blocks (`eri_block_with` evaluates each quartet directly, with no
// symmetrization): (ij|kl) and σ(ij|kl) come from different VRR/HRR paths,
// so their agreement is a real assertion on the recurrences.
let basis = mixed_basis();
let shells = basis.shells();
let nsh = shells.len();
let nc: Vec<usize> = shells.iter().map(|s| n_cart(s.l())).collect();
const PERMS: [[usize; 4]; 8] = [
[0, 1, 2, 3],
[1, 0, 2, 3],
[0, 1, 3, 2],
[1, 0, 3, 2],
[2, 3, 0, 1],
[2, 3, 1, 0],
[3, 2, 0, 1],
[3, 2, 1, 0],
];
// Metric mirrors `eri_maxima`: a tight *relative* residual on the significant
// elements (|base| ≥ 1e-3·peak) plus an absolute floor for the rest. A floorless
// relative residual would over-weight structurally-near-zero elements, where the
// two permutation paths differ only by f64 round-off (~1e-16 abs) that any
// value-changing kernel optimisation perturbs — and which the consumer never
// sees, since it reuses one computed value per unique quartet.
let mut peak = 0.0_f64;
let mut blocks: Vec<Vec<f64>> = Vec::new();
for i in 0..nsh {
for j in 0..nsh {
for k in 0..nsh {
for l in 0..nsh {
let block = basis.eri_block_with(Engine::OsHgp, i, j, k, l);
peak = block.iter().fold(peak, |m, &x| m.max(x.abs()));
blocks.push(block);
}
}
}
}
let floor = 1e-3 * peak;
let block_of =
|q: [usize; 4]| -> &Vec<f64> { &blocks[((q[0] * nsh + q[1]) * nsh + q[2]) * nsh + q[3]] };
let mut worst_sig = 0.0_f64; // worst relative residual on significant elements
let mut worst_abs = 0.0_f64; // worst absolute residual anywhere
for i in 0..nsh {
for j in 0..nsh {
for k in 0..nsh {
for l in 0..nsh {
let q = [i, j, k, l];
let base = block_of(q);
let nq = [nc[i], nc[j], nc[k], nc[l]];
for perm in &PERMS[1..] {
let qp = [q[perm[0]], q[perm[1]], q[perm[2]], q[perm[3]]];
let pb = block_of(qp);
let np = [nc[qp[0]], nc[qp[1]], nc[qp[2]], nc[qp[3]]];
for a in 0..nq[0] {
for b in 0..nq[1] {
for c in 0..nq[2] {
for d in 0..nq[3] {
let src = ((a * nq[1] + b) * nq[2] + c) * nq[3] + d;
let comp = [a, b, c, d];
let dst = ((comp[perm[0]] * np[1] + comp[perm[1]]) * np[2]
+ comp[perm[2]])
* np[3]
+ comp[perm[3]];
let dv = (base[src] - pb[dst]).abs();
worst_abs = worst_abs.max(dv);
if base[src].abs() >= floor {
worst_sig = worst_sig.max(dv / base[src].abs());
}
}
}
}
}
}
}
}
}
}
assert!(
worst_sig < 1e-10,
"worst OS symmetry significant-relative residual {worst_sig:e}"
);
assert!(
worst_abs < 1e-10 * peak.max(1.0) + 1e-12,
"worst OS symmetry absolute residual {worst_abs:e} (peak {peak:e})"
);
}
#[test]
fn os_block_layout_matches_dense_strides_and_is_falsifiable() {
// The forced-OS `eri_block` must equal the forced-OS dense slice under the
// documented row-major (a,b,c,d) layout; a deliberate (c,d) transpose must
// make the comparison fail (so the layout test has teeth).
let basis = mixed_basis();
let n = basis.nao_cart();
let dense = basis.eri_with(Engine::OsHgp);
let shells = basis.shells();
let offs: Vec<usize> = {
let mut acc = 0;
let mut v = Vec::new();
for s in shells {
v.push(acc);
acc += s.n_cart();
}
v
};
let (qi, qj, qk, ql) = (1usize, 0usize, 2usize, 3usize); // (ps|df), all distinct L
let block = basis.eri_block_with(Engine::OsHgp, qi, qj, qk, ql);
let (na, nb, nc, nd) = (
n_cart(shells[qi].l()),
n_cart(shells[qj].l()),
n_cart(shells[qk].l()),
n_cart(shells[ql].l()),
);
assert_eq!(block.len(), na * nb * nc * nd);
let mut transpose_would_differ = false;
for a in 0..na {
for b in 0..nb {
for c in 0..nc {
for d in 0..nd {
let src = ((a * nb + b) * nc + c) * nd + d;
let (i, j, k, l) = (offs[qi] + a, offs[qj] + b, offs[qk] + c, offs[ql] + d);
let dval = dense[((i * n + j) * n + k) * n + l];
assert!(
(block[src] - dval).abs() <= 1e-12 * dval.abs().max(1e-12),
"OS layout mismatch at {src} ({i}{j}|{k}{l}): {} vs {}",
block[src],
dval
);
// The deliberately wrong (c,d)-transposed index: if it differs
// from the correct value anywhere, the layout test is sensitive.
if c != d && nc == nd {
let wrong = ((a * nb + b) * nd + d) * nc + c;
if (block[wrong] - dval).abs() > 1e-9 * dval.abs().max(1e-12) {
transpose_would_differ = true;
}
}
}
}
}
}
// For (ps|df), nc (d=6) ≠ nd (f=10), so the transpose is a different shape;
// assert the block is non-trivial instead (the dense-slice equality above is
// the falsifiable layout check — a transposed engine output would fail it).
let _ = transpose_would_differ;
assert!(
block.iter().any(|&x| x.abs() > 1e-6),
"OS block unexpectedly ~zero"
);
}
#[test]
fn auto_dispatch_equals_both_forced_engines() {
// Across the crossover boundary, `Auto` must (a) equal the engine it selects
// and (b) since both engines agree, equal *both* forced results. These quartets
// straddle the policy: the contracted low-L ones
// dispatch to OS/HGP, the low-contraction higher-L ones to Rys — yet `Auto`
// matches both. (The exhaustive per-boundary fingerprint is in `dispatch.rs`.)
let basis = mixed_basis();
let quartets = [
(0, 0, 0, 0), // l_total 0
(1, 1, 0, 0), // 2
(1, 1, 1, 0), // 3
(1, 1, 1, 1), // 4 (boundary, OS side)
(2, 1, 1, 1), // 5 (Rys side)
(2, 2, 3, 3), // 10 (Rys side)
];
for (i, j, k, l) in quartets {
let auto = basis.eri_block_with(Engine::Auto, i, j, k, l);
let os = basis.eri_block_with(Engine::OsHgp, i, j, k, l);
let rys = basis.eri_block_with(Engine::Rys, i, j, k, l);
let s = basis.shells();
let tag = format!(
"auto-vs-os (l{} l{}|l{} l{})",
s[i].l(),
s[j].l(),
s[k].l(),
s[l].l()
);
assert_close(&auto, &os, &tag);
let tag2 = format!(
"auto-vs-rys (l{} l{}|l{} l{})",
s[i].l(),
s[j].l(),
s[k].l(),
s[l].l()
);
assert_close(&auto, &rys, &tag2);
}
}