en 'exact' and 'asymptotic' to
      achieve reasonably accurate results in reasonable time (default)
    * 'asymptotic': compares the standardized test statistic against
      the normal distribution
    * 'exact': computes the exact *p*-value by comparing the observed
      :math:`L` statistic against those realized by all possible
      permutations of ranks (under the null hypothesis that each
      permutation is equally likely)

Returns
-------
res : PageTrendTestResult
    An object containing attributes:

    statistic : float
        Page's :math:`L` test statistic.
    pvalue : float
        The associated *p*-value
    method : {'asymptotic', 'exact'}
        The method used to compute the *p*-value

See Also
--------
rankdata, friedmanchisquare, spearmanr

Notes
-----
As noted in [1]_, "the :math:`n` 'treatments' could just as well represent
:math:`n` objects or events or performances or persons or trials ranked."
Similarly, the :math:`m` 'subjects' could equally stand for :math:`m`
"groupings by ability or some other control variable, or judges doing
the ranking, or random replications of some other sort."

The procedure for calculating the :math:`L` statistic, adapted from
[1]_, is:

1. "Predetermine with careful logic the appropriate hypotheses
   concerning the predicted ordering of the experimental results.
   If no reasonable basis for ordering any treatments is known, the
   :math:`L` test is not appropriate."
2. "As in other experiments, determine at what level of confidence
   you will reject the null hypothesis that there is no agreement of
   experimental results with the monotonic hypothesis."
3. "Cast the experimental material into a two-way table of :math:`n`
   columns (treatments, objects ranked, conditions) and :math:`m`
   rows (subjects, replication groups, levels of control variables)."
4. "When experimental observations are recorded, rank them across each
   row", e.g. ``ranks = scipy.stats.rankdata(data, axis=1)``.
5. "Add the ranks in each column", e.g.
   ``colsums = np.sum(ranks, axis=0)``.
6. "Multiply each sum of ranks by the predicted rank for that same
   column", e.g. ``products = predicted_ranks * colsums``.
7. "Sum all such products", e.g. ``L = products.sum()``.

[1]_ continues by suggesting use of the standardized statistic

.. math::

    \chi_L^2 = \frac{\left[12L-3mn(n+1)^2\right]^2}{mn^2(n^2-1)(n+1)}

"which is distributed approximately as chi-square with 1 degree of
freedom. The ordinary use of :math:`\chi^2` tables would be
equivalent to a two-sided test of agreement. If a one-sided test
is desired, *as will almost always be the case*, the probability
discovered in the chi-square table should be *halved*."

However, this standardized statistic does not distinguish between the
observed values being well correlated with the predicted ranks and being
_anti_-correlated with the predicted ranks. Instead, we follow [2]_
and calculate the standardized statistic

.. math::

    \Lambda = \frac{L - E_0}{\sqrt{V_0}},

where :math:`E_0 = \frac{1}{4} mn(n+1)^2` and
:math:`V_0 = \frac{1}{144} mn^2(n+1)(n^2-1)`, "which is asymptotically
normal under the null hypothesis".

The *p*-value for ``method='exact'`` is generated by comparing the observed
value of :math:`L` against the :math:`L` values generated for all
:math:`(n!)^m` possible permutations of ranks. The calculation is performed
using the recursive method of [5].

The *p*-values are not adjusted for the possibility of ties. When
ties are present, the reported  ``'exact'`` *p*-values may be somewhat
larger (i.e. more conservative) than the true *p*-value [2]_. The
``'asymptotic'``` *p*-values, however, tend to be smaller (i.e. less
conservative) than the ``'exact'`` *p*-values.

References
----------
.. [1] Ellis Batten Page, "Ordered hypotheses for multiple treatments:
   a significant test for linear ranks", *Journal of the American
   Statistical Association* 58(301), p. 216--230, 1963.

.. [2] Markus Neuhauser, *Nonparametric Statistical Test: A computational
   approach*, CRC Press, p. 150--152, 2012.

.. [3] Statext LLC, "Page's L Trend Test - Easy Statistics", *Statext -
   Statistics Study*, https://www.statext.com/practice/PageTrendTest03.php,
   Accessed July 12, 2020.

.. [4] "Page's Trend Test", *Wikipedia*, WikimediaFoundation,
   https://en.wikipedia.org/wiki/Page%27s_trend_test,
   Accessed July 12, 2020.

.. [5] Robert E. Odeh, "The exact distribution of Page's L-statistic in
   the two-way layout", *Communications in Statistics - Simulation and
   Computation*,  6(1), p. 49--61, 1977.

Examples
--------
We use the example from [3]_: 10 students are asked to rate three
teaching methods - tutorial, lecture, and seminar - on a scale of 1-5,
with 1 being the lowest and 5 being the highest. We have decided that
a confidence level of 99% is required to reject the null hypothesis in
favor of our alternative: that the seminar will have the highest ratings
and the tutorial will have the lowest. Initially, the data have been
tabulated with each row representing an individual student's ratings of
the three methods in the following order: tutorial, lecture, seminar.

>>> table = [[3, 4, 3],
...          [2, 2, 4],
...          [3, 3, 5],
...          [1, 3, 2],
...          [2, 3, 2],
...          [2, 4, 5],
...          [1, 2, 4],
...          [3, 4, 4],
...          [2, 4, 5],
...          [1, 3, 4]]

Because the tutorial is hypothesized to have the lowest ratings, the
column corresponding with tutorial rankings should be first; the seminar
is hypothesized to have the highest ratings, so its column should be last.
Since the columns are already arranged in this order of increasing
predicted mean, we can pass the table directly into `page_trend_test`.

>>> from scipy.stats import page_trend_test
>>> res = page_trend_test(table)
>>> res
PageTrendTestResult(statistic=133.5, pvalue=0.0018191161948127822,
                    method='exact')

This *p*-value indicates that there is a 0.1819% chance that
the :math:`L` statistic would reach such an extreme value under the null
hypothesis. Because 0.1819% is less than 1%, we have evidence to reject
the null hypothesis in favor of our alternative at a 99% confidence level.

The value of the :math:`L` statistic is 133.5. To check this manually,
we rank the data such that high scores correspond with high ranks, settling
ties with an average rank:

>>> from scipy.stats import rankdata
>>> ranks = rankdata(table, axis=1)
>>> ranks
array([[1.5, 3. , 1.5],
       [1.5, 1.5, 3. ],
       [1.5, 1.5, 3. ],
       [1. , 3. , 2. ],
       [1.5, 3. , 1.5],
       [1. , 2. , 3. ],
       [1. , 2. , 3. ],
       [1. , 2.5, 2.5],
       [1. , 2. , 3. ],
       [1. , 2. , 3. ]])

We add the ranks within each column, multiply the sums by the
predicted ranks, and sum the products.

>>> import numpy as np
>>> m, n = ranks.shape
>>> predicted_ranks = np.arange(1, n+1)
>>> L = (predicted_ranks * np.sum(ranks, axis=0)).sum()
>>> res.statistic == L
True

As presented in [3]_, the asymptotic approximation of the *p*-value is the
survival function of the normal distribution evaluated at the standardized
test statistic:

>>> from scipy.stats import norm
>>> E0 = (m*n*(n+1)**2)/4
>>> V0 = (m*n**2*(n+1)*(n**2-1))/144
>>> Lambda = (L-E0)/np.sqrt(V0)
>>> p = norm.sf(Lambda)
>>> p
0.0012693433690751756

This does not precisely match the *p*-value reported by `page_trend_test`
above. The asymptotic distribution is not very accurate, nor conservative,
for :math:`m \leq 12` and :math:`n \leq 8`, so `page_trend_test` chose to
use ``method='exact'`` based on the dimensions of the table and the
recommendations in Page's original paper [1]_. To override
`page_trend_test`'s choice, provide the `method` argument.

>>> res = page_trend_test(table, method="asymptotic")
>>> res
PageTrendTestResult(statistic=133.5, pvalue=0.0012693433690751756,
                    method='asymptotic')

If the data are already ranked, we can pass in the ``ranks`` instead of
the ``table`` to save computation time.

>>> res = page_trend_test(ranks,             # ranks of data
...                       ranked=True,       # data is already ranked
...                       )
>>> res
PageTrendTestResult(statistic=133.5, pvalue=0.0018191161948127822,
                    method='exact')

Suppose the raw data had been tabulated in an order different from the
order of predicted means, say lecture, seminar, tutorial.

>>> table = np.asarray(table)[:, [1, 2, 0]]

Since the arrangement of this table is not consistent with the assumed
ordering, we can either rearrange the table or provide the
`predicted_ranks`. Remembering that the lecture is predicted
to have the middle rank, the seminar the highest, and tutorial the lowest,
we pass:

>>> res = page_trend_test(table,             # data as originally tabulated
...                       predicted_ranks=[2, 3, 1],  # our predicted order
...                       )
>>> res
PageTrendTestResult(statistic=133.5, pvalue=0.0018191161948127822,
                    method='exact')

N)