Skip to content

Commit 92aeae1

Browse files
committed
Fix cov.normalization matrix and cov.intrinsic_emittances for 2D matrices
1 parent 20e40cd commit 92aeae1

File tree

1 file changed

+22
-11
lines changed

1 file changed

+22
-11
lines changed

psdist/cov.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
"""Covariance matrix analysis."""
2-
32
import numpy as np
43

54

@@ -8,6 +7,10 @@ def rms_ellipsoid_volume(cov_matrix: np.ndarray) -> float:
87

98

109
def projected_emittances(cov_matrix: np.ndarray) -> tuple[float, ...]:
10+
ndim = cov_matrix.shape[0]
11+
if ndim == 2:
12+
return rms_ellipsoid_volume(cov_matrix)
13+
1114
emittances = []
1215
for i in range(0, cov_matrix.shape[0], 2):
1316
emittance = rms_ellipsoid_volume(cov_matrix[i : i + 2, i : i + 2])
@@ -16,8 +19,15 @@ def projected_emittances(cov_matrix: np.ndarray) -> tuple[float, ...]:
1619

1720

1821
def intrinsic_emittances(cov_matrix: np.ndarray) -> tuple[float, ...]:
19-
S = cov_matrix[:4, :4].copy() # [to do]: expand to NxN
20-
U = unit_symplectic_matrix(4)
22+
ndim = cov_matrix.shape[0]
23+
if ndim > 4:
24+
raise ValueError("ndim > 4")
25+
26+
if ndim == 2:
27+
return rms_ellipsoid_volume(cov_matrix)
28+
29+
S = cov_matrix.copy() # [to do] expand to NxN using np.eig
30+
U = unit_symplectic_matrix(ndim)
2131
tr_SU2 = np.trace(np.linalg.matrix_power(np.matmul(S, U), 2))
2232
det_S = np.linalg.det(S)
2333
eps_1 = 0.5 * np.sqrt(-tr_SU2 + np.sqrt(tr_SU2**2 - 16.0 * det_S))
@@ -26,11 +36,6 @@ def intrinsic_emittances(cov_matrix: np.ndarray) -> tuple[float, ...]:
2636

2737

2838
def twiss_2d(cov_matrix: np.ndarray) -> tuple[float, float, float]:
29-
"""Compute twiss parameters from 2 x 2 covariance matrix.
30-
31-
alpha = -<xx'> / sqrt(<xx><x'x'> - <xx'><xx'>)
32-
beta = <xx> / sqrt(<xx><x'x'> - <xx'><xx'>)
33-
"""
3439
emittance = rms_ellipsoid_volume(cov_matrix)
3540
beta = cov_matrix[0, 0] / emittance
3641
alpha = -cov_matrix[0, 1] / emittance
@@ -128,16 +133,22 @@ def normalization_matrix(
128133
block_diag : bool
129134
If true, normalize only 2x2 block-diagonal elements (x-x', y-y', etc.).
130135
"""
131-
def _normalization_matrix(_cov_matrix: np.ndarray, scale: bool = False) -> np.ndarray:
132-
S = _cov_matrix.copy()
136+
def _normalization_matrix(cov_matrix: np.ndarray, scale: bool = False) -> np.ndarray:
137+
S = cov_matrix.copy()
133138
U = unit_symplectic_matrix(S.shape[0])
134139
eigvals, eigvecs = np.linalg.eig(np.matmul(S, U))
135140
eigvecs = normalize_eigvecs(eigvecs)
136141
V_inv = normalization_matrix_from_eigvecs(eigvecs)
137142

138143
if scale:
144+
ndim = S.shape[0]
139145
V = np.linalg.inv(V_inv)
140-
A = np.sqrt(np.diag(np.repeat(intrinsic_emittances(S), 2)))
146+
A = np.eye(ndim)
147+
if ndim == 2:
148+
emittance = np.sqrt(np.linalg.det(S))
149+
A = np.diag(np.sqrt([emittance, emittance]))
150+
else:
151+
A = np.sqrt(np.diag(np.repeat(intrinsic_emittances(S), 2)))
141152
V = np.matmul(V, A)
142153
V_inv = np.linalg.inv(V)
143154

0 commit comments

Comments
 (0)