|
4 | 4 | dim = 100 |
5 | 5 | rng = np.random.default_rng() |
6 | 6 | A = rng.random((dim, dim)) |
| 7 | +A = (A + A.T) * 0.5 |
7 | 8 |
|
8 | 9 | tri = nanoeigenpy.Tridiagonalization(A) |
| 10 | + |
| 11 | +Q = tri.matrixQ() |
| 12 | +T = tri.matrixT() |
| 13 | + |
| 14 | +assert nanoeigenpy.is_approx(A, Q @ T @ Q.T, 1e-10) |
| 15 | +assert nanoeigenpy.is_approx(Q @ Q.T, np.eye(dim), 1e-10) |
| 16 | + |
| 17 | +for i in range(dim): |
| 18 | + for j in range(dim): |
| 19 | + if abs(i - j) > 1: |
| 20 | + assert abs(T[i, j]) < 1e-12 |
| 21 | + |
| 22 | +assert nanoeigenpy.is_approx(T, T.T, 1e-12) |
| 23 | + |
| 24 | +diag = tri.diagonal() |
| 25 | +sub_diag = tri.subDiagonal() |
| 26 | + |
| 27 | +for i in range(dim): |
| 28 | + assert abs(diag[i] - T[i, i]) < 1e-12 |
| 29 | + |
| 30 | +for i in range(dim - 1): |
| 31 | + assert abs(sub_diag[i] - T[i + 1, i]) < 1e-12 |
| 32 | + |
| 33 | +A_test = rng.random((dim, dim)) |
| 34 | +A_test = (A_test + A_test.T) * 0.5 |
| 35 | + |
| 36 | +tri1 = nanoeigenpy.Tridiagonalization(dim) |
| 37 | +tri1.compute(A_test) |
| 38 | +tri2 = nanoeigenpy.Tridiagonalization(A_test) |
| 39 | + |
| 40 | +Q1 = tri1.matrixQ() |
| 41 | +T1 = tri1.matrixT() |
| 42 | +Q2 = tri2.matrixQ() |
| 43 | +T2 = tri2.matrixT() |
| 44 | + |
| 45 | +assert nanoeigenpy.is_approx(Q1, Q2, 1e-12) |
| 46 | +assert nanoeigenpy.is_approx(T1, T2, 1e-12) |
| 47 | + |
| 48 | +h_coeffs = tri.householderCoefficients() |
| 49 | +packed = tri.packedMatrix() |
| 50 | + |
| 51 | +assert h_coeffs.shape == (dim - 1,) |
| 52 | +assert packed.shape == (dim, dim) |
| 53 | + |
| 54 | +for i in range(dim): |
| 55 | + for j in range(i + 1, dim): |
| 56 | + assert abs(packed[i, j] - A[i, j]) < 1e-12 |
| 57 | + |
| 58 | +for i in range(dim): |
| 59 | + assert abs(packed[i, i] - T[i, i]) < 1e-12 |
| 60 | + if i < dim - 1: |
| 61 | + assert abs(packed[i + 1, i] - T[i + 1, i]) < 1e-12 |
| 62 | + |
| 63 | +A_diag = np.diag(rng.random(dim)) |
| 64 | +tri_diag = nanoeigenpy.Tridiagonalization(A_diag) |
| 65 | +Q_diag = tri_diag.matrixQ() |
| 66 | +T_diag = tri_diag.matrixT() |
| 67 | + |
| 68 | +assert nanoeigenpy.is_approx(A_diag, Q_diag @ T_diag @ Q_diag.T, 1e-10) |
| 69 | +for i in range(dim): |
| 70 | + for j in range(dim): |
| 71 | + if i != j: |
| 72 | + assert abs(T_diag[i, j]) < 1e-10 |
| 73 | + |
| 74 | +A_tridiag = np.zeros((dim, dim)) |
| 75 | +for i in range(dim): |
| 76 | + A_tridiag[i, i] = rng.random() |
| 77 | + if i < dim - 1: |
| 78 | + val = rng.random() |
| 79 | + A_tridiag[i, i + 1] = val |
| 80 | + A_tridiag[i + 1, i] = val |
| 81 | + |
| 82 | +tri_tridiag = nanoeigenpy.Tridiagonalization(A_tridiag) |
| 83 | +Q_tridiag = tri_tridiag.matrixQ() |
| 84 | +T_tridiag = tri_tridiag.matrixT() |
| 85 | + |
| 86 | +assert nanoeigenpy.is_approx(A_tridiag, Q_tridiag @ T_tridiag @ Q_tridiag.T, 1e-10) |
| 87 | + |
| 88 | + |
| 89 | +tri1_id = nanoeigenpy.Tridiagonalization(dim) |
| 90 | +tri2_id = nanoeigenpy.Tridiagonalization(dim) |
| 91 | +id1 = tri1_id.id() |
| 92 | +id2 = tri2_id.id() |
| 93 | +assert id1 != id2 |
| 94 | +assert id1 == tri1_id.id() |
| 95 | +assert id2 == tri2_id.id() |
| 96 | + |
| 97 | +tri3_id = nanoeigenpy.Tridiagonalization(A) |
| 98 | +tri4_id = nanoeigenpy.Tridiagonalization(A) |
| 99 | +id3 = tri3_id.id() |
| 100 | +id4 = tri4_id.id() |
| 101 | +assert id3 != id4 |
| 102 | +assert id3 == tri3_id.id() |
| 103 | +assert id4 == tri4_id.id() |
0 commit comments