Skip to content

Commit 55fca04

Browse files
committed
MAINT: stats.dunnett: transition to rng (SPEC 7)
1 parent f51a5df commit 55fca04

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

scipy/stats/_multicomp.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from scipy.stats._common import ConfidenceInterval
1212
from scipy.stats._qmc import check_random_state
1313
from scipy.stats._stats_py import _var
14+
from scipy._lib._util import _transition_to_rng
15+
1416

1517
if TYPE_CHECKING:
1618
import numpy.typing as npt
@@ -180,11 +182,12 @@ def confidence_interval(
180182
return self._ci
181183

182184

185+
@_transition_to_rng('random_state')
183186
def dunnett(
184187
*samples: npt.ArrayLike, # noqa: D417
185188
control: npt.ArrayLike,
186189
alternative: Literal['two-sided', 'less', 'greater'] = "two-sided",
187-
random_state: SeedType = None
190+
rng: SeedType = None
188191
) -> DunnettResult:
189192
"""Dunnett's test: multiple comparisons of means against a control group.
190193
@@ -211,14 +214,20 @@ def dunnett(
211214
* 'greater': the means of the distributions underlying the
212215
samples are greater than the mean of the distribution underlying
213216
the control.
214-
random_state : {None, int, `numpy.random.Generator`}, optional
215-
If `random_state` is an int or None, a new `numpy.random.Generator` is
216-
created using ``np.random.default_rng(random_state)``.
217-
If `random_state` is already a ``Generator`` instance, then the
218-
provided instance is used.
217+
rng : `numpy.random.Generator`, optional
218+
Pseudorandom number generator state. When `rng` is None, a new
219+
`numpy.random.Generator` is created using entropy from the
220+
operating system. Types other than `numpy.random.Generator` are
221+
passed to `numpy.random.default_rng` to instantiate a ``Generator``.
222+
223+
.. versionchanged:: 1.15.0
219224
220-
The random number generator is used to control the randomized
221-
Quasi-Monte Carlo integration of the multivariate-t distribution.
225+
As part of the `SPEC-007 <https://scientific-python.org/specs/spec-0007/>`_
226+
transition from use of `numpy.random.RandomState` to
227+
`numpy.random.Generator`, this keyword was changed from `random_state` to `rng`.
228+
For an interim period, both keywords will continue to work, although only one
229+
may be specified at a time. After the interim period, function calls using the
230+
`random_state` keyword will emit warnings.
222231
223232
Returns
224233
-------
@@ -311,7 +320,7 @@ def dunnett(
311320
"""
312321
samples_, control_, rng = _iv_dunnett(
313322
samples=samples, control=control,
314-
alternative=alternative, random_state=random_state
323+
alternative=alternative, rng=rng
315324
)
316325

317326
rho, df, n_group, n_samples, n_control = _params_dunnett(
@@ -342,10 +351,10 @@ def _iv_dunnett(
342351
samples: Sequence[npt.ArrayLike],
343352
control: npt.ArrayLike,
344353
alternative: Literal['two-sided', 'less', 'greater'],
345-
random_state: SeedType
354+
rng: SeedType
346355
) -> tuple[list[np.ndarray], np.ndarray, SeedType]:
347356
"""Input validation for Dunnett's test."""
348-
rng = check_random_state(random_state)
357+
rng = check_random_state(rng)
349358

350359
if alternative not in {'two-sided', 'less', 'greater'}:
351360
raise ValueError(

scipy/stats/tests/test_multicomp.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ def test_critical_values(
220220
def test_basic(self, samples, control, pvalue, statistic):
221221
rng = np.random.default_rng(11681140010308601919115036826969764808)
222222

223-
res = stats.dunnett(*samples, control=control, random_state=rng)
223+
res = stats.dunnett(*samples, control=control, rng=rng)
224224

225225
assert isinstance(res, DunnettResult)
226226
assert_allclose(res.statistic, statistic, rtol=5e-5)
@@ -239,6 +239,7 @@ def test_ttest_ind(self, alternative):
239239
sample = rng.integers(-100, 100, size=(10,))
240240
control = rng.integers(-100, 100, size=(10,))
241241

242+
# preserve use of old random_state during SPEC 7 transition
242243
res = stats.dunnett(
243244
sample, control=control,
244245
alternative=alternative, random_state=rng
@@ -270,7 +271,7 @@ def test_alternatives(self, alternative, pvalue):
270271

271272
res = stats.dunnett(
272273
sample_less, sample_greater, control=control,
273-
alternative=alternative, random_state=rng
274+
alternative=alternative, rng=rng
274275
)
275276
assert_allclose(res.pvalue, pvalue, atol=1e-7)
276277

@@ -301,7 +302,7 @@ def test_against_R_multicomp_glht(self, case, alternative):
301302
p_ref = case['pvalues'][alternative.replace('-', '')]
302303

303304
res = stats.dunnett(*samples, control=control, alternative=alternative,
304-
random_state=rng)
305+
rng=rng)
305306
# atol can't be tighter because R reports some pvalues as "< 1e-4"
306307
assert_allclose(res.pvalue, p_ref, rtol=5e-3, atol=1e-4)
307308

@@ -328,7 +329,7 @@ def test_str(self, alternative):
328329

329330
res = stats.dunnett(
330331
*self.samples_3, control=self.control_3, alternative=alternative,
331-
random_state=rng
332+
rng=rng
332333
)
333334

334335
# check some str output
@@ -350,7 +351,7 @@ def test_warnings(self):
350351
rng = np.random.default_rng(189117774084579816190295271136455278291)
351352

352353
res = stats.dunnett(
353-
*self.samples_3, control=self.control_3, random_state=rng
354+
*self.samples_3, control=self.control_3, rng=rng
354355
)
355356
msg = r"Computation of the confidence interval did not converge"
356357
with pytest.warns(UserWarning, match=msg):
@@ -396,7 +397,7 @@ def test_shapes(self, n_samples):
396397
rng = np.random.default_rng(689448934110805334)
397398
samples = rng.normal(size=(n_samples, 10))
398399
control = rng.normal(size=10)
399-
res = stats.dunnett(*samples, control=control, random_state=rng)
400+
res = stats.dunnett(*samples, control=control, rng=rng)
400401
assert res.statistic.shape == (n_samples,)
401402
assert res.pvalue.shape == (n_samples,)
402403
ci = res.confidence_interval()

0 commit comments

Comments
 (0)