Coverage for nilearn/decomposition/tests/test_multi_pca.py: 0%
44 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"""Test the multi-PCA module."""
3import numpy as np
4import pytest
5from numpy.testing import (
6 assert_almost_equal,
7 assert_array_almost_equal,
8 assert_array_equal,
9)
11from nilearn.decomposition._multi_pca import _MultiPCA
12from nilearn.decomposition.tests.conftest import (
13 RANDOM_STATE,
14 check_decomposition_estimator,
15)
16from nilearn.maskers import NiftiMasker, SurfaceMasker
19@pytest.mark.timeout(0)
20@pytest.mark.parametrize("data_type", ["nifti", "surface"])
21@pytest.mark.parametrize("length", [1, 2])
22def test_multi_pca(
23 length,
24 data_type,
25 decomposition_mask_img,
26 decomposition_images,
27):
28 """Components are the same if we put twice the same data, \
29 and that fit output is deterministic.
30 """
31 multi_pca = _MultiPCA(
32 mask=decomposition_mask_img, n_components=3, random_state=RANDOM_STATE
33 )
34 multi_pca.fit(decomposition_images)
36 check_decomposition_estimator(multi_pca, data_type)
38 components1 = multi_pca.components_
40 multi_pca = _MultiPCA(
41 mask=decomposition_mask_img, n_components=3, random_state=RANDOM_STATE
42 )
43 multi_pca.fit(length * decomposition_images)
44 components2 = multi_pca.components_
46 if length == 1:
47 assert_array_equal(components1, components2)
48 else:
49 assert_array_almost_equal(components1, components2)
52@pytest.mark.parametrize("data_type", ["nifti", "surface"])
53def test_multi_pca_with_masker_without_cca_smoke(
54 data_type,
55 decomposition_masker,
56 decomposition_images,
57):
58 """Multi-pca can run with a masker \
59 and without canonical correlation analysis.
60 """
61 multi_pca = _MultiPCA(
62 mask=decomposition_masker,
63 do_cca=False,
64 n_components=3,
65 )
66 multi_pca.fit(decomposition_images[:2])
68 check_decomposition_estimator(multi_pca, data_type)
70 # Smoke test the transform and inverse_transform
71 multi_pca.inverse_transform(multi_pca.transform(decomposition_images[-2:]))
74@pytest.mark.parametrize("with_activation", [False])
75@pytest.mark.parametrize("data_type", ["nifti", "surface"])
76def test_multi_pca_score_single_subject_n_components(
77 data_type,
78 decomposition_mask_img,
79 decomposition_img,
80 with_activation, # noqa: ARG001
81):
82 """Score is one for n_components == n_sample \
83 in single subject configuration.
84 """
85 multi_pca = _MultiPCA(
86 mask=decomposition_mask_img,
87 random_state=RANDOM_STATE,
88 memory_level=0,
89 n_components=5,
90 )
91 multi_pca.fit(decomposition_img)
92 s = multi_pca.score(decomposition_img)
94 assert_almost_equal(s, 1.0, 1)
96 # Per component score
97 multi_pca = _MultiPCA(
98 mask=decomposition_mask_img,
99 random_state=RANDOM_STATE,
100 memory_level=0,
101 n_components=5,
102 )
103 multi_pca.fit(decomposition_img)
105 check_decomposition_estimator(multi_pca, data_type)
107 if data_type == "nifti":
108 masker = NiftiMasker(decomposition_mask_img).fit()
109 elif data_type == "surface":
110 masker = SurfaceMasker(decomposition_mask_img).fit()
112 s = multi_pca._raw_score(
113 masker.transform(decomposition_img), per_component=True
114 )
116 assert s.shape == (5,)
117 assert np.all(s <= 1)
118 assert np.all(s >= 0)