def Delta_Psi_eval(y, S): N, K = y.shape kernel_vect, u, sr_S = kernel_rank_sign(y, S) # sr_S = sp.linalg.inv(sp.linalg.sqrtm(S)) inv_sr_S2 = np.kron(T(sr_S), sr_S) I_N = np.eye(N) J_n_per = np.eye(N**2) - np.outer(routines.vec(I_N), routines.vec(I_N)) / N K_V = inv_sr_S2 @ J_n_per # Kernel_appo = np.zeros((N**2,), dtype=complex) # for k in range(K): # uk = u[:,k] # Mat_appo = np.outer(uk,C(uk)) # Kernel_appo = Kernel_appo + kernel_vect[k] * routines.vec(Mat_appo) Kernel_appo = np.zeros((N, N), dtype=complex) for n1 in range(N): Kernel_appo[n1, n1:N] = ((u[n1, :].conj() * kernel_vect) * u[n1:N, :]).sum(axis=1) Kernel_appo = np.triu(Kernel_appo, 1) + np.tril( Kernel_appo.transpose().conj(), 0) Kernel_appo = np.ravel(Kernel_appo, order='C') Delta_S = (K_V @ Kernel_appo) / math.sqrt(K) Delta_S = np.delete(Delta_S, [0]) Kc = K_V @ H(K_V) Psi_S = np.delete(np.delete(Kc, 0, 0), 0, 1) return Delta_S, Psi_S
def Delta_Psi_eval(y, S, M_n): N, K = y.shape kernel_vect, u, sr_S = kernel_rank_sign(y,S) #sr_S = sp.linalg.inv(sp.linalg.sqrtm(S)) inv_sr_S2 = np.kron(sr_S,sr_S) I_N = np.eye(N) J_n_per = np.eye(N**2) - np.outer(routines.vec(I_N), routines.vec(I_N))/N K_V = M_n @ (inv_sr_S2 @ J_n_per) Kernel_appo = np.zeros((N,N)) for n1 in range(N): Kernel_appo[n1,n1:N] = ((u[n1,:] * kernel_vect) * u[n1:N,:]).sum(axis=1) Kernel_appo = np.triu(Kernel_appo, 1) + np.tril(Kernel_appo.transpose(), 0) Kernel_appo = np.ravel(Kernel_appo, order='C') #Kernel_appo = np.zeros((N**2,)) #for k in range(K): # uk = u[:,k] # Mat_appo = np.outer(uk,uk) # Kernel_appo = Kernel_appo + kernel_vect[k] * vec(Mat_appo) Delta_S = (K_V @ Kernel_appo) / math.sqrt(K) Psi_S = K_V @ T(K_V) return Delta_S, Psi_S
def R_estimator_VdW_score(y, mu, S0, pert): """ # ----------------------------------------------------------- # This function implement the R-estimator for shape matrices # Input: # y: (N, K)-dim complex data array where N is the dimension of each vector and K is the number of available data # mu: N-dim array containing a preliminary estimate of the location # S0: (N, N)-dim array containing a preliminary estimator of the scatter matrix # pert: perturbation parameter # Output: # S_est: Estimated shape matrix with the normalization [S_est]_{1,1} = 1 # ----------------------------------------------------------- """ N, K = y.shape S0 = S0 / S0[0, 0] y = T(T(y) - mu) # Generation of the perturbation matrix V = pert * (np.random.randn(N, N) + 1j * np.random.randn(N, N)) V = (V + H(V)) / 2 V[0, 0] = 0 alpha_est, Delta_S, Psi_S = alpha_estimator_sub(y, S0, V) beta_est = 1 / alpha_est v_appo = beta_est * (sp.linalg.inv(Psi_S) @ Delta_S) / math.sqrt(K) N_VDW = routines.vec(S0) + np.append([0], v_appo) N_VDW_mat = np.reshape(N_VDW, (N, N), order='F') return N_VDW_mat
def alpha_estimator_sub( y, S0, V, M_n, N_n): N, K = y.shape Delta_S, Psi_S = Delta_Psi_eval(y, S0, M_n) S_pert = S0 + V/math.sqrt(K) Delta_S_pert = Delta_only_eval(y, S_pert, M_n) V_1 = routines.vec(V) alpha_est = np.linalg.norm(Delta_S_pert-Delta_S)/np.linalg.norm(Psi_S @ (N_n @ V_1)) return alpha_est, Delta_S, Psi_S
def alpha_estimator_sub(y, S0, V): N, K = y.shape Delta_S, Psi_S = Delta_Psi_eval(y, S0) S_pert = S0 + V / math.sqrt(K) Delta_S_pert = Delta_only_eval(y, S_pert) V_1 = routines.vec(V) V_1 = np.delete(V_1, [0]) alpha_est = np.linalg.norm(Delta_S_pert - Delta_S) / np.linalg.norm( Psi_S @ V_1) return alpha_est, Delta_S, Psi_S
Nl = len(svect) K = 5 * N n = np.arange(0, N, 1) rx = rho**n Sigma = C(sp.linalg.toeplitz(rx)) Ls = H(sp.linalg.cholesky(Sigma)) Shape_S = N * Sigma / np.trace(Sigma) Inv_Shape_S = sp.linalg.inv(Shape_S) DIM = int(N**2) J_phi = routines.vec(np.eye(N)).reshape(-1, 1) U = sp.linalg.null_space(T(J_phi)) Fro_MSE_SCM = np.empty(Nl) Fro_MSE_Ty = np.empty(Nl) Fro_MSE_R = np.empty(Nl) SCRBn = np.empty(Nl) for il in range(Nl): s = svect[il] print(s) b = (sigma2 * N * math.gamma(N / s) / (math.gamma((N + 1) / s)))**s MSE_SCM = np.zeros((DIM, DIM)) MSE_Ty = np.zeros((DIM, DIM))
err_Ty = np.outer(err_v, err_v) MSE_Ty = MSE_Ty + err_Ty / Ns mu0 = np.zeros((N, )) Rm1 = R_shape_estim_REAL.R_estimator_VdW_score(y, mu0, Ty1, perturbation_par) Rm = N * Rm1 / np.trace(Rm1) # MSE mismatch on sigma err_rm = routines.vech(Rm - Shape_S) err_RM = np.outer(err_rm, err_rm) MSE_R = MSE_R + err_RM / Ns # Semiparametric CRB a2 = (N + 2 * s) / (2 * (N + 2)) SFIM_Sigma = K * a2 * T(Dn) @ ( np.kron(Inv_Shape_S, Inv_Shape_S) - (1 / N) * np.outer(routines.vec(Inv_Shape_S), routines.vec(Inv_Shape_S))) @ Dn SCRB = U @ sp.linalg.inv(T(U) @ SFIM_Sigma @ U) @ T(U) SCRBn[il] = np.linalg.norm(SCRB, ord='fro') Fro_MSE_SCM[il] = np.linalg.norm(MSE_SCM, ord='fro') Fro_MSE_Ty[il] = np.linalg.norm(MSE_Ty, ord='fro') Fro_MSE_R[il] = np.linalg.norm(MSE_R, ord='fro') plt.plot(svect, Fro_MSE_SCM, svect, Fro_MSE_Ty, svect, Fro_MSE_R, svect, SCRBn) plt.legend(['SCM', 'Ty', 'R', 'SCRB']) plt.ylabel('MSE and Bound') plt.xlabel('Shape parameter: s') plt.show()
err_v = routines.vech(Ty-Shape_S) err_Ty = np.outer(err_v, err_v) MSE_Ty = MSE_Ty + err_Ty/Ns mu0 = np.zeros((N,)) Rm1 = R_shape_estim_REAL.R_estimator_VdW_score(y, mu0, Ty1, perturbation_par) Rm = N * Rm1 / np.trace(Rm1) # MSE mismatch on sigma err_rm = routines.vech(Rm-Shape_S) err_RM = np.outer(err_rm, err_rm) MSE_R = MSE_R + err_RM/Ns # Semiparametric CRB a2 = (lambdap + N)/(2*(N+2+lambdap)) SFIM_Sigma = K * a2 * T(Dn) @ (np.kron(Inv_Shape_S,Inv_Shape_S) - (1/N) * np.outer(routines.vec(Inv_Shape_S), routines.vec(Inv_Shape_S)) ) @ Dn SCRB = U @ sp.linalg.inv(T(U) @ SFIM_Sigma @ U) @ T(U) SCRBn[il] = np.linalg.norm(SCRB, ord='fro') Fro_MSE_SCM[il] = np.linalg.norm(MSE_SCM, ord='fro') Fro_MSE_Ty[il] = np.linalg.norm(MSE_Ty, ord='fro') Fro_MSE_R[il] = np.linalg.norm(MSE_R, ord='fro') plt.plot(lambdavect, Fro_MSE_SCM, lambdavect, Fro_MSE_Ty, lambdavect, Fro_MSE_R, lambdavect, SCRBn) plt.ylim(0.3, 1) plt.legend(['SCM','Ty','R','SCRB']) plt.ylabel('MSE and Bound') plt.xlabel('Degrees of freedom: lambda')