In my book Wobbly Universe I have a number of graphics showing Harmonics Theory predicted common cycles with comparison to various different observed cycles for different subjects. At that time I had the means to plot them together. Now I have (with Claude AI) devised a solid statistical test for whether some cycles found in a particular series (or set of series) are supporting Harmonics Theory or are likely to occur by chance alone. This article is about how that test has been designed to be statistically solid and an example of it applied to my recent analysis of Earth's Magnetic Reversal polarity cycles.
HT cycles period testing
Method for testing whether a set of detected cycle periods matches Harmonics Theory (HT) predicted periods better than chance.
Version 1.0 — 13 October 2026. Worked out by Ray Tomes with Claude. Reference implementation: ht_period_test.py. Harmonics input: strong-harmonics.csv (columns H, C(H), Cest(H), Str(H), years).
1. Purpose
A cycles analysis of some data (spectrum, CATS, etc.) produces a list of periods. HT predicts a set of periods, each with a relative strength Str(H). This method answers one question:
Do the detected periods lie closer to strong HT-predicted periods than randomly placed periods would?
It rewards multiple precise hits. A miss costs almost nothing; a near-exact match earns a very large score. The result is a p-value from a Monte Carlo test against random periods.
This replaces the earlier "mean log-distance to nearest strong line" test. That test gave every period equal weight, so many mediocre matches could look as good as a few exact ones, and it did not use the accuracy of the data.
2. Inputs
|
Input |
Default |
Notes |
|---|---|---|
|
Detected periods |
(user list) |
Any unit. At least 2 different values (the range is built from their span). |
|
Strength limit |
0.9 |
Only HT lines with Str(H) at or above this are used. Fix it before looking at results. |
|
Relative accuracy, a |
0.0001 |
Expected error divided by the period, for the data being tested. Change it only according to how accurate the data are. |
|
HT predictions |
strong-harmonics.csv |
years column gives the predicted period; convert to the unit of the detected periods. |
|
Monte Carlo size |
10 batches × 100,000 trials |
Batches show whether p is stable. |
Choosing a
a is a property of the data, not a tuning knob. Use a small value when the periods are very accurate (0.0001 was used for the magnetic reversal periods), and a larger value (0.001, 0.01) for noisier estimates such as spectral peaks from short data. Never adjust a after seeing which value gives the lowest p.
3. Procedure
Step 1 — Strong lines. Take every HT line with Str(H) ≥ the strength limit. Convert years to the unit of the detected periods.
Step 2 — Range. With N detected periods, let
span = log10(P_max) - log10(P_min)
pad = span / N
range = 10^(log10(P_min) - pad) to 10^(log10(P_max) + pad)
The range is the periods found plus a margin of span/N each side (one average log-spacing of the found periods).
Step 3 — Score each period. For each detected period P, find the nearest strong line L (searching all strong lines, including any just outside the range, so edge periods are not penalised):
error = |P - L| / P
score = 1 / (error + a)
Step 4 — Fit statistic.
S = sum of score over all N periods
Larger S means a better fit.
Step 5 — Monte Carlo. Repeat many times: draw N random periods uniformly in log period across the range from Step 2, score them exactly as in Steps 3–4, and record the sum. Do this in several batches.
p = (number of random sets with S_random >= S_observed) / (number of random sets)
Report p for each batch and overall, plus the Monte Carlo mean and the 95th and 99th percentile of S for comparison.
4. Chart specification
-
x-axis: period, log scale, restricted to the Step 2 range, longest period on the left (descending).
-
One vertical line per strong HT prediction, from the bottom of the chart up to its Str(H). The period is written vertically above each line.
-
Detected periods are plotted as triangles about 30% of the way up the chart, or lower if needed so they sit below the top of the lowest HT line.
-
Title states the range, strength limit and a.
5. How the score behaves
score = 1/(error + a):
|
Relative error |
Score (a = 0.0001) |
|---|---|
|
0 (exact) |
10,000 (the cap, 1/a) |
|
0.01% |
5,000 |
|
0.1% |
about 909 |
|
1% |
about 99 |
|
3% |
about 33 |
-
Scores fall roughly as 1/error, so one exact hit is worth many 1% hits. This is what makes multiple hits dominate and misses nearly irrelevant.
-
a stops a single exact match from scoring infinity. The maximum per period is 1/a.
-
a does not, by itself, make a single lucky hit non-significant. In the worked example below, one near-exact hit (score 5,523) on its own gives p ≈ 0.017 against 6 random periods, and two such hits give p ≈ 0.003. The Monte Carlo test is what decides whether a hit is surprising; a sets how much credit a given precision earns, so it must match the real accuracy of the data. If a is set smaller than the data's true accuracy, small errors in the data are treated as real mismatches; if larger, genuine precision earns less credit.
6. Rules to keep the test honest
-
Fix everything before testing. The period list, strength limit, a, and the unit conversions must be decided first. Trying several strength limits or a values and reporting the best inflates significance. If sensitivity is shown, show all of it (Section 7).
-
Do not trim the list to the best matches. The list must come from the cycles analysis by a rule that does not look at the HT lines (for example all peaks above a significance level). Adding weak periods lowers the apparent significance slightly; removing them to improve p is selection.
-
Collapse clusters. If several detected periods are near-duplicates of the same cycle (within about 1–2%), count the cluster once (use its mean). Otherwise the test counts one cycle many times. (This lowered one earlier result from p = 0.0018 to p = 0.041.)
-
The range depends on the list. Adding or removing a period changes N and the span, so the range, the number of lines, and p all shift. State the range used.
-
Monte Carlo resolution. With 10 × 100,000 trials the smallest reportable p is about 1e-6. If no random set reaches S, report p < 1e-6 rather than 0.
-
Statistics are one-sided: p is the chance that random periods do at least as well.
-
Different tests are not comparable. p-values from this method cannot be compared with those from the earlier mean-closeness test.
7. Worked example — magnetic reversals, 1.11 Ma cycle paper
This paper is available on viXra at
Detected periods (Ma): 1.1101, 1.2286, 3.3335, 2.2683, 0.74026, 2.7629. Strength limit 0.9, a = 0.0001.
Range: 0.576 – 4.284 Ma (span 0.6535 in log10, pad 0.1089); 26 strong lines in range.
|
Period (Ma) |
Nearest line (Ma) |
Relative error |
Score |
|---|---|---|---|
|
0.74026 |
0.74020 |
0.008% |
5,523 |
|
1.1101 |
1.1103 |
0.018% |
3,569 |
|
3.3335 |
3.3309 |
0.078% |
1,136 |
|
1.2286 |
1.2213 |
0.59% |
166 |
|
2.2683 |
2.2206 |
2.1% |
47 |
|
2.7629 |
2.6647 |
3.6% |
28 |
-
Observed sum S = 10,471.
-
Random sets: mean S ≈ 897; 95th percentile ≈ 2,939; 99th ≈ 6,988.
-
p = 0.00069 (10 batches of 100,000: 0.00057 to 0.00079).
The result rests on the first three periods (about 10,230 of the 10,471). The last three are weak or no matches. A paper should say this.
Sensitivity (reported for transparency, not for choosing)
|
Variation |
p |
|---|---|
|
Drop 1.1101 |
0.0078 |
|
Drop 0.74026 |
0.016 |
|
Drop 3.3335 |
0.0017 |
|
Drop 1.2286 |
0.00051 |
|
Drop 2.2683 |
0.00043 |
|
Drop 2.7629 |
0.00042 |
|
Only 1.1101, 3.3335, 0.74026 |
0.00012 |
|
a = 0.00001 / 0.0001 / 0.001 / 0.01 |
0.0078 / 0.00065 / 0.00009 / 0.0014 |
|
Strength limit 0.85 / 0.9 / 0.95 |
0.0016 / 0.00065 / 0.00012 |
Removing any one period leaves p below 0.02. Note that the "only best three" row is a selected subset and should not be quoted as the result.
8. What to report in a paper
-
The detected periods and how they were obtained (data, method, any significance criterion).
-
Strength limit, a and the reason for it, the test range, number of strong lines in range.
-
Per-period nearest line, relative error and score.
-
Observed S, Monte Carlo mean and 95th/99th percentile, p per batch and overall, number of trials.
-
The fact that the test is dominated by the best few matches, if so.
-
Any sensitivity checks, shown in full.
9. Reference implementation
ht_period_test.py (Python 3, numpy; matplotlib for the chart).
python ht_period_test.py \
--periods 1.1101 1.2286 3.3335 2.2683 0.74026 2.7629 \
--period-unit Ma \
--harmonics strong-harmonics.csv \
--str-min 0.9 --a 0.0001 \
--batches 10 --trials 100000 \
--label "Magnetic reversal cycles" \
--out chart.png
--period-unit accepts yr, kyr, Ma, Ga, months, days. The script prints the range, the per-period table, S, the Monte Carlo summary and p, and writes the chart described in Section 4.
10. Possible future extensions
-
Build this into the interactive chart tool (inputs: periods, strength limit, a).
-
Add automatic cluster collapsing with a stated tolerance.
-
Add a "run all with the same pre-registered settings" mode for comparing several datasets fairly.
