Skip to content

Correlation

circ_corrcc(a, b, method='fl', test=False, strict=True)

Angular-Angular / Spherical Correlation.

Three methods are available:

  • 'fl' (Fisher & Lee, 1983): T-linear association. The correlation coefficient
\[ r = \frac{\sum_{i=1}^{n-1}\sum_{j=i+1}^{n} \sin(a_{ij}) \sin(b_{ij})}{\sqrt{\sum_{i=1}^{n-1}\sum_{j=i+1}^{n} \sin^2(a_{ij}) \sum_{i=1}^{n-1}\sum_{j=i+1}^{n} \sin^2(b_{ij})}} \]
  • 'js' (Jammalamadaka & SenGupta, 2001)
\[ r = \frac{\sum \sin(a_i - \bar{a}) \sin(b_i - \bar{b})}{\sqrt{\sum \sin^2(a_i - \bar{a}) \sum \sin^2(b_i - \bar{b})}} \]
  • 'nonparametric'
\[ r = \frac{\sum \cos(C \cdot \text{rankdiff})^2 + \sum \sin(C \cdot \text{rankdiff})^2}{n^2} - \frac{\sum \cos(C \cdot \text{ranksum})^2 + \sum \sin(C \cdot \text{ranksum})^2}{n^2} \]

, where \(C = 2\pi / n\) and \(\text{rankdiff} = \text{rank}_a - \text{rank}_b\) and \(\text{ranksum} = \text{rank}_a + \text{rank}_b\).

Parameters:

Name Type Description Default
a Union[Type[Circular], ndarray]

Angles in radian

required
b Union[Type[Circular], ndarray]

Angles in radian

required
method str
  • 'fl' (Fisher & Lee, 1983): T-linear association. The correlation coefficient is computed as:
  • 'js' (Jammalamadaka & SenGupta, 2001)
  • 'nonparametric'
'fl'
test bool

Return significant test results.

False
strict bool

Strict mode. If True, raise an error when mean direction is not significant. Only for method="js" (Jammalamadaka & SenGupta, 2001).

True

Returns:

Name Type Description
r float

Correlation coefficient.

reject bool

Return significant test if test is set to True.

Source code in pycircstat2/correlation.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
def circ_corrcc(
    a: Union[Type[Circular], np.ndarray],
    b: Union[Type[Circular], np.ndarray],
    method: str = "fl",
    test: bool = False,
    strict: bool = True,
) -> Union[float, CorrelationResult]:
    r"""
    Angular-Angular / Spherical Correlation.

    Three methods are available:

    - 'fl' (Fisher & Lee, 1983): T-linear association. The correlation coefficient

    $$
    r = \frac{\sum_{i=1}^{n-1}\sum_{j=i+1}^{n} \sin(a_{ij}) \sin(b_{ij})}{\sqrt{\sum_{i=1}^{n-1}\sum_{j=i+1}^{n} \sin^2(a_{ij}) \sum_{i=1}^{n-1}\sum_{j=i+1}^{n} \sin^2(b_{ij})}}
    $$

    - 'js' (Jammalamadaka & SenGupta, 2001)

    $$
    r = \frac{\sum \sin(a_i - \bar{a}) \sin(b_i - \bar{b})}{\sqrt{\sum \sin^2(a_i - \bar{a}) \sum \sin^2(b_i - \bar{b})}}
    $$

    - 'nonparametric'

    $$
    r = \frac{\sum \cos(C \cdot \text{rankdiff})^2 + \sum \sin(C \cdot \text{rankdiff})^2}{n^2} - \frac{\sum \cos(C \cdot \text{ranksum})^2 + \sum \sin(C \cdot \text{ranksum})^2}{n^2}
    $$

    , where $C = 2\pi / n$ and $\text{rankdiff} = \text{rank}_a - \text{rank}_b$ and $\text{ranksum} = \text{rank}_a + \text{rank}_b$.


    Parameters
    ----------
    a: Circular or np.ndarray
        Angles in radian
    b: Circular or np.ndarray
        Angles in radian
    method: str
        - 'fl' (Fisher & Lee, 1983): T-linear association. The correlation coefficient
          is computed as:
        - 'js' (Jammalamadaka & SenGupta, 2001)
        - 'nonparametric'
    test: bool
        Return significant test results.
    strict: bool
        Strict mode. If True, raise an error when mean direction is
        not significant. Only for method="js" (Jammalamadaka & SenGupta, 2001).

    Returns
    -------
    r: float
        Correlation coefficient.
    reject: bool
        Return significant test if `test` is set to True.
    """

    if method == "fl":  # Fisher & Lee (1983)
        _corr = _circ_corrcc_fl
    elif method == "js":  # Jammalamadaka & SenGupta (2001)
        _corr = _circ_corrcc_js
    elif method == "nonparametric":
        _corr = _circ_corrcc_np
    else:
        raise ValueError("Invalid method. Choose from 'fl', 'js', 'nonparametric'.")

    result = _corr(a, b, test, strict)

    if test:
        return result
    else:
        return result.r

circ_corrcl(a, x)

Angular-Linear / Cylindrical Correlation based on Mardia (1972).

Also known as Linear-circular or C-linear association (Fisher, 1993).

\[ r = \sqrt{\frac{r_{xc}^2 + r_{xs}^2 - 2r_{xc}r_{xs}r_{cs}}{1 - r_{cs}^2}} \]

where \(r_{xc}\), \(r_{xs}\), and \(r_{cs}\) are the correlation coefficients between \(\cos(a)\) and \(x\), \(x\) and \(\sin(a)\), and \(\sin(a)\) and \(\cos(a)\), respectively.

Parameters:

Name Type Description Default
a Union[Type[Circular], ndarray]

Angles in radian

required
x ndarray

Linear variable

required

Returns:

Name Type Description
ral float

correlation coefficient.

pval float
Reference

P658-659, Section 27.15(b) of Example 27.21 (Zar, 2010).

Source code in pycircstat2/correlation.py
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
def circ_corrcl(
    a: Union[Type[Circular], np.ndarray],
    x: np.ndarray,
) -> CorrelationResult:
    r"""Angular-Linear / Cylindrical Correlation based on Mardia (1972).

    Also known as Linear-circular or C-linear association (Fisher, 1993).

    $$
    r = \sqrt{\frac{r_{xc}^2 + r_{xs}^2 - 2r_{xc}r_{xs}r_{cs}}{1 - r_{cs}^2}}
    $$

    where $r_{xc}$, $r_{xs}$, and $r_{cs}$ are the correlation coefficients between
    $\cos(a)$ and $x$, $x$ and $\sin(a)$, and $\sin(a)$ and $\cos(a)$, respectively.

    Parameters
    ----------
    a: Circular or np.ndarray
        Angles in radian
    x: np.ndarray
        Linear variable

    Returns
    -------
    ral: float
        correlation coefficient.
    pval: float

    Reference
    ----
    P658-659, Section 27.15(b) of Example 27.21 (Zar, 2010).
    """

    a_alpha = np.array(a.alpha) if isinstance(a, Circular) else a

    if len(a_alpha) != len(x):
        raise ValueError("`a` and `x` must be the same length.")

    n = len(a_alpha)

    rxc = np.corrcoef(np.cos(a), x)[0, 1]
    rxs = np.corrcoef(x, np.sin(a))[0, 1]
    rcs = np.corrcoef(np.sin(a), np.cos(a))[0, 1]

    num = rxc**2 + rxs**2 - 2 * rxc * rxs * rcs
    den = 1 - rcs**2
    r = np.sqrt(num / den)

    pval = 1 - chi2(df=2).cdf(n * r**2)

    return CorrelationResult(r=r, p_value=pval)