lockkernel 1.2.0__tar.gz → 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lockkernel-1.2.0/src/lockkernel.egg-info → lockkernel-1.3.0}/PKG-INFO +230 -29
- {lockkernel-1.2.0 → lockkernel-1.3.0}/README.md +229 -28
- {lockkernel-1.2.0 → lockkernel-1.3.0}/pyproject.toml +1 -1
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel/__init__.py +2 -2
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel/exact.py +27 -6
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel/kernels.py +57 -7
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel/lineshapes.py +14 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel/measured.py +253 -48
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel/parametric.py +59 -7
- {lockkernel-1.2.0 → lockkernel-1.3.0/src/lockkernel.egg-info}/PKG-INFO +230 -29
- {lockkernel-1.2.0 → lockkernel-1.3.0}/tests/test_cumulant.py +47 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/tests/test_measured.py +168 -2
- {lockkernel-1.2.0 → lockkernel-1.3.0}/tests/test_onset.py +182 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/LICENSE +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/MANIFEST.in +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/NOTICE +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/setup.cfg +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel/cumulant.py +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel/ensemble.py +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel.egg-info/SOURCES.txt +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel.egg-info/dependency_links.txt +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel.egg-info/requires.txt +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/src/lockkernel.egg-info/top_level.txt +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/tests/conftest.py +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/tests/test_meanfield.py +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/tests/test_parametric.py +0 -0
- {lockkernel-1.2.0 → lockkernel-1.3.0}/tests/test_universality.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lockkernel
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Locking kernel universality: exact thresholds and exponents of synchronization transitions, and fits of measured branches with error bars and refusals
|
|
5
5
|
Author: Tanvir Mahmud Mahim
|
|
6
6
|
License: Apache-2.0
|
|
@@ -59,10 +59,13 @@ The collective motion must be the one the oscillators themselves
|
|
|
59
59
|
produce (the "self-consistency condition"); one substitution turns
|
|
60
60
|
that condition into an exact formula (a "parametric solution") valid
|
|
61
61
|
for any frequency spread and any kernel. The exponent depends only on how fast the kernel falls off
|
|
62
|
-
far from the
|
|
62
|
+
far from the center (its **tail**). The **lab half** (`lockkernel.measured`)
|
|
63
63
|
works the other way round: it fits measured points for the threshold
|
|
64
64
|
and the exponent, reads the kernel's tail back off the exponent, and
|
|
65
|
-
plans how many points a target error bar costs.
|
|
65
|
+
plans how many points a target error bar costs. It also tests whether
|
|
66
|
+
the data are consistent with the power law at their stated noise, and
|
|
67
|
+
carries the uncertainties of the measured couplings and of calibration
|
|
68
|
+
scales into the error bars. When the data cannot
|
|
66
69
|
support the number asked for, it stops with an error message that says
|
|
67
70
|
why, rather than returning a number that looks fine but is not.
|
|
68
71
|
|
|
@@ -161,8 +164,9 @@ and mpmath 1.2 or newer, and nothing else.
|
|
|
161
164
|
## Examples
|
|
162
165
|
|
|
163
166
|
Each example below runs as written, and the output shown is what it
|
|
164
|
-
printed with lockkernel 1.
|
|
165
|
-
|
|
167
|
+
printed with lockkernel 1.3.0 (examples 1 to 9 print the same as with
|
|
168
|
+
1.2.0). Line widths, couplings and noise levels are illustrative
|
|
169
|
+
values, not taken from any experiment.
|
|
166
170
|
|
|
167
171
|
### 1. Threshold and exponent from the theory
|
|
168
172
|
|
|
@@ -525,6 +529,98 @@ should. `xi^2` is the **Wineland spin-squeezing parameter**:
|
|
|
525
529
|
1 for uncorrelated spins, below 1 when the spins are entangled in a way
|
|
526
530
|
that improves phase measurements.
|
|
527
531
|
|
|
532
|
+
### 10. Are the data consistent with the power law?
|
|
533
|
+
|
|
534
|
+
```python
|
|
535
|
+
import numpy as np
|
|
536
|
+
from lockkernel import fit_branch
|
|
537
|
+
|
|
538
|
+
# Conservative spins on a Lorentzian line of FWHM 1: chi_c = 1/2 and,
|
|
539
|
+
# exactly, R = eps/(1+eps). 14 points from eps = 1e-4, 1 % seeded noise.
|
|
540
|
+
rng = np.random.default_rng(4)
|
|
541
|
+
for eps_max in (0.01, 0.1, 0.5):
|
|
542
|
+
eps = np.geomspace(1e-4, eps_max, 14)
|
|
543
|
+
r = eps / (1 + eps) * np.exp(rng.normal(0.0, 0.01, eps.size))
|
|
544
|
+
fit = fit_branch(0.5 * (1 + eps), r, sigma_r=0.01 * r,
|
|
545
|
+
reference="illustrative: closed form + 1 % noise")
|
|
546
|
+
print(f"eps up to {eps_max:4}: beta = {fit.beta:.4f} +- {fit.sigma_beta:.4f}, "
|
|
547
|
+
f"chi2 = {fit.chi2:5.1f} for {fit.dof} dof, p = {fit.p_value:.2g}")
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
```
|
|
551
|
+
eps up to 0.01: beta = 1.0001 +- 0.0037, chi2 = 11.1 for 11 dof, p = 0.44
|
|
552
|
+
eps up to 0.1: beta = 0.9833 +- 0.0019, chi2 = 48.3 for 11 dof, p = 1.3e-06
|
|
553
|
+
eps up to 0.5: beta = 0.9546 +- 0.0014, chi2 = 584.2 for 11 dof, p = 3.4e-118
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
The true exponent is 1. When the points reach far above the threshold,
|
|
557
|
+
the branch bends away from the power law, and the fit returns a biased
|
|
558
|
+
exponent with a small error bar: 0.9833 +- 0.0019 is 9 error bars from
|
|
559
|
+
1. The error bar alone does not show this. The chi-square test does.
|
|
560
|
+
When `sigma_r` is given, `fit_branch` also returns `chi2` (the weighted
|
|
561
|
+
sum of squared misfits in `log R`), its degrees of freedom `dof`
|
|
562
|
+
(points minus 3) and `p_value`, the chance of a misfit at least this
|
|
563
|
+
large if the law and the stated errors were right. A very small
|
|
564
|
+
`p_value` means one of the two is wrong: drop the points farthest from
|
|
565
|
+
the threshold, or check `sigma_r`. Without `sigma_r` the scatter of the
|
|
566
|
+
points sets the error scale, so there is nothing to test, and `chi2`
|
|
567
|
+
and `p_value` are `None`.
|
|
568
|
+
|
|
569
|
+
### 11. Errors in the couplings, and calibration
|
|
570
|
+
|
|
571
|
+
```python
|
|
572
|
+
import numpy as np
|
|
573
|
+
from lockkernel import fit_branch, with_calibration
|
|
574
|
+
|
|
575
|
+
# Stand-in measurement: R = 0.65 eps^(2/3) above chi_c = 0.5, at 14
|
|
576
|
+
# recorded couplings. Each true coupling differs from the recorded one by
|
|
577
|
+
# a seeded error of 5e-6 (a tenth of the distance to the threshold at the
|
|
578
|
+
# first point), and R carries 1 % seeded noise.
|
|
579
|
+
rng = np.random.default_rng(2)
|
|
580
|
+
chi = 0.5 * (1 + np.geomspace(1e-4, 1e-1, 14))
|
|
581
|
+
sigma_chi = np.full(chi.size, 5e-6)
|
|
582
|
+
chi_true = chi + rng.normal(0.0, 1.0, chi.size) * sigma_chi
|
|
583
|
+
r = 0.65 * (chi_true / 0.5 - 1) ** (2 / 3) * np.exp(rng.normal(0.0, 0.01, chi.size))
|
|
584
|
+
|
|
585
|
+
ref = "illustrative: power law + seeded noise"
|
|
586
|
+
plain = fit_branch(chi, r, ref, sigma_r=0.01 * r)
|
|
587
|
+
full = fit_branch(chi, r, ref, sigma_r=0.01 * r, sigma_chi=sigma_chi)
|
|
588
|
+
for name, f in (("errors of R only:", plain), ("errors of R and chi:", full)):
|
|
589
|
+
print(f"{name:20s} beta = {f.beta:.4f} +- {f.sigma_beta:.4f}, "
|
|
590
|
+
f"chi_c = {f.chi_c:.7f} +- {f.sigma_chi_c:.1e}, p = {f.p_value:.2g}")
|
|
591
|
+
|
|
592
|
+
# The couplings share a 2 % calibration uncertainty, R a 5 % one:
|
|
593
|
+
cal = with_calibration(full, chi_scale_rel=0.02, r_scale_rel=0.05)
|
|
594
|
+
print(f"with calibration: chi_c +- {cal.sigma_chi_c:.1e}, "
|
|
595
|
+
f"A = {cal.amplitude:.3f} +- {cal.sigma_amplitude:.3f}, "
|
|
596
|
+
f"beta +- {cal.sigma_beta:.4f} (unchanged)")
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
```
|
|
600
|
+
errors of R only: beta = 0.6698 +- 0.0020, chi_c = 0.4999987 +- 1.2e-06, p = 0.00051
|
|
601
|
+
errors of R and chi: beta = 0.6658 +- 0.0026, chi_c = 0.5000034 +- 3.7e-06, p = 0.15
|
|
602
|
+
with calibration: chi_c +- 1.0e-02, A = 0.649 +- 0.033, beta +- 0.0026 (unchanged)
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
Near the threshold `R` rises steeply with the coupling, so a small
|
|
606
|
+
error in the coupling moves `R` a lot: by `beta sigma_chi / (chi -
|
|
607
|
+
chi_c)` in `log R`. Pass the coupling errors as `sigma_chi` and
|
|
608
|
+
`fit_branch` adds this term to each point's error (to first order, and
|
|
609
|
+
repeats the fit until the weights settle). Here, without it, the error
|
|
610
|
+
bars are too small and the chi-square test says so (`p = 0.00051`).
|
|
611
|
+
With it the fit is consistent (`p = 0.15`) and the exponent lands within
|
|
612
|
+
its error bar of 2/3. `fit_branch` refuses `sigma_chi` larger than a
|
|
613
|
+
quarter of `chi - chi_c` at any point, where first order is not enough.
|
|
614
|
+
|
|
615
|
+
`with_calibration` adds the uncertainty of an overall scale factor: one
|
|
616
|
+
common to all couplings (for example the conversion of a laser power
|
|
617
|
+
into `chiN`), and one common to all `R` (for example a detection
|
|
618
|
+
efficiency). Scaling every coupling scales the fitted threshold by the
|
|
619
|
+
same factor and leaves `beta` and `A` exactly as they were; scaling
|
|
620
|
+
`R` scales only `A`. So the two calibrations add to the error bars of
|
|
621
|
+
`chi_c` and `A` in quadrature, and the exponent is immune to both. The
|
|
622
|
+
tests check both statements by refitting scaled data.
|
|
623
|
+
|
|
528
624
|
## What is in the package
|
|
529
625
|
|
|
530
626
|
The top level imports the `measured` names below and the submodules
|
|
@@ -571,10 +667,18 @@ directly.
|
|
|
571
667
|
|
|
572
668
|
**Fitting measured data** (`lockkernel.measured`, also at the top level)
|
|
573
669
|
|
|
574
|
-
- `fit_branch(chi, r, reference, sigma_r=None, min_decade=1.0
|
|
575
|
-
returns a `BranchFit` with `chi_c`, `beta`,
|
|
576
|
-
errors, `n_points`, `eps_range`,
|
|
577
|
-
root-mean-square misfit in `log R`) and
|
|
670
|
+
- `fit_branch(chi, r, reference, sigma_r=None, min_decade=1.0,
|
|
671
|
+
sigma_chi=None)` -- returns a `BranchFit` with `chi_c`, `beta`,
|
|
672
|
+
`amplitude`, their errors, `n_points`, `eps_range`,
|
|
673
|
+
`residual_rms_log` (the root-mean-square misfit in `log R`) and
|
|
674
|
+
`reference`. Since 1.3.0 it also has `dof`, `chi2` and `p_value`
|
|
675
|
+
(the last two `None` without `sigma_r`; example 10),
|
|
676
|
+
`sigma_chi_used` and `calibration_rel`. `sigma_chi` gives the errors
|
|
677
|
+
of the couplings (example 11).
|
|
678
|
+
- `with_calibration(fit, chi_scale_rel=0, r_scale_rel=0)` -- the same
|
|
679
|
+
fit with the relative uncertainties of an overall coupling scale and
|
|
680
|
+
an overall `R` scale added to the error bars of `chi_c` and `A`
|
|
681
|
+
(example 11).
|
|
578
682
|
- `kernel_tail_from_beta(beta, sigma_beta=0, n_sigma=2)` -- the tail
|
|
579
683
|
exponent `s` and its error.
|
|
580
684
|
- `beta_relative_sigma(n_points, decades, sigma_log)`,
|
|
@@ -606,7 +710,7 @@ directly.
|
|
|
606
710
|
- `symmetric_exact` (all detunings equal, any number of emitters),
|
|
607
711
|
`full_exact` (full quantum problem, up to about twelve emitters) and
|
|
608
712
|
`class_exact` (emitters grouped by detuning, a few tens) -- exact
|
|
609
|
-
references. `class_exact` is
|
|
713
|
+
references. `class_exact` is tested against `full_exact` since 1.3.0.
|
|
610
714
|
|
|
611
715
|
Each function's docstring (`help(lockkernel.fit_branch)`, for example)
|
|
612
716
|
gives its inputs and conventions.
|
|
@@ -619,12 +723,19 @@ gives its inputs and conventions.
|
|
|
619
723
|
saying where they come from;
|
|
620
724
|
- fewer than 6 points are given, or `chi` and `r` differ in length
|
|
621
725
|
(three parameters with error bars need more);
|
|
622
|
-
- the couplings are not finite and strictly increasing, or
|
|
623
|
-
parameter is not finite and positive (points below the
|
|
624
|
-
`R = 0`, carry no exponent information; drop them);
|
|
625
|
-
- `sigma_r` is not positive or not on the same grid as `r`;
|
|
726
|
+
- the couplings are not finite, positive and strictly increasing, or
|
|
727
|
+
an order parameter is not finite and positive (points below the
|
|
728
|
+
threshold, `R = 0`, carry no exponent information; drop them);
|
|
729
|
+
- `sigma_r` is not finite and positive, or not on the same grid as `r`;
|
|
626
730
|
- the fit does not converge, or its covariance is singular (the data
|
|
627
731
|
cannot pin down the three parameters separately);
|
|
732
|
+
- the fitted exponent runs into the limits of the search, 0.05 or 20
|
|
733
|
+
(new in 1.3.0; the data are not a power law of this kind, for
|
|
734
|
+
example because `R` hardly changes, as at a jump);
|
|
735
|
+
- `sigma_chi` is given without `sigma_r`, is negative, or is larger
|
|
736
|
+
than a quarter of `chi - chi_c` at some point (new in 1.3.0);
|
|
737
|
+
- `with_calibration` gets a negative uncertainty, or a fit that
|
|
738
|
+
already includes one;
|
|
628
739
|
- the fitted threshold is indistinguishable from the smallest
|
|
629
740
|
coupling: the data do not reach the onset;
|
|
630
741
|
- the fitted points span less than `min_decade` decades of `eps`
|
|
@@ -634,9 +745,10 @@ gives its inputs and conventions.
|
|
|
634
745
|
identified), clearly below 1/2 (no kernel gives that; the fit has
|
|
635
746
|
probably left the near-threshold range), or not positive;
|
|
636
747
|
- a planned measurement has fewer than 3 points (6 with the threshold
|
|
637
|
-
fitted, as `fit_branch` needs), a
|
|
638
|
-
non-positive
|
|
639
|
-
more than
|
|
748
|
+
fitted, as `fit_branch` needs), a number of points that is not a
|
|
749
|
+
whole number, a non-positive or reversed range, a non-positive
|
|
750
|
+
scatter or `beta`, a non-positive target, or would need more than
|
|
751
|
+
10^7 points;
|
|
640
752
|
- `extract_beta` meets a point with `eps <= 0`: the branch is at or
|
|
641
753
|
below the threshold there, because it bends back (a first-order
|
|
642
754
|
onset, example 8) or is flat (`R` jumps at the threshold), and there
|
|
@@ -647,11 +759,17 @@ gives its inputs and conventions.
|
|
|
647
759
|
- `fold_interval` finds a fold on a line with compact support (`box`),
|
|
648
760
|
which it cannot refine, or cannot bracket a turning point on its
|
|
649
761
|
grid;
|
|
650
|
-
- `power_tail(s)` is asked for `s <= 1` (the
|
|
651
|
-
infinite), or `heterogeneous` for `gamma <= 2
|
|
652
|
-
`s <= 1`;
|
|
762
|
+
- `power_tail(s)` or `predicted_beta(s)` is asked for `s <= 1` (the
|
|
763
|
+
kernel mass would be infinite), or `heterogeneous` for `gamma <= 2`,
|
|
764
|
+
a non-positive `eta` or `k_min`, or a resulting tail `s <= 1`;
|
|
765
|
+
- a line shape is given a width that is not finite and positive;
|
|
653
766
|
- `tail_integral` is asked for `s` outside `1 < s < 3`, where it
|
|
654
767
|
diverges;
|
|
768
|
+
- `amplitude_general` is asked for a kernel without a tail in
|
|
769
|
+
`1 < s < 3`, or (new in 1.3.0) its default tail amplitude `C`, read
|
|
770
|
+
off the kernel at `|u| = 10^6`, differs by more than a relative 1e-6
|
|
771
|
+
from the value at `10^9` (pass `C` yourself then);
|
|
772
|
+
- `class_exact` gets class populations that are not whole numbers;
|
|
655
773
|
- a line shape without a floating-point distribution
|
|
656
774
|
(`bimodal_gaussian`) is asked for `cdf`, `ppf` or a class table;
|
|
657
775
|
- the solver of the differential equations fails in `evolve` or
|
|
@@ -659,7 +777,7 @@ gives its inputs and conventions.
|
|
|
659
777
|
|
|
660
778
|
## How the results are checked
|
|
661
779
|
|
|
662
|
-
|
|
780
|
+
128 automated tests run on every push and pull request, on Python 3.9
|
|
663
781
|
to 3.14, and once more on Python 3.10 with the oldest NumPy (1.22.0),
|
|
664
782
|
SciPy (1.8.0) and mpmath (1.2.1) the package allows. The numerical
|
|
665
783
|
checks compare the package with something independent of it: a closed
|
|
@@ -720,6 +838,47 @@ forms evaluated separately from the package's integrals)
|
|
|
720
838
|
1e-12; at 20 digits it matches `R/sqrt(eps)` at `Omega = 1e-6` to a
|
|
721
839
|
relative 1e-10 for three kernel-line pairs, and to 2e-6 for `s = 4`.
|
|
722
840
|
|
|
841
|
+
**New in 1.3.0** (15 digits unless stated; every reference is a closed
|
|
842
|
+
form or a calculation done another way)
|
|
843
|
+
|
|
844
|
+
- Kernel masses for slow tails, `power_tail(s)` with `s` = 1.05, 1.1,
|
|
845
|
+
1.25 and 1.5, against `2 (pi/s)/sin(pi/s)` to a relative 1e-14, and
|
|
846
|
+
1e-28 at 30 digits. The averaged Kuramoto kernel of example 6 with
|
|
847
|
+
`gamma` = 3.4, 3.8 and 4.4 against its mass
|
|
848
|
+
`(pi/2)(gamma-2)/(gamma-3)` to 1e-13. `second_moment` for `s` = 3.1,
|
|
849
|
+
3.25 and 3.5 against `2 (pi/s)/sin(3 pi/s)` to 1e-13.
|
|
850
|
+
- For `s = 1.1` on a Lorentzian line the threshold equals
|
|
851
|
+
`s sin(pi/s)/4` to 1e-13, and `chiN/chiN_c - 1` on the branch equals
|
|
852
|
+
`eps` from its separate integral to 1e-10.
|
|
853
|
+
- `tail_integral` against the closed forms on Lorentzian and Gaussian
|
|
854
|
+
lines of widths 0.001, 1 and 1000, for `s` from 1.1 to 2.99, to a
|
|
855
|
+
relative 1e-13 (and 1e-27 at 30 digits). `amplitude_general` against
|
|
856
|
+
its closed form on the Lorentzian line for `s` = 1.1, 1.5, 2.5 and
|
|
857
|
+
2.9, to 1e-12.
|
|
858
|
+
- `amplitude_general` refuses the conservative kernel averaged over
|
|
859
|
+
coupling strengths, whose tail amplitude (a closed form, also checked
|
|
860
|
+
by quadrature) is not reached at `|u| = 10^6`, and accepts the
|
|
861
|
+
averaged Kuramoto kernel, whose tail is an exact power law (its
|
|
862
|
+
default `C` matches the closed form `(gamma-2) B(s/2, 3/2)/2` to give
|
|
863
|
+
the same amplitude to 1e-12).
|
|
864
|
+
- `class_exact` matches `full_exact` (8 emitters, two sets of classes)
|
|
865
|
+
to 1e-10 in `R` and 1e-9 in `xi^2`, with the times in any order.
|
|
866
|
+
- `fit_branch`: `chi2` matches the sum recomputed from the returned
|
|
867
|
+
parameters; over 300 seeded fits under the model the p-values pass a
|
|
868
|
+
Kolmogorov-Smirnov test for uniformity and `chi2` averages to `dof`
|
|
869
|
+
within four standard errors; on the exact conservative branch with
|
|
870
|
+
1 % noise, points up to `eps = 0.01` give `p > 0.05` and `beta`
|
|
871
|
+
within 3 error bars of 1, points up to `eps = 0.5` give
|
|
872
|
+
`p < 1e-10` and `beta` more than 10 error bars off.
|
|
873
|
+
- With coupling noise of a tenth of `chi - chi_c` at the first point,
|
|
874
|
+
the error bars of `chi_c`, `beta` and `A` with `sigma_chi` match the
|
|
875
|
+
scatter of 300 seeded fits within 12 %, while without it `sigma_beta`
|
|
876
|
+
is more than 15 % too small. `sigma_chi = 0` gives exactly the plain
|
|
877
|
+
fit. A fit refuses data generated with `beta` = 0.02, 0.04 and 25.
|
|
878
|
+
- Refitting data with all couplings scaled by 1.07 scales `chi_c` by
|
|
879
|
+
1.07 to 1e-9 and leaves `beta` and `A` unchanged to 1e-7; scaling `R`
|
|
880
|
+
scales only `A`. `with_calibration` adds in quadrature to 1e-12.
|
|
881
|
+
|
|
723
882
|
**The exponent rule** (25 digits, Gaussian line, `Omega` down to 1e-6)
|
|
724
883
|
|
|
725
884
|
- `beta = 1/(s-1)` or 1/2 for the kernel family with `s` = 1.5, 1.8,
|
|
@@ -778,11 +937,45 @@ forms evaluated separately from the package's integrals)
|
|
|
778
937
|
within 5e-3 for couplings `r` = 1.2, 2 and 3 times the threshold,
|
|
779
938
|
and stays below 0.05 at 0.6 times the threshold.
|
|
780
939
|
|
|
781
|
-
Not covered by tests: `
|
|
782
|
-
`valid_window`.
|
|
940
|
+
Not covered by tests: `physicality` and `valid_window`.
|
|
783
941
|
|
|
784
942
|
## Corrections in earlier versions
|
|
785
943
|
|
|
944
|
+
**1.3.0 fixed five silent errors.** Numbers are at mpmath's default 15
|
|
945
|
+
digits unless stated.
|
|
946
|
+
|
|
947
|
+
- `Kernel.mass()` integrated a slow tail directly out to infinity. For
|
|
948
|
+
`power_tail(1.1)` the mass was 20.0312 instead of 20.2745 (1.2 % low;
|
|
949
|
+
3.7e-4 at 30 digits), so the threshold on a Lorentzian line of FWHM 1
|
|
950
|
+
was 0.0784174 instead of 0.0774765, and did not match the branch's own
|
|
951
|
+
`eps`. `second_moment()` had the same problem just above `s = 3`
|
|
952
|
+
(19.7910 instead of 20.0343 for `s = 3.1`). The tail is now mapped
|
|
953
|
+
onto a finite interval, as `G(Omega)` already was, and both match
|
|
954
|
+
their closed forms to the working precision.
|
|
955
|
+
- `tail_integral` integrated a singularity `delta^(2-s)` at the center
|
|
956
|
+
directly. On a Lorentzian line of FWHM 1, `I_s` was 47.063 instead
|
|
957
|
+
of 47.715 at `s = 2.9` and 86.97 instead of 98.49 at `s = 2.95`. A
|
|
958
|
+
change of variables now removes the singularity.
|
|
959
|
+
- Through these two, `amplitude_general` was wrong at the edges of
|
|
960
|
+
`1 < s < 3`, where the power `1/(s-1)` amplifies errors: on a
|
|
961
|
+
Gaussian line 8.4219 instead of 9.6179 for `s = 1.1`, and 0.45574
|
|
962
|
+
instead of 0.45258 for `s = 2.9`. Its default tail amplitude was also
|
|
963
|
+
used without a check: for the conservative kernel averaged over
|
|
964
|
+
coupling strengths (`gamma = 3.8`) it was 6.2 % low, and the
|
|
965
|
+
amplitude 8.3 % high. It now refuses such a kernel unless `C` is
|
|
966
|
+
given.
|
|
967
|
+
- `fit_branch` returned the limit of its search as the exponent when
|
|
968
|
+
the best fit lay beyond it: for `R = 0.8 eps^0.04` it reported
|
|
969
|
+
`beta = 0.0500 +- 0.0040`, and for `eps^25`, `beta = 20 +- 1.5`. It
|
|
970
|
+
now refuses.
|
|
971
|
+
- `class_exact` skipped a time earlier than the one before it and
|
|
972
|
+
returned the later state: for times `[1.0, 0.2]` (the system of
|
|
973
|
+
example 9) both entries gave `R = 0.677579`; the right value at
|
|
974
|
+
`t = 0.2` is 0.984316. It now accepts times in any order.
|
|
975
|
+
|
|
976
|
+
All earlier tests pass unchanged, and examples 1 to 9 print the same
|
|
977
|
+
as with 1.2.0.
|
|
978
|
+
|
|
786
979
|
**1.2.0 fixed four silent inaccuracies.** Numbers below are at
|
|
787
980
|
mpmath's default 15 digits unless stated.
|
|
788
981
|
|
|
@@ -868,10 +1061,17 @@ CI did not run Python 3.10. The full history is in
|
|
|
868
1061
|
It needs a differentiable line. It costs `n` plus about 40
|
|
869
1062
|
high-precision integrals (about 17 s at the default `n = 400` on the
|
|
870
1063
|
two-peaked line).
|
|
871
|
-
- `
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
1064
|
+
- `fit_branch` propagates coupling errors `sigma_chi` to first order.
|
|
1065
|
+
The tests check this at a tenth of `chi - chi_c`, and hand checks
|
|
1066
|
+
with 1000 seeded fits held to within 6 % up to three tenths. It is
|
|
1067
|
+
refused above a quarter.
|
|
1068
|
+
- `with_calibration` treats calibration as one scale factor for all
|
|
1069
|
+
couplings and one for all `R`. An offset (a zero error) is not a
|
|
1070
|
+
scale: it changes `eps` and so the exponent, and is not covered.
|
|
1071
|
+
- The default tail amplitude of `amplitude_general` is read off the
|
|
1072
|
+
kernel at `|u| = 10^6`; for `power_tail(s)` it is low by a relative
|
|
1073
|
+
`10^(-6 s)`, which the power `1/(s-1)` multiplies (2.5e-6 in `A` for
|
|
1074
|
+
`s = 1.1`). Pass `C` for more digits.
|
|
875
1075
|
- `build_system`'s docstring refers to a convergence check in
|
|
876
1076
|
`scripts/vlasov_check.py`; that script belongs to the research
|
|
877
1077
|
repository and is not part of this package.
|
|
@@ -887,8 +1087,9 @@ whose scripts, archived run records and figures remain with the
|
|
|
887
1087
|
study. The core modules were carried over unchanged in v1.1.0 (1.1.1
|
|
888
1088
|
changes only `c_coefficient`; 1.2.0 changes how `G`, `eps` and the
|
|
889
1089
|
fold are computed, and adds `amplitude_curvature` and
|
|
890
|
-
`Kernel.second_moment
|
|
891
|
-
|
|
1090
|
+
`Kernel.second_moment`; 1.3.0 changes how the kernel mass, the second
|
|
1091
|
+
moment and `tail_integral` are integrated, and how `class_exact` steps
|
|
1092
|
+
through time); the `measured` module and the packaging are new here. Copyright as in [NOTICE](NOTICE).
|
|
892
1093
|
|
|
893
1094
|
## Citing, support and license
|
|
894
1095
|
|