pyerrors.mpm
1import numpy as np 2import scipy.linalg 3 4from .linalg import eig, svd 5from .obs import Obs 6 7 8def matrix_pencil_method(corrs, k=1, p=None, **kwargs): 9 """Matrix pencil method to extract k energy levels from data 10 11 Implementation of the matrix pencil method based on 12 eq. (2.17) of Y. Hua, T. K. Sarkar, IEEE Trans. Acoust. 38, 814-824 (1990) 13 14 Parameters 15 ---------- 16 data : list 17 can be a list of Obs for the analysis of a single correlator, or a list of lists 18 of Obs if several correlators are to analyzed at once. 19 k : int 20 Number of states to extract (default 1). 21 p : int 22 matrix pencil parameter which filters noise. The optimal value is expected between 23 len(data)/3 and 2*len(data)/3. The computation is more expensive the closer p is 24 to len(data)/2 but could possibly suppress more noise (default len(data)//2). 25 26 Returns 27 ------- 28 energy_levels : list[Obs] 29 Extracted energy levels 30 """ 31 if isinstance(corrs[0], Obs): 32 data = [corrs] 33 else: 34 data = corrs 35 36 lengths = [len(d) for d in data] 37 if lengths.count(lengths[0]) != len(lengths): 38 raise Exception('All datasets have to have the same length.') 39 40 data_sets = len(data) 41 n_data = len(data[0]) 42 43 if p is None: 44 p = max(n_data // 2, k) 45 if n_data <= p: 46 raise Exception('The pencil p has to be smaller than the number of data samples.') 47 if p < k or n_data - p < k: 48 raise Exception('Cannot extract', k, 'energy levels with p=', p, 'and N-p=', n_data - p) 49 50 # Construct the hankel matrices 51 matrix = [] 52 for n in range(data_sets): 53 matrix.append(scipy.linalg.hankel(data[n][:n_data - p], data[n][n_data - p - 1:])) 54 matrix = np.array(matrix) 55 # Construct y1 and y2 56 y1 = np.concatenate(matrix[:, :, :p]) 57 y2 = np.concatenate(matrix[:, :, 1:]) 58 # Apply SVD to y2 59 u, s, vh = svd(y2, **kwargs) 60 # Construct z from y1 and SVD of y2, setting all singular values beyond the kth to zero 61 z = np.diag(1. / s[:k]) @ u[:, :k].T @ y1 @ vh.T[:, :k] 62 # Return the sorted logarithms of the real eigenvalues as Obs 63 energy_levels = np.log(np.abs(eig(z, **kwargs))) 64 return sorted(energy_levels, key=lambda x: abs(x.value))
def
matrix_pencil_method(corrs, k=1, p=None, **kwargs):
9def matrix_pencil_method(corrs, k=1, p=None, **kwargs): 10 """Matrix pencil method to extract k energy levels from data 11 12 Implementation of the matrix pencil method based on 13 eq. (2.17) of Y. Hua, T. K. Sarkar, IEEE Trans. Acoust. 38, 814-824 (1990) 14 15 Parameters 16 ---------- 17 data : list 18 can be a list of Obs for the analysis of a single correlator, or a list of lists 19 of Obs if several correlators are to analyzed at once. 20 k : int 21 Number of states to extract (default 1). 22 p : int 23 matrix pencil parameter which filters noise. The optimal value is expected between 24 len(data)/3 and 2*len(data)/3. The computation is more expensive the closer p is 25 to len(data)/2 but could possibly suppress more noise (default len(data)//2). 26 27 Returns 28 ------- 29 energy_levels : list[Obs] 30 Extracted energy levels 31 """ 32 if isinstance(corrs[0], Obs): 33 data = [corrs] 34 else: 35 data = corrs 36 37 lengths = [len(d) for d in data] 38 if lengths.count(lengths[0]) != len(lengths): 39 raise Exception('All datasets have to have the same length.') 40 41 data_sets = len(data) 42 n_data = len(data[0]) 43 44 if p is None: 45 p = max(n_data // 2, k) 46 if n_data <= p: 47 raise Exception('The pencil p has to be smaller than the number of data samples.') 48 if p < k or n_data - p < k: 49 raise Exception('Cannot extract', k, 'energy levels with p=', p, 'and N-p=', n_data - p) 50 51 # Construct the hankel matrices 52 matrix = [] 53 for n in range(data_sets): 54 matrix.append(scipy.linalg.hankel(data[n][:n_data - p], data[n][n_data - p - 1:])) 55 matrix = np.array(matrix) 56 # Construct y1 and y2 57 y1 = np.concatenate(matrix[:, :, :p]) 58 y2 = np.concatenate(matrix[:, :, 1:]) 59 # Apply SVD to y2 60 u, s, vh = svd(y2, **kwargs) 61 # Construct z from y1 and SVD of y2, setting all singular values beyond the kth to zero 62 z = np.diag(1. / s[:k]) @ u[:, :k].T @ y1 @ vh.T[:, :k] 63 # Return the sorted logarithms of the real eigenvalues as Obs 64 energy_levels = np.log(np.abs(eig(z, **kwargs))) 65 return sorted(energy_levels, key=lambda x: abs(x.value))
Matrix pencil method to extract k energy levels from data
Implementation of the matrix pencil method based on eq. (2.17) of Y. Hua, T. K. Sarkar, IEEE Trans. Acoust. 38, 814-824 (1990)
Parameters
- data (list): can be a list of Obs for the analysis of a single correlator, or a list of lists of Obs if several correlators are to analyzed at once.
- k (int): Number of states to extract (default 1).
- p (int): matrix pencil parameter which filters noise. The optimal value is expected between len(data)/3 and 2*len(data)/3. The computation is more expensive the closer p is to len(data)/2 but could possibly suppress more noise (default len(data)//2).
Returns
- energy_levels (list[Obs]): Extracted energy levels