├── matrix_pencil.m ├── README.md └── PronyMethod.py /matrix_pencil.m: -------------------------------------------------------------------------------- 1 | function [answer] = matrix_pencil(x,p,Ts) 2 | 3 | N=length(x); 4 | Y=hankel(x(1:end-p),x(end-p:end)); 5 | 6 | Y1=Y(:,1:end-1); 7 | Y2=Y(:,2:end); 8 | 9 | l=eig(pinv(Y1)*Y2); 10 | 11 | alfa=log(abs(l))/Ts; 12 | freq=atan2(imag(l),real(l))/(2*pi*Ts); 13 | 14 | Z=zeros(N,p); 15 | for i = 1:length(l) 16 | Z(:,i)=transpose(l(i).^(0:N-1)); 17 | end 18 | 19 | rZ=real(Z); 20 | iZ=imag(Z); 21 | 22 | rZ(isinf(rZ))=realmax*sign(rZ(isinf(rZ))); 23 | iZ(isinf(iZ))=realmax*sign(iZ(isinf(iZ))); 24 | 25 | Z=rZ+1i*iZ; 26 | h=Z\x; 27 | Amp=abs(h); 28 | theta=atan2(imag(h),real(h)); 29 | 30 | answer=[Amp theta alfa freq]; 31 | 32 | end 33 | 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ReadMe 2 | 这里有用矩阵束方法实现Prony方法的matlab和python代码,可用来分析时域信号。matlab代码来自参考文献,py代码的过程和功能和matlab代码一致。 3 | 4 | 代码中的函数需要三个输入参数,分别是信号数组x\[n\],分析阶数p(p阶意味着信号由p项指数项的线性组合表示)和采样时间。 5 | 6 | 函数输出的是一个p×4矩阵,矩阵的列向量分别是振幅,初相位,衰减因子和频率。 7 | 8 | ----------------------------------------------------------------------------------------------------------------------------------------- 9 | This repository includes matlab code and py code which implement Prony's method via Matrix Pencil Method. 10 | 11 | A data sequence x\[n\] can be represented by the sum of p complex parameters (order p).The function requires three input parameters (x,p,Ts), which are data sequence x\[n\], p, and sampling period of signal x\[n\]. 12 | 13 | The output parameter of the function is a (p × 4) matrix whose column vectors are amplitude, initial phase, attenuation factor, and frequency. 14 | 15 | Reference : 16 | Fernández Rodríguez, A., de Santiago Rodrigo, L., López Guillén, E. et al. Coding Prony’s method in MATLAB and applying it to biomedical signal filtering. BMC Bioinformatics 19, 451 (2018). https://doi.org/10.1186/s12859-018-2473-y 17 | -------------------------------------------------------------------------------- /PronyMethod.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Jun 29 10:18:43 2021 4 | 5 | @author: Tan Bingyang 6 | """ 7 | 8 | import numpy as np 9 | import math as mt 10 | import scipy.linalg as sl 11 | 12 | 13 | def MPM(phi,p,Ts): 14 | 15 | end=len(phi)-1 16 | Y=sl.hankel(phi[:end-p],phi[end-p:]) 17 | Y1=Y[:,:-1] 18 | Y2=Y[:,1:] 19 | Y1p=np.linalg.pinv(Y1) 20 | EV=np.linalg.eigvals(np.dot(Y1p, Y2)) 21 | EL=len(EV) 22 | 23 | 24 | #Damping factor and frequency as Prony's method 25 | alpha=np.empty([p]) 26 | frequency=np.empty([p]) 27 | for i in range(p): 28 | alpha[i]=mt.log(abs(EV[i]))/Ts 29 | frequency[i]=mt.atan2(EV[i].imag, EV[i].real)/(2*mt.pi*Ts) 30 | 31 | #complex residues (amplitudes and angle phases)as Prony's method 32 | Z=np.zeros([EL,EL],dtype=complex) 33 | rZ=np.empty([EL,EL]) 34 | iZ=np.empty([EL,EL]) 35 | for i in range(EL): 36 | for j in range(EL): 37 | Z[i,j]=EV[j]**i 38 | rZ[i,j]=Z[i,j].real 39 | iZ[i,j]=Z[i,j].imag 40 | 41 | h=np.linalg.solve(Z,phi[0:EL]) 42 | theta=np.empty([EL]) 43 | amp=abs(h) 44 | for i in range(EL): 45 | theta[i]=mt.atan2(h[i].imag, h[i].real) 46 | 47 | answer=np.c_[amp,theta,alpha,frequency] 48 | return answer 49 | 50 | --------------------------------------------------------------------------------