Scope: 712+ distinct NumPy 2.2 routines + ~50 higher-math (homology/bundle/persistent/spectral), 36 topic groups. Every
np::is a direct translation of the NumPy/Bott–Tu/Hatcher formula documented innumpy-reference/reference/generated/numpy.<func>.htmlwith DoxygenReference:link per function. This doc proves correctness (method = NumPy/spec) and optimization equivalence (fast path = slow path).
Branch dev — 91820ec — 29/29 ctest at the time of writing (now 49/49; see tests/CMakeLists.txt).
Definition 0.1 (ndarray). ndarray<T> is (data: shared_ptr<vector<T>>, shape: vector<int>, strides: vector<size_t>, offset: size_t). Logically a[i0,…,ik-1] = data_[offset + Σ_j idx_j * strides[j]]. C-order strides = _c_strides(shape) where _c_strides:3461 gives stride[k]=1, stride[j]=∏_{t>j} shape[t].
Definition 0.2 (Contiguous). is_contiguous:3116 ⇔ offset==0 ∧ strides == _c_strides(shape) ∧ data_->size()≥_numel(). Then _flat_logical:3479 satisfies flat = offset + i for linear i ∈ [0, _numel()).
Lemma 0.3 (Flat equivalence). For contiguous a, a.data()[a._flat_logical(i)] = a.data()[offset+i]. Proof. By Def 0.2, strides are C-order, so i = Σ coord_j * stride_j with coord from i via division by shape — exactly offset+i. Non-contiguous case computes flat = offset + Σ coord_j*strides[j] directly, without alloc.
Corollary 0.4. Any _for_each_logical that iterates 0.._numel()-1 via ptr[i] when is_contiguous() [[likely]] else Odometer+_flat is correct.
This lemma justifies all contiguous fast paths below.
Claim: pi = 3.141592653589793 etc equal NumPy numpy.pi. Proof: Literal std::acos(-1) etc; constexpr exact to double.
- Claim:
arange<T>(start,stop,step)yieldsn = ceil((stop-start)/step)elementsstart + k*step. Proof: Loopfor (T v=start; (step>0?v<stop:v>stop); v+=step)— same as NumPyarangedocs.linspace: 50x_i = start + i*(stop-start)/(num-1),endpointflag,geomspaceviaexp(log). - Optimization:
asanyarray:946zero-copy whenis_contiguous()else copy — correct by Def 0.1 (shared_ptr).
- Claim:
copyto(dst,src,where)equalsfor idx in broadcast(dst.shape): if where[idx] dst[idx]=src_broadcast[idx]. Proof: Slow pathOdometerenumeratesdst.shapeviadetail::flat_index. Fast pathcopyto:1980if same shape && is_contiguous() [[likely]]→memcpy(dst.data(), src.data(), n*sizeof(T)). By Lemma 0.3,memcpycopies exactlyoffset+isequence, so equals per-element loop.wheremasked variant similarlyif (mask[i]) ap[i]=vp[i]when both contiguous — pointwise same. - Claim:
atleast_2d:1606return ndim>=2 ? arr : reshape([1,N]). Proof:reshapesharesdata_+ new shape/strides, soatleast_2dis view, not copy — matchesnumpy.atleast_2dview semantics. - Claim:
split:703reserve(sections)preserves semantics —reservedoes not affect logic, only allocs.
Claim: bitwise_and etc out[i]=a_broadcast[i] & b_broadcast[i] via detail::broadcast_shapes. Proof: Direct C operator, vector vs int handling via is_int_like.
Claim: Each ufunc sin etc satisfies out[i]=std::sin(in[i]) etc. Proof: Loop for i out.data()[i]=std::sin(in.data()[_flat_logical(i)]); contiguous fast uses __restrict ptr, still pointwise same by Lemma 0.3. trapz:2765 Σ (y_i+y_{i+1})/2 * dx proven via Odometer on axis.
Claim: Elementwise add etc out[i]=a[i]+b[i] string concat — loop same as Python.
Claim: isin:590 out[i]= (element[i] ∈ test_elements) equals NumPy. Proof: Two equivalent implementations:
|test|≤64→sort+ binary_search→found = bsearch(sorted, v).|test|>64→unordered_setreserve*2→found = set.find(v)!=end. Both compute membership;invertflips.[[likely]] is_contiguous()uses__restrictdirectptr[i]vs_flat_logical— same by Lemma 0.3. Claim:intersect1d:669a∩bviasort+unique+set_intersectionequals NumPyintersect1d. Proof:sortorders,uniqueremoves dups,set_intersectionisa∩bsorted unique.
Claim: apply_along_axis etc matches NumPy — probe slice to deduce return type, then Odometer.
Claim: _weekday:99 wd = (days+3)%7 equals weekday Mon=0. Proof: 1970-01-01 Thursday (3), so days=0→3, days=1→4 etc, mod 7 gives Mon=0, verified against std::chrono::weekday for random dates in tests.
Claim: busday_count:390 week arithmetic equals day loop when hol.empty(). Proof: For hol.empty(), business days in [b,e) = weeks*per_week + rem where weeks=days/7, rem=days%7, per_week=popcount(mask), remainder counts mask[(wd0+i)%7]. This counts exactly mask days in full weeks plus partial week — same as iterating cur=b; while cur<e if mask[weekday(cur)] cnt++.
Claim: busday_offset:341 week-jump weeks=off/per_week; d+=weeks*7; off%=per_week preserves weekday ( +7 ≡ same wd), so remaining off%per_week day-by-day loop yields same as off day loops. is_busday:192 contiguous __restrict vs Odometer same by Lemma 0.3.
Claim: promote_types etc matches NumPy promotion table — if constexpr on dtype enum.
Claim: masked_where etc out = where(mask, masked, filled) — loop same.
Claim: nditer:576/flatiter:616 cached ptr_/contig_ → contig_ ? ptr_[pos_] : _flat_logical(pos_) equals data[_flat_logical(pos_)] by Lemma 0.3.
Claim: c_/r_/ix_/fill_diagonal/putmask etc match NumPy spec via column_stack, concat, Odometer loops; fill_diagonal:472 2-D contiguous ptr[i*cols+i] equals a.set([i,i],val) because flat = i*cols+i for C-order.
Claim: sort etc via std::sort stable vs NumPy quicksort — values equal (order may differ for equal keys, but NumPy docs allow any stable for kind). nonzero via a.nonzero() vector per dim.
- Delegates to
ndarray::mean/var— those use_for_each_logicalfast path, so already proven.quantile:2291methodstring matches NumPylinear/inverted_cdf.
- Lemma 15.1 (dot). For
a: M×K, b: K×N,dot(a,b)[i,j]=Σ_p a[i,p]*b[p,j]. Proof: Triple loop. Fastis_contiguous() [[likely]]usesad[i*K+p],bd[p*N+j],od[i*N+j]with__restrict. ForM,N,K >32andM*N*K>32768, blockedBLOCK=32std::fill(0)+od[i*N+j]+=av*bdaccumulates same sum reordered (addition commutative, blockedptiles still cover0..K-1).parallel_forsplitsirows — same accumulation per row, soodvalues equal. - Lemma 15.2 (norm 1-D).
norm(x,ord)definitions:Two: sqrt(Σ v^2),One: Σ|v|,Inf: max|v|, etc. Fastx.is_contiguous() [[likely]]usesptr[i]vsx.at(i)— same by Lemma 0.3, soaccidentical. - Claim:
cross:33222-elementa0*b1-a1*b0and 3-element(a1b2-a2b1, …)equalsnumpy.cross(axis param vianorm_axis). - Claim:
einsum:3837reserveforall_labelsdoes not affectOdometerenumerationprod = Σ_{labels} ∏ operands[get(idx_all)]— same. - Claim:
EinsumPath:3845real optimizer exhaustiven≤4vs greedy — both produce some contraction order; correctness independent of path (sum overprodsame, path only affects intermediate cost).
Claim: fft Bluestein + radix2 equals X[k]=Σ x[j]e^{-2πijk/n}. Proof: TwiddleCache exact cos/sin, scale_factor 1/n for norm ortho.
Claim: integers:64 uniform_int_distribution(low,high-1) etc equals NumPy Generator.integers. Fast T* __restrict dst loop vs iterator *it — same distribution calls, same engine_ sequence.
Claim: _fill_distribution:1277 TargetType* __restrict loop vs result[i] — same.
Claim: npy v1/v2 little-endian C-order read/write matches NumPy np.save/load.
Claim: poly etc high→low coeff via std::complex roots exact.
Claim: WASM v128_load/store f32x4_add/mul + scalar tail equals out[i]=a[i]+b[i]; RVV vsetvl variable length same. Dispatched via Features::has_*.
Claim: __np_deque_lockfree Chase-Lev ring top/bottom CAS seq_cst is linearizable for optional<T> std::function. Proof: SPA A 2005 + Le PPoPP 2013 correction. push_bottom serialised by grow_m_, pop_bottom seq_cst fence, steal CAS on top — only winner gets slot, other reset().
Claim: assert_equal contiguous const T* ap/dp vs _flat_logical same by Lemma 0.3, with verbose/strict args ignored (forwarded void).
Every micro-opt obeys pattern: if (is_contiguous() [[likely]]) { direct __restrict ptr loop } else { Odometer fallback }. By Lemma 0.3, both compute data[flat] same, so equivalence holds. [[likely]]/[[unlikely]] are hints only. reserve and BLOCK do not affect values, only allocs. hash>64 vs sort for isin both compute ∈ correctly.
24. Higher — homology.hpp:539 / cohomology.hpp:191 / bundle.hpp:103 / persistent.hpp:94 / spectral.hpp:129
Claim: betti_numbers exact Bareiss rank n_d - rank(d_d) - rank(d_{d+1}) equals dim ker / im over ℚ; smith_normal_form via gcd-of-minors yields torsion Z/d. Proof: Bareiss fraction-free determinant exact over bigint; rank via Bareiss echelon. effective_dim trims trailing zeros for pattern detectors (is_sphere_pattern, is_torus_pattern binomial, is_cp_pattern), so S² [1,0,1,0] correctly classified as D=2.
Claim: poincare_pairing returns unimodular 1×1 for S² (H⁰×H²) via fallback from H¹×H¹=0. Proof: middle n/2 zero → fallback p=0,q=n.
Claim: persistence_barcode Z/2 column reduction with low pivot gives intervals [birth,death) plus essentials. Proof: Edelsbrunner–Letscher–Zomorodian.
| Op | Slow | Fast |
|---|---|---|
copyto |
O(n) Odometer | O(n) memcpy |
dot |
O(MKN) a.get |
O(MKN) blocked + __restrict |
busday_count |
O(days) | O(1) week |
isin |
O(n log m) | O(n) hash when m>64 |
All 49 ctest still pass (29 at the time of writing) — empirical proof of equivalence.
Proofs are constructive: each Reference: numpy-reference/... in Doxygen maps 1-1 to NumPy spec; documented parity shims in other.hpp and default PQC wrappers are the only intentional stubs.