Coverage for nilearn/_utils/extmath.py: 16%
19 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-20 10:58 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-20 10:58 +0200
1"""Extended math utilities."""
3import numpy as np
5from nilearn._utils import logger
8def fast_abs_percentile(data, percentile=80):
9 """Implement a fast version of the percentile of the absolute value.
11 Parameters
12 ----------
13 data : ndarray, possibly masked array
14 The input data.
16 percentile : number between 0 and 100
17 The percentile that we are asking for.
19 Returns
20 -------
21 value : number
22 The score at percentile.
24 Notes
25 -----
26 This is a faster, and less accurate version of
27 scipy.stats.scoreatpercentile(np.abs(data), percentile)
29 """
30 if hasattr(data, "mask"):
31 # Catter for masked arrays
32 data = np.asarray(data[np.logical_not(data.mask)])
33 data = np.abs(data)
34 data = data.ravel()
35 index = int(data.size * 0.01 * percentile)
36 # Partial sort: faster than sort
37 data = np.partition(data, index)
38 return data[index]
41def is_spd(M, decimal=15, verbose=1):
42 """Assert that input matrix is symmetric positive definite.
44 M must be symmetric down to specified decimal places.
45 The check is performed by checking that all eigenvalues are positive.
47 Parameters
48 ----------
49 M : numpy.ndarray
50 Symmetric positive definite matrix.
52 decimal : int, default=15
53 Decimal.
55 %(verbose)s
57 Returns
58 -------
59 answer : boolean
60 True if matrix is symmetric positive definite, False otherwise.
62 """
63 if not np.allclose(M, M.T, atol=0, rtol=10**-decimal):
64 logger.log(f"matrix not symmetric to {decimal:d} decimals", verbose)
65 return False
67 eigvalsh = np.linalg.eigvalsh(M)
68 ispd = eigvalsh.min() > 0
70 if not ispd:
71 logger.log(
72 f"matrix has a negative eigenvalue: {eigvalsh.min():.3f}", verbose
73 )
75 return ispd