22import numpy as np
33import pytest
44
5+ THIN_U = nanoeigenpy .DecompositionOptions .ComputeThinU .value
6+ THIN_V = nanoeigenpy .DecompositionOptions .ComputeThinV .value
7+ FULL_U = nanoeigenpy .DecompositionOptions .ComputeFullU .value
8+ FULL_V = nanoeigenpy .DecompositionOptions .ComputeFullV .value
9+
510_options = [
611 0 ,
7- nanoeigenpy .DecompositionOptions .ComputeThinU .value ,
8- nanoeigenpy .DecompositionOptions .ComputeThinV .value ,
9- nanoeigenpy .DecompositionOptions .ComputeFullU .value ,
10- nanoeigenpy .DecompositionOptions .ComputeFullV .value ,
11- nanoeigenpy .DecompositionOptions .ComputeThinU .value
12- | nanoeigenpy .DecompositionOptions .ComputeThinV .value ,
13- nanoeigenpy .DecompositionOptions .ComputeFullU .value
14- | nanoeigenpy .DecompositionOptions .ComputeFullV .value ,
15- nanoeigenpy .DecompositionOptions .ComputeThinU .value
16- | nanoeigenpy .DecompositionOptions .ComputeFullV .value ,
17- nanoeigenpy .DecompositionOptions .ComputeFullU .value
18- | nanoeigenpy .DecompositionOptions .ComputeThinV .value ,
12+ THIN_U ,
13+ THIN_V ,
14+ FULL_U ,
15+ FULL_V ,
16+ THIN_U | THIN_V ,
17+ FULL_U | FULL_V ,
18+ THIN_U | FULL_V ,
19+ FULL_U | THIN_V ,
1920]
2021
2122_classes = [
2627]
2728
2829
30+ def is_valid_combination (cls , options ):
31+ if cls == nanoeigenpy .FullPivHhJacobiSVD :
32+ has_thin_u = bool (options & THIN_U )
33+ has_thin_v = bool (options & THIN_V )
34+
35+ if has_thin_u or has_thin_v :
36+ return False
37+
38+ return True
39+
40+
2941@pytest .mark .parametrize ("cls" , _classes )
3042@pytest .mark .parametrize ("options" , _options )
3143def test_jacobi (cls , options ):
44+ if not is_valid_combination (cls , options ):
45+ pytest .skip (f"Invalid combination: { cls .__name__ } with options { options } " )
46+
3247 dim = 100
3348 rng = np .random .default_rng ()
3449 A = rng .random ((dim , dim ))
3550 A = (A + A .T ) * 0.5 + np .diag (10.0 + rng .random (dim ))
3651
37- if cls == nanoeigenpy .FullPivHhJacobiSVD :
38- if options != 0 and not (
39- options
40- & (
41- nanoeigenpy .DecompositionOptions .ComputeFullU .value
42- | nanoeigenpy .DecompositionOptions .ComputeFullV .value
43- )
44- ):
45- return
46-
4752 jacobisvd = cls (A , options )
4853 assert jacobisvd .info () == nanoeigenpy .ComputationInfo .Success
4954
50- if options & (
51- nanoeigenpy .DecompositionOptions .ComputeThinU .value
52- | nanoeigenpy .DecompositionOptions .ComputeFullU .value
53- ) and options & (
54- nanoeigenpy .DecompositionOptions .ComputeThinV .value
55- | nanoeigenpy .DecompositionOptions .ComputeFullV .value
56- ):
55+ has_u = options & (THIN_U | FULL_U )
56+ has_v = options & (THIN_V | FULL_V )
57+
58+ if has_u and has_v :
5759 X = rng .random ((dim , 20 ))
5860 B = A @ X
5961 X_est = jacobisvd .solve (B )
@@ -66,10 +68,8 @@ def test_jacobi(cls, options):
6668 assert nanoeigenpy .is_approx (x , x_est )
6769 assert nanoeigenpy .is_approx (A @ x_est , b )
6870
69- rows = jacobisvd .rows ()
70- cols = jacobisvd .cols ()
71- assert cols == dim
72- assert rows == dim
71+ assert jacobisvd .rows () == dim
72+ assert jacobisvd .cols () == dim
7373
7474 _jacobisvd_compute = jacobisvd .compute (A )
7575 _jacobisvd_compute_options = jacobisvd .compute (A , options )
@@ -86,37 +86,19 @@ def test_jacobi(cls, options):
8686
8787 compute_u = jacobisvd .computeU ()
8888 compute_v = jacobisvd .computeV ()
89- expected_compute_u = bool (
90- options
91- & (
92- nanoeigenpy .DecompositionOptions .ComputeThinU .value
93- | nanoeigenpy .DecompositionOptions .ComputeFullU .value
94- )
95- )
96- expected_compute_v = bool (
97- options
98- & (
99- nanoeigenpy .DecompositionOptions .ComputeThinV .value
100- | nanoeigenpy .DecompositionOptions .ComputeFullV .value
101- )
102- )
89+ expected_compute_u = bool (has_u )
90+ expected_compute_v = bool (has_v )
10391 assert compute_u == expected_compute_u
10492 assert compute_v == expected_compute_v
10593
10694 if compute_u :
10795 matrixU = jacobisvd .matrixU ()
108- if options & nanoeigenpy .DecompositionOptions .ComputeFullU .value :
109- assert matrixU .shape == (dim , dim )
110- elif options & nanoeigenpy .DecompositionOptions .ComputeThinU .value :
111- assert matrixU .shape == (dim , dim )
96+ assert matrixU .shape == (dim , dim )
11297 assert nanoeigenpy .is_approx (matrixU .T @ matrixU , np .eye (matrixU .shape [1 ]))
11398
11499 if compute_v :
115100 matrixV = jacobisvd .matrixV ()
116- if options & nanoeigenpy .DecompositionOptions .ComputeFullV .value :
117- assert matrixV .shape == (dim , dim )
118- elif options & nanoeigenpy .DecompositionOptions .ComputeThinV .value :
119- assert matrixV .shape == (dim , dim )
101+ assert matrixV .shape == (dim , dim )
120102 assert nanoeigenpy .is_approx (matrixV .T @ matrixV , np .eye (matrixV .shape [1 ]))
121103
122104 if compute_u and compute_v :
0 commit comments