def test_covariances(estimator, rndstate):
    """Test covariance for multiple estimators"""
    n_matrices, n_channels, n_times = 2, 3, 100
    x = rndstate.randn(n_matrices, n_channels, n_times)

    if estimator is None:
        cov = covariances(x)
        assert cov.shape == (n_matrices, n_channels, n_channels)
    elif estimator == 'truc':
        with pytest.raises(ValueError):
            covariances(x, estimator=estimator)
    else:
        cov = covariances(x, estimator=estimator)
        assert cov.shape == (n_matrices, n_channels, n_channels)
Example #2
0
    def transform(self, X):
        """Estimate the hankel covariance matrices.

        Parameters
        ----------
        X : ndarray, shape (n_trials, n_channels, n_samples)
            ndarray of trials.

        Returns
        -------
        covmats : ndarray, shape (n_trials, n_channels, n_channels)
            ndarray of covariance matrices for each trials.
        """

        if isinstance(self.delays, int):
            delays = range(1, self.delays)
        else:
            delays = self.delays

        X2 = []

        for x in X:
            tmp = x
            for d in delays:
                tmp = numpy.r_[tmp, numpy.roll(x, d, axis=-1)]
            X2.append(tmp)
        X2 = numpy.array(X2)
        covmats = covariances(X2, estimator=self.estimator)
        return covmats
def test_covariances():
    """Test covariance for multiple estimator"""
    x = np.random.randn(2, 3, 100)
    cov = covariances(x)
    cov = covariances(x, estimator='oas')
    cov = covariances(x, estimator='lwf')
    cov = covariances(x, estimator='scm')
    cov = covariances(x, estimator='corr')
    cov = covariances(x, estimator='mcd')
    cov = covariances(x, estimator=np.cov)
    
    with pytest.raises(ValueError):
        covariances(x, estimator='truc')
Example #4
0
def find_soulmate_iter(population_signals, stranger_signals):
    dist_dict = {}

    stranger_covariance = covariances(X=stranger_signals)
    stranger_reference = mean_covariance(covmats=stranger_covariance,
                                         metric='riemann')

    for subject, subject_signal in population_signals.iteritems():
        subject_covariance = covariances(X=subject_signal)
        subject_reference = mean_covariance(covmats=subject_covariance,
                                            metric='riemann')

        dist_dict[subject] = distance(stranger_reference, subject_reference)

    sorted_dist_dict = sorted(dist_dict.items(), key=operator.itemgetter(1))

    return dict(sorted_dist_dict)
Example #5
0
def test_block_covariances(rndstate):
    """Test block covariance"""
    n_matrices, n_channels, n_times = 2, 12, 100
    x = rndstate.randn(n_matrices, n_channels, n_times)

    cov = block_covariances(x, [12], estimator='cov')
    assert_array_almost_equal(cov, covariances(x, estimator='cov'))

    cov = block_covariances(x, [6, 6], estimator='cov')
    cov2 = covariances(x, estimator='cov')
    covcomp = block_diag(*(cov2[0, :6, :6], cov2[0, 6:12, 6:12]))
    assert_array_almost_equal(cov[0], covcomp)

    cov = block_covariances(x, [3, 5, 4], estimator='cov')
    cov2 = covariances(x, estimator='cov')
    covcomp = block_diag(*(cov2[0, :3, :3], cov2[0, 3:8, 3:8], cov2[0, 8:12,
                                                                    8:12]))
    assert_array_almost_equal(cov[0], covcomp)
Example #6
0
    def transform(self, X):
        """Clean signal
        Parameters
        ----------
        X : ndarray, shape (n_trials, n_samples, n_channels)
            Data to clean, already filtered
        Returns
        -------
        Xclean : ndarray, shape (n_trials, n_samples, n_channels)
            Cleaned data
        """
        check_is_fitted(self, ['Ne_', 'mixing_', 'threshold_'])
        X = check_array(X, allow_nd=True)
        shapeX = X.shape

        if len(shapeX) == 3:
            Nt, Ns, Ne = shapeX
        else:
            raise ValueError(
                "X.shape should be (n_trials, n_samples, n_electrodes).")

        Xclean = np.zeros((Nt, Ns, Ne))

        assert Ne < Ns, "number of samples should be higher than number of electrodes, check than \n" \
                        + "X.shape is (n_trials,  n_samples, n_channels)."

        covmats = covariances(
            np.swapaxes(X, 1, 2),
            estimator=self.estimator)  # (n_trials, n_channels, n_times)

        # TODO: parallelizing the loop for efficiency
        for k in range(Nt):
            # TODO: HAVE BOTH euclidian PCA and Riemannian PCA (PGA) using pymanopt
            evals, evecs = eigh(covmats[k, :])  # compute PCA
            indx = np.argsort(evals)  # sort in ascending
            evecs = evecs[:, indx]

            keep = (evals[indx] < np.sum(self.threshold_.dot(evecs) ** 2, axis = 0)) | \
                   (np.arange(Ne) < (Ne * (1 - self.max_dimension)))

            keep = np.expand_dims(
                keep, 0)  # for element wise multiplication that follows

            spatialfilter = np.linalg.pinv(keep.transpose() *
                                           evecs.transpose().dot(self.mixing_))

            R = self.mixing_.dot(spatialfilter).dot(evecs.transpose())

            Xclean[k, :] = X[k, :].dot(R.transpose(
            ))  # suboptimal in term of memory but great for debug

        return Xclean
def test_covariances():
    """Test covariance for multiple estimator"""
    x = np.random.randn(2, 3, 100)
    cov = covariances(x)
    cov = covariances(x, estimator='oas')
    cov = covariances(x, estimator='lwf')
    cov = covariances(x, estimator='scm')
    cov = covariances(x, estimator='corr')
    cov = covariances(x, estimator='mcd')
    cov = covariances(x, estimator=np.cov)
    assert_raises(ValueError,covariances, x, estimator='truc')
Example #8
0
    def transform(self, X):
        """Estimate covariance matrices.

        Parameters
        ----------
        X : ndarray, shape (n_trials, n_channels, n_samples)
            ndarray of trials.

        Returns
        -------
        covmats : ndarray, shape (n_trials, n_channels, n_channels)
            ndarray of covariance matrices for each trials.
        """
        covmats = covariances(X, estimator=self.estimator)
        return covmats
Example #9
0
    def transform(self, X: np.array) -> np.array:
        """Estimate covariance matrices.

        Parameters
        ----------
        X : ndarray, shape (n_trials, n_channels, n_samples)
            ndarray of trials.

        Returns
        -------
        covmats : ndarray, shape (n_trials, n_channels * n_frequencies, n_channels * n_frequencies)
            SSVEP covariance matrices for each trials.
        """
        filtered = []
        for filter in self.filters:
            filtered_X = filter(X, axis=-1)
            filtered.append(filtered_X)
        mega_X = np.concatenate(filtered, axis=1)
        out = covariances(mega_X, estimator=self._estimator)
        return out
Example #10
0
    def fit(self, X, y=None):
        """
        Parameters
        ----------
        X : ndarray, shape (n_trials,  n_samples, n_channels)
            Training data, already filtered.
        y : ndarray, shape (n_trials,) | None, optional
            labels corresponding to each trial, not used (mentioned for sklearn comp)

        Returns
        -------
        self : RASR instance.
            the fitted RASR estimator.
        """
        X = check_array(X, allow_nd=True)
        shapeX = X.shape
        if len(shapeX) == 3:
            # concatenate all epochs
            Nt, Ns, Ne = shapeX  # 3D array (not fully sklearn-compatible). First dim should always be trials.
        else:
            raise ValueError(
                "X.shape should be (n_trials, n_samples, n_electrodes).")

        assert Ne < Ns, "number of samples should be higher than number of electrodes, check than \n" \
                        + "X.shape is (n_trials,  n_samples, n_channels)."

        if shapeX[0] < 100:
            raise ValueError(
                "Training requires at least 100 of trials to fit.")

        self.Ne_ = Ne  # save attribute for testing

        epochs = X.copy()
        epochs = check_array(epochs, allow_nd=True)

        # estimate covariances matrices
        covmats = covariances(
            np.swapaxes(epochs, 1, 2),
            estimator=self.estimator)  # (n_trials, n_channels, n_times)
        covmats = check_array(covmats, allow_nd=True)

        # geometric median
        # NOTE: while the term geometric median is used, it is NOT riemannian median but euclidian median, i.e.
        # it might be suboptimal for Symmetric Positive Definite matrices.

        logger.debug("geometric median")
        # covmean = mean_covariance(covmats, metric=self.metric_mean)
        covmean = np.reshape(
            geometric_median(
                np.reshape(
                    covmats,
                    (covmats.shape[0], covmats.shape[1] * covmats.shape[2]))),
            (covmats.shape[1], covmats.shape[2]))

        self.mixing_ = sqrtm(covmean)  # estimate matrix matrix

        # TODO: implement both manifold-aware PCA (rASR) and standard PCA (ASR)
        evals, evecs = eigh(self.mixing_)  # compute PCA
        indx = np.argsort(evals)  # sort in ascending
        evecs = evecs[:, indx]
        epochs = np.tensordot(epochs, evecs,
                              axes=(2, 0))  # apply PCA to epochs

        # RMS on sliding window
        rms_sliding = _rms(epochs)

        dist_params = np.zeros(
            (Ne,
             4))  # mu, sig, alpha, beta parameters of estimated distribution

        #TODO: use joblib to parrallelize this loop (code bottleneck)
        for c in range(Ne):
            dist_params[c, :] = _fit_eeg_distribution(
                rms_sliding[:, c], **self.args_eeg_distribution)
        self.threshold_ = np.diag(dist_params[:, 0] + self.rejection_cutoff *
                                  dist_params[:, 1]).dot(np.transpose(evecs))

        logger.debug("rASR calibrated")

        return self