Fixed Model.jacobian (used by information, design and fit) took its finite-difference step as 1e-6 * max(|theta|, 1e-3). For a parameter smaller than 1e-3 in its own units the step, 1e-9, was too coarse; for a time constant of 1e-9 s it was the size of the parameter itself. The planned error bars then depended on the units the parameter was written in, a noiseless fit could stop away from the truth (V0 = 0.987 and tau = 0.938 ns instead of 1 and 1 ns in the new test's RC model), and a model that divides by such a parameter was refused as "non-finite". The step is now 1e-6 * |theta|. When that step changes the predictions by less than 1e-8 of their size (always for a parameter that is exactly zero, and for one that is tiny next to the rest of the prediction, such as a slope of 1e-12 beside an offset of 1), the 0.1.0 step 1e-6 * max(|theta|, 1e-3) is used instead: a purely relative step would there be lost in floating-point rounding and give wrong slopes, wrong error bars and false "cannot tell the parameters apart" refusals. Results for parameters of size 1e-3 or more are unchanged. Tests New test_small_parameters_unit_invariant: the same RC model with tau in seconds and in nanoseconds gives the same planned error bars (to 1 part in 10^6) and the same noiseless fit, and the slopes of a model that divides by a 1e-9 parameter are finite and exact to 1 part in 10^6. It fails on 0.1.0. New test_near_zero_parameter_keeps_a_resolvable_step: for a straight line with slope 1e-12, 1e-300 or 0, the slopes match the exact ones to 1 part in 10^6, and a noiseless fit of a flat line returns the textbook covariance. It guards the fallback above. The CI matrix now includes Python 3.10, which the classifiers claim but CI did not run, and a new oldest-dependencies job runs the suite on Python 3.9 with NumPy 1.22.0 and pytest 7.0.0, the lowest versions pyproject.toml allows. Changed README rewritten in plain language, with worked examples whose printed output is checked, a list of the actual refusals, and each test described with the tolerance it really uses. Corrections to the v0.1.0 notes "the recomputed greedy rule": no test recomputes the greedy selection step by step. The tests check that the picks are distinct, that they beat 30 random subsets, and that the two-point pick equals the best pair found by exhaustion. "linear-model covariance equals the textbook closed form exactly, planner and fit agree as one matrix": the tests assert this to a relative tolerance of 1e-6, not exactly. Full history: CHANGELOG.md
Tanvir M. Mahim· Zenodo (CERN European Organi...· 0 citations
Fixed Model.jacobian (used by information, design and fit) took its finite-difference step as 1e-6 * max(|theta|, 1e-3). For a parameter smaller than 1e-3 in its own units the step, 1e-9, was too coarse; for a time constant of 1e-9 s it was the size of the parameter itself. The planned error bars then depended on the units the parameter was written in, a noiseless fit could stop away from the truth (V0 = 0.987 and tau = 0.938 ns instead of 1 and 1 ns in the new test's RC model), and a model that divides by such a parameter was refused as "non-finite". The step is now 1e-6 * |theta|. When that step changes the predictions by less than 1e-8 of their size (always for a parameter that is exactly zero, and for one that is tiny next to the rest of the prediction, such as a slope of 1e-12 beside an offset of 1), the 0.1.0 step 1e-6 * max(|theta|, 1e-3) is used instead: a purely relative step would there be lost in floating-point rounding and give wrong slopes, wrong error bars and false "cannot tell the parameters apart" refusals. Results for parameters of size 1e-3 or more are unchanged. Tests New test_small_parameters_unit_invariant: the same RC model with tau in seconds and in nanoseconds gives the same planned error bars (to 1 part in 10^6) and the same noiseless fit, and the slopes of a model that divides by a 1e-9 parameter are finite and exact to 1 part in 10^6. It fails on 0.1.0. New test_near_zero_parameter_keeps_a_resolvable_step: for a straight line with slope 1e-12, 1e-300 or 0, the slopes match the exact ones to 1 part in 10^6, and a noiseless fit of a flat line returns the textbook covariance. It guards the fallback above. The CI matrix now includes Python 3.10, which the classifiers claim but CI did not run, and a new oldest-dependencies job runs the suite on Python 3.9 with NumPy 1.22.0 and pytest 7.0.0, the lowest versions pyproject.toml allows. Changed README rewritten in plain language, with worked examples whose printed output is checked, a list of the actual refusals, and each test described with the tolerance it really uses. Corrections to the v0.1.0 notes "the recomputed greedy rule": no test recomputes the greedy selection step by step. The tests check that the picks are distinct, that they beat 30 random subsets, and that the two-point pick equals the best pair found by exhaustion. "linear-model covariance equals the textbook closed form exactly, planner and fit agree as one matrix": the tests assert this to a relative tolerance of 1e-6, not exactly. Full history: CHANGELOG.md
Tanvir M. Mahim· Zenodo (CERN European Organi...· 0 citations
0.2.0 reported that, with a delta-sigma divider, the edge-level loop shows in-band noise that the exact linear sampled-data model misses, even with perfectly matched pumps, and that its mechanism was not identified. 0.3.0 identifies it, computes it and tests it. The mechanism A PFD/charge-pump pulse is a rectangle of charge q = pol Icp tau lasting |tau| on one side of the reference edge, not an impulse at the edge. Expanding the exact response over the pulse gives two moments: The zeroth moment is the impulse the linear model uses. The first moment adds -(pol Icp tau^2 / 2) M B to the loop state. The charge centroid sits tau/2 from the edge for either edge order. The delta-sigma divider makes tau fluctuate, so tau^2 carries difference-frequency content that lands in the loop band. Two parts of the correction nearly cancel: the in-pulse control-voltage ramp, Kvco Icp tau^2 / (2 C_shunt); the filter's charge redistribution. The oscillator row of e^{Mt} M B is Kvco times the filter's control-voltage impulse response, so what lasts is Kvco Icp tau^2 / (2 C_total). That is why the effect does not depend on C_shunt, as 0.2.0 observed. How it was established No fitted parameters were used: The effect was isolated in the residual between the edge-level run and the exact linear map. Its spectral shape was resolved. It peaks near the loop bandwidth, and the 'flat floor' of 0.2.0 was coarse Welch bins. Linear explanations were ruled out, including loop-gain and timing mismatch. The source was measured in single-pulse runs. Ablation showed that each half of the pulse correction alone is about 20 dB off, and together they are right. The second-order divider-timing terms are negligible. New simulate_sampled(order=1|2): a fast per-cycle loop. Order 2 includes every second-order pulse-width effect, computed self-consistently from its own state. It reproduces the edge-level simulator and runs about 5x faster. pulse_doublet_vector: the correction direction M B. How it is checked (7 new tests, 57 total, Python 3.9-3.14) Order 2 vs the edge-level simulator: per-cycle pulse widths to 1e-15 s, time-domain residual more than 1000x below the linear map's, and in-band levels within 0.5 dB. This holds at C_shunt 100 and 400 pF and with negative Kvco. Order 1: equals the exact linear sampled map. Doublet oscillator row: Kvco/C_shunt at t = 0+ and Kvco/C_total at long times. Pulse-width scaling: the effect drops about 6 dB when the pulse width halves at the same loop, in both the edge-level run and the order-2 map. Limits The order-2 map assumes matched pumps, no dead zone and a constant small-signal Kvco. Third-order terms are neglected; in the designs checked they are 60 dB or more below the effect. For mismatch, dead zones, measured curves and large signals, use the edge-level simulator.
Tanvir M. Mahim· Zenodo (CERN European Organi...· 0 citations
First release: the charge-pump fractional-N loop, noise, delta-sigma, tuning-curve, lock and measurement-planning machinery distilled from a monolithic GaN-on-SOI HEMT-varactor PLL co-design study, generalized to any technology that fits a charge-pump loop -- CMOS, SiGe, GaN or board-level. The physics-informed-ML and adjoint layers of that study stay with the study; what generalizes is here, running on YOUR measured tuning curves and noise points, each behind a mandatory reference field. What is inside filters / loop: the general passive loop-filter one-port, L = Icp Kvco Z / (jw N), exact complementary transfers, and a crossover/phase-margin report with validity refusals -- no crossover, non-positive margin, or a crossover past f_ref/10, the classical validity edge of the averaged continuous-time model (Gardner, IEEE Trans. Commun. 28, 1849 (1980)). mash: MASH 1/2/3 delta-sigma division sequences computed with exact integer accumulators, and the one-sided quantization phase PSD. First-order modulation is refused: it produces discrete spurs, not the smooth PSD. noise: measured NoiseSpec points with mandatory provenance and no extrapolation, the three-path closed-loop noise assembly, one-sided RMS jitter. tuning: monotone PCHIP tuning curves through measured (Vc, f) points -- negative-Kvco oscillators are first-class -- with analytic-derivative gain, linear temperature interpolation between measured corners, and refusals for folded curves (offending bias voltage named) and any extrapolation. lock: the averaged nonlinear lock transient (saturating tanh detector, leakage, mismatch) on the measured curve, and the closed-form static offset 2 pi atanh(I_leak/Icp - mismatch); refusals for unreachable lock targets and leakage the pump cannot cancel. plan: the closed-form error bar of an averaged jitter measurement and its exact 1/sqrt(n) inversion into instrument time. How this release is checked (26 tests, Python 3.9-3.14) The general filter impedance equals the textbook second-order closed form at machine precision (rtol 1e-12); a branch sent to infinite resistance drops out of the network. 1/(1+L) + L/(1+L) = 1 to 1e-12; the crossover/margin report matches an independent 400,000-point dense-grid reading. The MASH mean division offset equals num/den EXACTLY, asserted with rational arithmetic (fractions.Fraction) over full periods; the sequence ranges hit their closed per-order bounds. The quantization phase PSD closed form matches the Welch spectrum of the exact accumulator sequence for MASH-2 and MASH-3 (median ratio within 15% across the band) -- the formula is validated against the sequence, not taken on authority. (The common textbook form differs by the one/two-sided convention; this package states its convention and tests it.) Jitter reproduces the flat and 1/f^2 closed forms; the noise assembly equals an independently computed |L/(1+L)|^2 N^2 path to 1e-12. The PCHIP tuning gain equals a central finite difference across the fitted curve; the fitted curve hits the measured points exactly. The integrated nonlinear lock transient settles to the closed-form static offset and puts the oscillator exactly on N f_ref (two independent routes, one number). The measurement-planning error bar matches a 4000-trial seeded Monte Carlo with exponentially distributed periodogram bins; the inversion is asserted on both sides (n meets the target, n-1 fails it). Honest limits Everything here is the AVERAGED model: per-edge PFD behavior (dead zone, cycle-slip granularity, reset overlap) is below its resolution, and the stability report refuses past f_ref/10 rather than pretending otherwise. No device physics, no transistor models and no PDK data ship with this package: the source study's foundry PDK files are licensed material and are not redistributed.
Tanvir M. Mahim· Zenodo (CERN European Organi...· 0 citations
First release: the charge-pump fractional-N loop, noise, delta-sigma, tuning-curve, lock and measurement-planning machinery distilled from a monolithic GaN-on-SOI HEMT-varactor PLL co-design study, generalized to any technology that fits a charge-pump loop -- CMOS, SiGe, GaN or board-level. The physics-informed-ML and adjoint layers of that study stay with the study; what generalizes is here, running on YOUR measured tuning curves and noise points, each behind a mandatory reference field. What is inside filters / loop: the general passive loop-filter one-port, L = Icp Kvco Z / (jw N), exact complementary transfers, and a crossover/phase-margin report with validity refusals -- no crossover, non-positive margin, or a crossover past f_ref/10, the classical validity edge of the averaged continuous-time model (Gardner, IEEE Trans. Commun. 28, 1849 (1980)). mash: MASH 1/2/3 delta-sigma division sequences computed with exact integer accumulators, and the one-sided quantization phase PSD. First-order modulation is refused: it produces discrete spurs, not the smooth PSD. noise: measured NoiseSpec points with mandatory provenance and no extrapolation, the three-path closed-loop noise assembly, one-sided RMS jitter. tuning: monotone PCHIP tuning curves through measured (Vc, f) points -- negative-Kvco oscillators are first-class -- with analytic-derivative gain, linear temperature interpolation between measured corners, and refusals for folded curves (offending bias voltage named) and any extrapolation. lock: the averaged nonlinear lock transient (saturating tanh detector, leakage, mismatch) on the measured curve, and the closed-form static offset 2 pi atanh(I_leak/Icp - mismatch); refusals for unreachable lock targets and leakage the pump cannot cancel. plan: the closed-form error bar of an averaged jitter measurement and its exact 1/sqrt(n) inversion into instrument time. How this release is checked (26 tests, Python 3.9-3.14) The general filter impedance equals the textbook second-order closed form at machine precision (rtol 1e-12); a branch sent to infinite resistance drops out of the network. 1/(1+L) + L/(1+L) = 1 to 1e-12; the crossover/margin report matches an independent 400,000-point dense-grid reading. The MASH mean division offset equals num/den EXACTLY, asserted with rational arithmetic (fractions.Fraction) over full periods; the sequence ranges hit their closed per-order bounds. The quantization phase PSD closed form matches the Welch spectrum of the exact accumulator sequence for MASH-2 and MASH-3 (median ratio within 15% across the band) -- the formula is validated against the sequence, not taken on authority. (The common textbook form differs by the one/two-sided convention; this package states its convention and tests it.) Jitter reproduces the flat and 1/f^2 closed forms; the noise assembly equals an independently computed |L/(1+L)|^2 N^2 path to 1e-12. The PCHIP tuning gain equals a central finite difference across the fitted curve; the fitted curve hits the measured points exactly. The integrated nonlinear lock transient settles to the closed-form static offset and puts the oscillator exactly on N f_ref (two independent routes, one number). The measurement-planning error bar matches a 4000-trial seeded Monte Carlo with exponentially distributed periodogram bins; the inversion is asserted on both sides (n meets the target, n-1 fails it). Honest limits Everything here is the AVERAGED model: per-edge PFD behavior (dead zone, cycle-slip granularity, reset overlap) is below its resolution, and the stability report refuses past f_ref/10 rather than pretending otherwise. No device physics, no transistor models and no PDK data ship with this package: the source study's foundry PDK files are licensed material and are not redistributed.
Tanvir M. Mahim· Zenodo (CERN European Organi...· 0 citations
Experimental-conditions release: the two knobs every measurement actually has -- a temperature and lab units -- plus an honest convergence report. Added Finite-temperature subband filling. fill_subbands_thermal implements the closed form n_i = dos_i kT ln(1 + exp((E_i - E_F)/kT)) for 2D parabolic hole subbands, and temperature_K is now a parameter of solve_self_consistent, solve_self_consistent_hetero and fill_subbands_kgrid (Fermi-Dirac occupation factor on the k-grid). The default 0 reproduces the historical cold filling exactly -- the same code path, asserted bit for bit in the tests. The Boltzmann constant in eV/K (KB_EV_PER_K) is computed from the two exact SI defining constants (k_B and e, both exact since the 2019 redefinition), not typed by hand. Lab units in and out. sheet_density_from_cm2 / sheet_density_to_cm2: exact powers of ten between the cm^-2 a lab quotes and the nm^-2 the solver speaks -- the single most common way to be wrong by orders of magnitude when driving the solver from measured numbers. SelfConsistentResult.converged. An iteration-starved run now reports its failure instead of hiding it in a residual the caller must remember to inspect. Changed The k-grid filler's undersized-window refusal extends to finite temperature (a Fermi tail reaching the grid edge is refused, as the T = 0 Fermi disc was). README rewritten: organized by what the package does rather than by release history, in plainer language, same facts and citations. Anchors (asserted in tests/test_thermal.py, not stated) KB_EV_PER_K from the exact SI definitions agrees with the CODATA eV/K value to 1e-14. The thermal closed form matches direct numerical quadrature of the Fermi-Dirac occupation over the constant 2D DOS (two independent code paths) to 1e-10 at several Fermi levels. temperature_K = 0 routes through the identical T = 0 filler (array_equal), the T -> 0 limit converges to it, and neutrality is exact (1e-15) at 4.2, 77 and 300 K. Warming moves holes from the top subband into lower ones -- the physics the temperature knob controls. On the exactly parabolic demo model the finite-T k-grid filler agrees with the closed-form thermal filler; an undersized k-window is refused. The self-consistent loop at 300 K converges with exact neutrality; the T = 0 default reproduces the historical run bit for bit; a max_iter-starved run reports converged = False. 4.6e13 cm^-2 = 0.46 nm^-2 exactly; conversions round-trip exactly. Full test suite: 54 passed (Python 3.9-3.13). See CHANGELOG.md for details.
Tanvir M. Mahim· Zenodo (CERN European Organi...· 0 citations
We use cookies to run the site and, with your consent, for analytics and to show ads.
See our Cookie Policy.