Skip to content

Commit 2e43b53

Browse files
authored
Merge pull request #19 from circstat/median
refactor: Median
2 parents 8f9313b + da56add commit 2e43b53

4 files changed

Lines changed: 566 additions & 114 deletions

File tree

docs/docs/feature-checklist.md

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
| **Measures of Central Tendency** | | | | | |
88
| Circular Mean | `circ_mean` | `mean(alpha)` | `circ_mean(alpha)` | `circ.mean` | `mean.circular` |
99
| Circular Mean CI | `circ_mean_ci` | `mean(alpha, ci=95)` | `circ_confmean` | - | `mle.vonmises.bootstrap.ci` |
10-
| Circular Median | `circ_median` | `median` | `circ_median` | - | `median.circular`/`medianHL.circular` |
10+
| Circular Median (Fisher/Mardia) | `circ_median` (method=`"deviation"`/`"count"`) [^median-grouped] | `median` | `circ_median` | - | `median.circular` |
11+
| Hodges-Lehmann Median | `circ_median` (method=`"HL1"`/`"HL2"`/`"HL3"`) | - | - | - | `medianHL.circular`[^medianHL-broken] |
1112
| Circular Median CI | `circ_median_ci` | - | - | - | - |
1213
| Circular Quantile | `circ_quantile` | - | - | - | `quantile.circular` |
1314
| **Measures of Spread & Dispersion** | | | | | |
@@ -17,12 +18,14 @@
1718
| Circular Variance | `circ_var` | `var` | `circ_var` | `circ.disp` | `var.circular` |
1819
| Circular Standard Deviation | `circ_std` | `std` | `circ_std` | - | `sd.circular` |
1920
| Circular Dispersion | `circ_dispersion` | - | - | - | - |
21+
| Circular Range | `circ_range` | - | - | `circ.range` | `range.circular` |
22+
| Concentration Parameter (κ) | `circ_kappa` | `kappa` | `circ_kappa` | `est.kappa` | `A1inv` |
2023
| **Higher-Order Statistics** | | | | | |
2124
| Circular Moment | `circ_moment` | `moment` | `circ_moment` | `tri.moment` | `trigonometric.moment` |
2225
| Circular Skewness | `circ_skewness` | `skewness` | `circ_skewness` | - | - |
2326
| Circular Kurtosis | `circ_kurtosis` | `kurtoisis` | `circ_kurtosis` | - | - |
2427
| **Distance & Pairwise Comparisons** | | | | | |
25-
| Mean deviation | `circ_mean_deviation` | - | - | - | `meandeviation` |
28+
| Mean deviation [^mean-dev] | `circ_mean_deviation` | - | - | - | `meandeviation` |
2629
| Circular Distance | `circ_dist` | `cdist` | `circ_dist` | - | - |
2730
| Pairwise Circular Distance | `circ_pairdist` | `pairwise_cdiff` | `circ_dist2` | - | `dist.circular` |
2831

@@ -67,19 +70,20 @@
6770

6871
| Feature | H0 | PyCircStat2 | PyCircStat | CircStat (MATLAB) | CircStats (R) | circular (R) |
6972
|---------------------|------------|--------------------|--------------|-------------------|---------------|--------------------|
70-
| Kuiper’s Test | $\rho = 0$ | `circ_kuiper_test` | `kupier` | `circ_kuipertest` | `kuiper` | `kuiper.test` |
73+
| Kuiper’s Test | $\rho = 0$ | `kuiper_test` | `kuiper` | `circ_kuipertest` | `kuiper` | `kuiper.test` |
7174
| Rao’s Spacing Test | $\rho = 0$ | `rao_spacing_test` | `raospacing` | `circ_raotest` | `rao.spacing` | `rao.spacing.test` |
7275
| Watson's Test | $\rho = 0$ | `watson_test` | - | - | `watson` | `watson.test` |
7376
| Circular Range Test | $\rho = 0$ | `circ_range_test` | - | - | `circ_range` | `range.circular` |
7477

7578

7679
### 3. Correlation & Regression
77-
| Feature | PyCircStat2 | PyCircStat | CircStat (MATLAB) | CircStats (R) | circular (R) |
78-
|-------------------------------|----------------|------------|-------------------|---------------|---------------------------|
79-
| Circular-Circular Correlation | `circ_corrcc` | `corrcc` | `circ_corrcc` | `circ.cor` | `cor.circular` |
80-
| Circular-Linear Correlation | `circ_corrcl` | `corrcl` | `circ_corrcl` | - | - |
81-
| Circular-Circular Regression | `CCRegression` | - | - | `circ.reg` | `lm.circular(type="c-c")` |
82-
| Circular-Linear Regression | `CLRegression` | - | - | - | `lm.circular(type="c-l")` |
80+
| Feature | PyCircStat2 | PyCircStat | CircStat (MATLAB) | CircStats (R) | circular (R) |
81+
|-----------------------------------------------|----------------|------------|-------------------|---------------|---------------------------|
82+
| Circular-Circular Correlation | `circ_corrcc` | `corrcc` | `circ_corrcc` | `circ.cor` | `cor.circular` |
83+
| Circular-Linear Correlation | `circ_corrcl` | `corrcl` | `circ_corrcl` | - | - |
84+
| Circular-Circular Regression | `CCRegression` | - | - | `circ.reg` | `lm.circular(type="c-c")` |
85+
| Circular-Linear Regression [^cl-resp] | `CLRegression` | - | - | - | `lm.circular(type="c-l")` |
86+
| Linear-Circular Regression (harmonic) [^lc-resp] | `LCRegression` | - | - | - | - |
8387

8488

8589

@@ -165,12 +169,26 @@ All circular distributions assume angles are on ``[0, 2π)``. Inputs are automat
165169
| | PPF | `wrapstable.ppf` | - | - | - | - |
166170
| | RVS | `wrapstable.rvs` | - | - | `rwrpstab` | - |
167171
| | Fit | `wrapstable.fit` | - | - | - | - |
168-
| Asymmetric Trangular | PDF | - | - | - | - | `dasytriangular` |
172+
| Asymmetric Triangular | PDF | - | - | - | - | `dasytriangular` |
169173
| Projected Normal | PDF | - | - | - | - | `dpnorm` |
170174
| | RVS | - | - | - | - | `rpnorm` |
171175

172176
[^uniform]: $\rho=0$ stands for uniform distributed.
173177
[^median]: $\theta$ stands for median.
174178
[^F]: $F$ stands for distributions.
175-
[^one-way]: Yet anothr one-way ANOVA.
179+
[^one-way]: Yet another one-way ANOVA.
176180
[^two-way]: Two-way ANOVA.
181+
[^median-grouped]: For grouped data (non-uniform `w`), `circ_median` uses the
182+
Mardia (1972) interpolation; the `method` argument is ignored on that path.
183+
[^medianHL-broken]: As of `circular` 0.5-2 (CRAN, 2025-09-24), `medianHL.circular`
184+
builds the pair-mean array but its C primitive calls the deviation median on
185+
the original `x` instead of on the pair-means, so HL1/HL2/HL3 all return the
186+
regular `median.circular` value. See Otieno (2002) §3.4 for the intended
187+
algorithm.
188+
[^mean-dev]: Different signatures: pycircstat2's `circ_mean_deviation(α, β)`
189+
evaluates Fisher (1993) eq. 2.32 — `d(β) = π − (1/n)Σ|π−|αᵢ−β||` — at every
190+
reference angle `β` (vector output). R's `meandeviation(x)` is the scalar
191+
`d(median(x))`. Same formula, different evaluation points.
192+
[^cl-resp]: Circular response, linear predictor.
193+
[^lc-resp]: Linear response, circular predictor (harmonic regression à la
194+
Pewsey et al. 2014, §8.4).

examples/B1-Fisher-1993.ipynb

Lines changed: 21 additions & 21 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)