def test_estimate_rank(): """Test rank estimation """ data = np.eye(10) assert_array_equal(estimate_rank(data, return_singular=True)[1], np.ones(10)) data[0, 0] = 0 assert_equal(estimate_rank(data), 9)
def test_estimate_rank(): """Test rank estimation.""" data = np.eye(10) assert_array_equal( estimate_rank(data, return_singular=True)[1], np.ones(10)) data[0, 0] = 0 assert_equal(estimate_rank(data), 9) pytest.raises(ValueError, estimate_rank, data, 'foo')
def test_estimate_rank(): """Test rank estimation.""" data = np.eye(10) assert_array_equal(estimate_rank(data, return_singular=True)[1], np.ones(10)) data[0, 0] = 0 assert_equal(estimate_rank(data), 9) assert_raises(ValueError, estimate_rank, data, 'foo')
def _reg_pinv(x, reg): """Compute a regularized pseudoinverse of a square array.""" if reg == 0: covrank = estimate_rank(x, tol='auto', norm=False, return_singular=False) if covrank < x.shape[0]: warn('Covariance matrix is rank-deficient, but no regularization ' 'is done.') # This adds it to the diagonal without using np.eye d = reg * np.trace(x) / len(x) x.flat[::x.shape[0] + 1] += d return linalg.pinv(x), d
def test_estimate_rank(): """Test rank estimation """ data = np.eye(10) data[0, 0] = 0 assert_equal(estimate_rank(data), 9)
def make_lcmv(info, forward, data_cov, reg=0.05, noise_cov=None, label=None, pick_ori=None, rank=None, weight_norm='unit-noise-gain', reduce_rank=False, verbose=None): """Compute LCMV spatial filter. Parameters ---------- info : dict The measurement info to specify the channels to include. Bad channels in info['bads'] are not used. forward : dict Forward operator. data_cov : Covariance The data covariance. reg : float The regularization for the whitened data covariance. noise_cov : Covariance The noise covariance. If provided, whitening will be done. Providing a noise covariance is mandatory if you mix sensor types, e.g. gradiometers with magnetometers or EEG with MEG. label : Label Restricts the LCMV solution to a given label. pick_ori : None | 'normal' | 'max-power' If 'normal', rather than pooling the orientations by taking the norm, only the radial component is kept. If 'max-power', the source orientation that maximizes output source power is chosen. If None, the solution depends on the forward model: if the orientation is fixed, a scalar beamformer is computed. If the forward model has free orientation, a vector beamformer is computed, combining the output for all source orientations. rank : None | int | dict Specified rank of the noise covariance matrix. If None, the rank is detected automatically. If int, the rank is specified for the MEG channels. A dictionary with entries 'eeg' and/or 'meg' can be used to specify the rank for each modality. weight_norm : 'unit-noise-gain' | 'nai' | None If 'unit-noise-gain', the unit-noise gain minimum variance beamformer will be computed (Borgiotti-Kaplan beamformer) [2]_, if 'nai', the Neural Activity Index [1]_ will be computed, if None, the unit-gain LCMV beamformer [2]_ will be computed. reduce_rank : bool If True, the rank of the leadfield will be reduced by 1 for each spatial location. Setting reduce_rank to True is typically necessary if you use a single sphere model for MEG. verbose : bool, str, int, or None If not None, override default verbose level (see :func:`mne.verbose` and :ref:`Logging documentation <tut_logging>` for more). Returns ------- filters | dict Beamformer weights. Notes ----- The original reference is [1]_. References ---------- .. [1] Van Veen et al. Localization of brain electrical activity via linearly constrained minimum variance spatial filtering. Biomedical Engineering (1997) vol. 44 (9) pp. 867--880 .. [2] Sekihara & Nagarajan. Adaptive spatial filters for electromagnetic brain imaging (2008) Springer Science & Business Media """ picks = _setup_picks(info, forward, data_cov, noise_cov) is_free_ori, ch_names, proj, vertno, G = \ _prepare_beamformer_input(info, forward, label, picks, pick_ori) data_cov = pick_channels_cov(data_cov, include=ch_names) Cm = data_cov['data'] # check number of sensor types present in the data # This line takes ~23 ms on kernprof # _check_one_ch_type(info, picks, noise_cov) # apply SSPs is_ssp = False if info['projs']: Cm = np.dot(proj, np.dot(Cm, proj.T)) is_ssp = True if noise_cov is not None: # Handle whitening + data covariance whitener, _ = compute_whitener(noise_cov, info, picks, rank=rank) # whiten the leadfield G = np.dot(whitener, G) # whiten data covariance Cm = np.dot(whitener, np.dot(Cm, whitener.T)) else: whitener = None # Tikhonov regularization using reg parameter d to control for # trade-off between spatial resolution and noise sensitivity Cm_inv, d = _reg_pinv(Cm.copy(), reg) if weight_norm is not None: # estimate noise level based on covariance matrix, taking the # smallest eigenvalue that is not zero noise, _ = linalg.eigh(Cm) if rank is not None: rank_Cm = rank else: rank_Cm = estimate_rank(Cm, tol='auto', norm=False, return_singular=False) noise = noise[len(noise) - rank_Cm] # use either noise floor or regularization parameter d noise = max(noise, d) # Compute square of Cm_inv used for weight normalization Cm_inv_sq = np.dot(Cm_inv, Cm_inv) del Cm # leadfield rank and optional rank reduction if reduce_rank: if not pick_ori == 'max-power': raise NotImplementedError('The computation of spatial filters ' 'with rank reduction using reduce_rank ' 'parameter is only implemented with ' 'pick_ori=="max-power".') if not isinstance(reduce_rank, bool): raise ValueError('reduce_rank has to be True or False ' ' (got %s).' % reduce_rank) # Compute spatial filters W = np.dot(G.T, Cm_inv) n_orient = 3 if is_free_ori else 1 n_sources = G.shape[1] // n_orient TMP = np.dot(G.T, Cm_inv_sq) G = np.asfortranarray(G) max_ori = np.empty(n_orient * n_sources, order='F') pwr = np.empty(n_sources, order='F') tmp_prod = _beam_loop(n_sources, W, G, n_orient, TMP) max_ori = stacked_power_iteration(tmp_prod) W = multiply_by_orientations_rowwise(W, max_ori) G_or = multiply_by_orientations_columnwise(G, max_ori) TMP_or = multiply_by_orientations_rowwise(TMP, max_ori) pwr = np.array([TMP_or[k, :] @ G_or[:, k] for k in range(n_sources)]) denom = np.sqrt(pwr) W /= np.expand_dims(denom, axis=1) is_free_ori = False filters = dict(weights=W, data_cov=data_cov, noise_cov=noise_cov, whitener=whitener, weight_norm=weight_norm, pick_ori=pick_ori, ch_names=ch_names, proj=proj, is_ssp=is_ssp, vertices=vertno, is_free_ori=is_free_ori, nsource=forward['nsource'], src=deepcopy(forward['src'])) return filters