Releases: 0xC000005/PyChebyshev
v0.21.1
TT _dim_order cluster cleanup + open issues + perf + sobol parity
Closes the v0.20+v0.20.1 _dim_order cluster on ChebyshevTT (3 latent bugs surfaced by ultrareview), three open follow-up issues, two perf hoists, and adds ChebyshevTT.sobol_indices() parity.
Fixed (TT _dim_order cluster)
roots/minimize/maximizevalidate against user-frame domain (was storage-frame)inner_productraisesValueErroron mismatched_dim_order(was silently miscomputing)get_evaluation_pointsreturns user-frame columns (was storage-frame)
Open issues closed
#19—eval_multithread-safety: structural fix via_eval_storage_frameprivate helper#20—integrateerror message references user-frame dim#22—_algebra._check_compatibleusesnp.allclose(handles tuple-vs-list domain syntax)
Added
ChebyshevTT.sobol_indices()— first-order + total-order Sobol indices via native TT contraction (O(d·n·r²)), no dense materialization. Cross-validated againstChebyshevApproximation.sobol_indicesto ~1e-9.
Performance
_calculus._optimize_1dvectorized — used by all four classes'minimize/maximizevectorized_eval_batchderivative-matrix hoist withmoveaxiscorrection — speedup for batch derivative eval- Sobol total-order via cached L/R partials — O(d²·n·r²) → O(d·n·r²)
Tests
26 new tests across 7 test files. Total: 1141 passing on Python 3.10/3.11/3.12/3.13. Project coverage 93% (95% on core library).
PR: #23
v0.21.0
Slider/TT Calculus Parity
Closes the calculus parity gap promised since v0.17. After v0.21.0, all four public classes (ChebyshevApproximation, ChebyshevSpline, ChebyshevSlider, ChebyshevTT) support the full calculus surface: integrate, roots, minimize, maximize.
Added
ChebyshevSlider.roots(dim, fixed)— find all roots alongdimwith other dims fixedChebyshevSlider.minimize(dim, fixed)— global minimum alongdimChebyshevSlider.maximize(dim, fixed)— global maximum alongdimChebyshevTT.roots(dim, fixed)— same; user-framedim/fixed, transparent under_dim_order(v0.20+)ChebyshevTT.minimize(dim, fixed)— sameChebyshevTT.maximize(dim, fixed)— same
Implementation
Pure delegation: each method validates via the existing _calculus._validate_calculus_args, reduces N-D to 1-D via self.slice(slice_params), constructs a 1-D ChebyshevApproximation via from_values(), and delegates to its roots()/minimize()/maximize() from v0.9. No new math.
Tests
57 new tests across 9 test classes in tests/test_calculus_completion.py (1112 total project tests pass on Python 3.10/3.11/3.12/3.13).
PR: #21
v0.20.1: TT _dim_order Full Threading + reorder()
Patch release closing the v0.20 known limitations on ChebyshevTT.
What changed
v0.20 shipped with_auto_order() (heuristic dim reordering for rank reduction) but six methods raised NotImplementedError on non-identity _dim_order. v0.20.1 threads _dim_order through every public TT method and adds reorder() as the explicit alignment escape hatch for binary algebra between TTs of different orders.
Threaded methods (no longer guarded)
eval_multi(point, derivative_orders)— point + per-deriv axis labels translated user→storageslice(dim_idx, value)— descending storage_pos processing, mutablelive_dim_orderextrude(dim_idx, lo, hi, n_nodes)— identity branch preserves v0.18 behavior bit-for-bitto_dense()— final transpose via inverse permutationintegrate(dims=, bounds=)partial —storage_formap keys quadrature/contraction/bounds by storage positions- Unary algebra (
__neg__,__mul__scalar,__truediv__scalar) — propagates_dim_order
New public API
ChebyshevTT.reorder(new_order, *, max_rank=None, tolerance=None)— bubble-sort permutation alignment via TT-swap on coefficient cores. Use this to align two TTs of different_dim_orders before binary algebra:result = (tt1 + tt2.reorder(tt1.dim_order))
Binary algebra error message
__add__ / __sub__ on TTs of different _dim_order now raise ValueError (not NotImplementedError) with an actionable fix:
TT dim_order mismatch: [0, 1, 2] vs [2, 0, 1]. Call other = other.reorder(self.dim_order)
(or self = self.reorder(other.dim_order)) to align before adding/subtracting.
Tests
- 1055 tests pass on Python 3.10/3.11/3.12/3.13
- New
tests/test_v0201_dim_threading.py(~63 tests, 9 classes) — TDD-driven per method - v0.20 guard tests flipped from
_raisesto_works - v0.18 TT parity (52 tests) untouched — identity-
_dim_orderpaths unchanged
Compatibility
- Fully backward-compatible. Canonical-order TTs (
with_auto_ordernot called) take the same code path as v0.18-v0.20. - No new dependencies. No version bumps to existing deps.
See CHANGELOG.md for full details.
v0.20.0: Adaptive Refinement + Cross-Language Interop
Adaptive Refinement + Cross-Language Interop
Added
ChebyshevSpline.auto_knots(f, num_dim, domain, ...)classmethod — auto-place knots at function kinks via curvature-spike scan. Heuristic; tunable viathreshold_factor,max_knots_per_dim,n_scan_points.sobol_indices()instance method onChebyshevApproximationandChebyshevSpline— first-order and total-order Sobol sensitivity indices computed directly from spectral coefficients (no Monte Carlo, no extra function evaluations).ChebyshevTT.with_auto_order(f, ...)classmethod — heuristic dimension reordering (greedy-swap or random) to minimize TT rank. Newdim_orderproperty; eval/save/load handle permutation transparently.- Reference
.pcbreaders in Rust and Julia —readers/rust/(Cargo cratepcb_reader) andreaders/julia/(Pkg packagePCBReader) ship as standalone projects within this repo. Delivers on the v0.14 cross-language portability promise.
Beyond MoCaX: auto-knot detection, Sobol indices, and TT dim reordering are PyChebyshev-unique adaptive features. The Rust + Julia readers parse v0.14 .pcb format independently of Python.
Known limitations (planned for v0.20.1)
ChebyshevTT.with_auto_order() threads the permuted _dim_order through eval() and full integrate(). Other methods (eval_multi(), slice(), extrude(), to_dense(), partial integrate(), algebra) raise NotImplementedError/ValueError on non-identity permutations to avoid silent wrong-results bugs. Full threading planned for v0.20.1.
Tests
- 1041 tests passing across Python 3.10–3.13
- 95% line coverage
- 462-test cross-feature suite for v0.20 additions
See CHANGELOG.md for full details.
v0.19.0 — Build & Diagnostics
Three opt-in features for users with slow f or large grids. Strictly additive — no breaking changes. New optional dependency group pychebyshev[viz].
What's new
- Parallel build —
n_workers=ctor kwarg onChebyshevApproximationandChebyshevSplineevaluatesfviaconcurrent.futures.ProcessPoolExecutor.None= sequential,-1=os.cpu_count(), positive int = pool size. - Progress bars —
verbose=2opt-in tqdm bars onChebyshevSpline,ChebyshevSlider, andChebyshevTTbuild paths. plot_convergence(target_error, max_n)onChebyshevApproximation— builds at increasing N, plots error decay on log-y axis.plot_1d/plot_2d_surface/plot_2d_contourinstance methods on all four classes. Usefixed=to constrain dimensions.
Plus optional pychebyshev[viz] (matplotlib + tqdm). Plot methods raise ImportError with install hint when used without the group.
See docs/user-guide/build-diagnostics.md for usage.
Stats
- 997 tests passing (was 949 baseline; +48 new)
- 12 commits across 10 implementation tasks + 2 review-fix commits
- All v0.11–v0.18 functionality preserved
v0.18.0 — TT Feature Parity
After v0.18, ChebyshevTT has full surface parity with ChebyshevApproximation for non-calculus features. Strictly additive — no breaking changes.
What's new
ChebyshevTT.nodes(num_dim, domain, n_nodes)static — Chebyshev grid generation matchingChebyshevApproximation.nodes().ChebyshevTT.from_values(tensor_values, ...)classmethod — build TT directly from a precomputed full tensor via TT-SVD compression, skipping TT-Cross.ChebyshevTT.extrude(params)— add a constant-function dimension; inserts a rank-preserving constant core.ChebyshevTT.slice(params)— fix a dimension at a value via barycentric contraction (fast path at nodes).- TT algebra:
+,-,*(scalar),__neg__, plus in-place variants. TT addition uses block-diagonal core stacking + TT-SVD rounding tomax(self.max_rank, other.max_rank)to prevent rank explosion. ChebyshevTT.to_dense()— materialize the TT chain into a full N-D tensor.
See CHANGELOG.md and docs/user-guide/tensor-train.md for usage.
Stats
- 949 tests passing (was 897 baseline)
- 96% line coverage
- 10 commits across 10 implementation tasks
- All v0.11–v0.17 functionality preserved
v0.17.0 — Integrate Everywhere
After v0.17, every PyChebyshev class supports integration. v0.9 had integrate() on ChebyshevApproximation and ChebyshevSpline; this release closes the gap on ChebyshevSlider and ChebyshevTT.
What's new
ChebyshevSlider.integrate(dims=None, bounds=None)— full and partial integration via the sliding-decomposition closed form. Returns scalar on full integration; aChebyshevSliderover surviving dims on partial.ChebyshevTT.integrate(dims=None, bounds=None)— full and partial integration via Fejér-1 quadrature contraction into each integrated core's node axis. Returns scalar on full integration; aChebyshevTTover surviving dims on partial. Works on TT objects built via Cross, SVD, and ALS methods.
Both implementations support sub-interval bounds, dim-order invariance, and chain through partial integrations consistently.
Implementation notes
- TT integration handles the DCT-II coefficient↔value-space distinction correctly:
_coeff_core_to_value_core(...)is invoked only on integrated cores before applying quadrature weights; kept cores stay in coefficient space (rank-axis matrix absorption is value-space-agnostic). - Slider integration uses the unified rule
new_tensor = vol_outside · source + (pv_new − pv · vol_T)for partial paths, equivalent to the spec's closed form across all classification cases. - 2 new private helpers in
_calculus.py:_slider_partition_intersect(),_integrate_tt_along_dim().
Stats
- 897 tests passing (from 853 baseline)
- 95% line coverage; 97% on
slider.py, 95% ontensor_train.py - 11 commits across 10 implementation tasks
- Math empirically validated to ~1e-11–1e-15 across all paths
Beyond MoCaX
MoCaX 4.3.1 has no integrate() API on any class — PyChebyshev's spectral calculus toolkit is unique to this library.
See CHANGELOG.md and the Spectral Calculus user guide for details.
v0.16.0 — Polish Bundle
The final cosmetic mirror of the MoCaX 4.3.1 surface. Strictly additive — no breaking changes.
What's new
11 v0.16 surface items across all four classes:
clone()deep copy on all four classes (function=None post-clone, like save/load)- Instance getters:
get_max_derivative_order(),get_error_threshold(),get_special_points(),get_evaluation_points(),get_num_evaluation_points() - Static helpers:
peek_format_version(filename),is_dimensionality_allowed(num_dim) defer_build=Truector flag +set_original_function_values(values)— in-place deferred construction (alt to thefrom_values()factory; bit-identical results)- Optional typed helpers
Domain,Ns,SpecialPoints(frozen dataclasses; constructors accept both raw lists and these forms)
Plus: ChebyshevTT now accepts max_derivative_order keyword-only kwarg with __setstate__ backfill for legacy pickles.
See CHANGELOG.md for the full list and docs/user-guide/ergonomics.md for usage examples.
Stats
- 853 tests passing (from 761 baseline)
- 96% line coverage
- 17 commits across 11 implementation tasks
- All v0.11–v0.15 functionality preserved
v0.15.0 — Ergonomics Bundle
v0.15.0 — Ergonomics Bundle
Closes the remaining MoCaX 4.3.1 API-parity gaps with four small, additive features.
Added
additional_data=constructor kwarg onChebyshevApproximation,ChebyshevSpline,ChebyshevSlider, andChebyshevTT— threads user-supplied context through everyf(point, data)call during build, eliminating closure boilerplate.set_descriptor(s)/get_descriptor()on all four classes — free-form text labels.get_derivative_id(orders)registry +eval(point, derivative_id=...)onChebyshevApproximation,ChebyshevSpline, andChebyshevSlider— stable session-local integer IDs over derivative-orders tuples (TT excluded since it has noderivative_orderarg).- Introspection trio
is_construction_finished()/get_constructor_type()/get_used_ns()on all four classes.
Changed
- Breaking:
ChebyshevApproximation.get_derivative_idwas previously a no-op stub returning the input list. It now returns a stable session-localintper registered orders tuple.
Persistence semantics
- Pickle preserves all v0.15 metadata (descriptor, additional_data, derivative-id registry).
- Binary
.pcbsave raisesNotImplementedErrorifadditional_data is not None. Useformat='pickle'for full persistence. Descriptor and derivative-id registry are silently dropped on.pcbsave (reset to""/ empty on load). - Factory-derived interpolants (
extrude,slice, partialintegrate, algebra) reset all v0.15 metadata to defaults.
Tests + coverage
- 761 tests pass (was 663 baseline; +98 new across
test_ergonomics.py,test_binary_format.py,test_barycentric.py). - 96% line coverage across the package.
Docs
- New user-guide page at
docs/user-guide/ergonomics.md. - Binary-format docs extended with v0.15 metadata gap rows.
- MoCaX side-by-side comparison script at
compare_ergonomics.py(local-only, requiresmocax_lib/).
🤖 Generated with Claude Code
v0.14.0 — Portable .pcb binary serialization
Adds an opt-in portable binary serialization format for ChebyshevApproximation and ChebyshevSpline. Cross-language consumers (C/Rust/Julia) can read PyChebyshev interpolants without Python.
Highlights
format='binary'kwarg onsave()— opt-in; default stays'pickle'(no breaking changes).load()auto-detects via 4-byte magic headerb"PCB\x00".- Stdlib
struct+ NumPy only — no new runtime dependencies. - C reference reader at
examples/binary_reader/(~240 lines, libm only). - Format spec at
docs/user-guide/binary-format.md.
Restrictions
- Binary format requires flat
n_nodesforChebyshevSpline. Nested-n_nodessplines raiseNotImplementedErroron binary save and fall back to pickle. ChebyshevSliderandChebyshevTTremain pickle-only in v0.14.
See CHANGELOG.md for full details.