def SNR_fun(l, rank): n_l = sum(num_ell_array[0: rank]) + l ell = l_min + n_l * delta_l # put the whole array cij for an given ell into the upper triangle part of the matrix cijl_array = Cijl_sets[l*N_dset_ext: (l+1)*N_dset_ext] #print(cijl_array, cijl_array.shape) cijl_m[iu1] = np.array(cijl_array) #print(cijl_m, cijl_m.shape) cijl_m_select = np.array(cijl_m[0:red_bin, 0:red_bin]) # select the first red_bin bins of Cij, match the case with T-F cijl_true = np.array(cijl_m_select[iu2]) # convert upper triangle matrix to an array cijl_sn = np.array(cijl_true) cijl_sn[sn_id] = cijl_true[sn_id] + pseudo_sn # add shape noise terms in Cii(l) terms Cov_cij_cpq = cal_cov_matrix(red_bin, iu2, cijl_sn) # calculate the covariance matrix of Cij(l), Cpq(l') Cov_cij_cpq = Cov_cij_cpq.T + np.triu(Cov_cij_cpq, k=1) # It's symmetric. From up triangular matrix, construct the whole matrix for inversion. #inv_Cov_cij_cpq = linalg.inv(Cov_cij_cpq, overwrite_a=True) inv_Cov_cij_cpq = linalg.inv(Cov_cij_cpq) inv_Cov_cij_cpq = inv_Cov_cij_cpq * ((2.0*ell+1.0)*delta_l*f_sky) # Take account of the number of modes (the denominator) SN_square_per_ell = reduce(np.dot, [cijl_true, inv_Cov_cij_cpq, cijl_true]) SN_per_ell = SN_square_per_ell**0.5 if rank == size-1: print('ell from rank', rank, 'is', ell, '\n') #print(np.allclose(np.dot(Cov_cij_cpq, inv_Cov_cij_cpq), np.eye(N_dset))) return ell, SN_per_ell
def cal_C_G(l, rank): n_l = default_num_l_in_rank * rank + l ell = l_min + n_l * delta_l #offset_cijl = n_l * N_dset * data_type_size #offset_Gm = n_l * N_dset * num_kout * data_type_size # put the whole array cij at ell into the upper triangle part of the matrix cijl_array = Cijl_sets[l * N_dset_ext:(l + 1) * N_dset_ext] #print(cijl_array, cijl_array.shape) cijl_m[iu1] = np.array(cijl_array) #print(cijl_m, cijl_m.shape) cijl_m_select = np.array( cijl_m[0:red_bin, 0:red_bin] ) # select the first red_bin bins of Cij, match the case with T-F cijl_true = np.array( cijl_m_select[iu2]) # convert upper triangle matrix to an array cijl_sn = np.array(cijl_true) cijl_sn[sn_id] = cijl_true[ sn_id] + pseudo_sn # add shape noise terms in Cii(l) terms Cov_cij_cpq = cal_cov_matrix( red_bin, iu2, cijl_sn) # calculate the covariance matrix of Cij(l), Cpq(l') # if rank == 0: # rank_matrix = np.linalg.matrix_rank(Cov_cij_cpq) # print('ell, rank of Cov:', ell, rank_matrix) Cov_cij_cpq = Cov_cij_cpq / ( (2.0 * ell + 1.0) * delta_l * f_sky ) # account the number of modes for each l with the interval delta_l w_ccij, v_ccij = linalg.eigh( Cov_cij_cpq, lower=False, overwrite_a=True ) # Get eigenvalue and eigenvectors from Scipy routine w_inv = 1.0 / w_ccij if not np.all(w_inv > 0.0): print('w_inv from ell ', ell, ' is negative.' ) # show below which ell, the inverse of Cov_cij_cpq fails # If uncomment the below, overwrite_a should be set False in the linalg.eigh() # sqrt_w_inv = np.diag(w_inv**0.5) # v_inv = np.transpose(v_ccij) # Cov_cij_sym = np.triu(Cov_cij_cpq, k=1) + Cov_cij_cpq.T # print reduce(np.dot, [np.diag(sqrt_w_inv**2.0), v_inv, Cov_cij_sym, v_inv.T]) Cov_inv_half = np.transpose( w_inv**0.5 * v_ccij ) # Simplify the expression of dot(sqrt_w_inv, v_inv), 05/09/2016 G_l_array = Gm_sets[l * N_dset_ext * num_kout:(l + 1) * N_dset_ext * num_kout] Gm_l_ext = np.reshape( G_l_array, (N_dset_ext, num_kout), 'C' ) # In Python, the default storage of a matrix follows C language format. #print(Gm_l_ext) Gm_l = np.array(Gm_l_ext[Gmrow_sel_ind, :]) Gm_l = np.dot(Cov_inv_half, Gm_l) cijl_true = np.dot(Cov_inv_half, cijl_true) return cijl_true, Gm_l
def cal_C_G(l, rank): n_l = default_num_l_in_rank * rank + l ell = l_min + n_l * delta_l cijl_true = Cijl_sets[l * N_dset:(l + 1) * N_dset] # if rank == 0: # print(cijl_true) cijl_sn = np.array( cijl_true ) # Distinguish the observed C^ijl) (denoted by cijl_sn) from the true C^ij(l) cijl_sn[sn_id] = cijl_true[ sn_id] + pseudo_sn # Add shape noise on C^ii terms to get cijl_sn # if rank == 0: # print('cijl_sn:', cijl_sn) Cov_cij_cpq = cal_cov_matrix( num_rbin, iu1, cijl_sn ) # Get an upper-triangle matrix for Cov(C^ij, C^pq) from Fortran subroutine wrapped. if rank == 0: rank_matrix = np.linalg.matrix_rank(Cov_cij_cpq) print('ell, rank of Cov:', ell, rank_matrix) # ofile = ofprefix + "Cov_cij_cpq_ell_{}_{}rbins_{}kbins_snf{}_rank{}.npz".format(ell, num_rbin, num_kin, snf, rank) # np.savez_compressed(ofile, Cov_cij_cpq = Cov_cij_cpq) Cov_cij_cpq = Cov_cij_cpq / ( (2.0 * ell + 1.0) * delta_l * f_sky ) # Take account of the number of modes (the denominator) # if rank == 0: # print('Cov_cij_cpq:', Cov_cij_cpq) w_ccij, v_ccij = linalg.eigh( Cov_cij_cpq, lower=False, overwrite_a=True ) # Get eigenvalue and eigenvectors from Scipy routine w_inv = 1. / w_ccij # if rank == 0: # print('w_ccij', w_ccij, 'v_ccij:', v_ccij) #--If uncomment the below, overwrite_a should be set False in the linalg.eigh() # sqrt_w_inv = np.diag(w_inv**0.5) # v_inv = np.transpose(v_ccij) # Cov_cij_sym = np.triu(Cov_cij_cpq, k=1) + Cov_cij_cpq.T # Once Cov_cij_cpq set to be overwriten, the criterion couldn't be used anymore # print(reduce(np.dot, [np.diag(w_inv), v_inv, Cov_cij_sym, v_inv.T])) Cov_inv_half = np.transpose( w_inv**0.5 * v_ccij ) # Simplify the expression of dot(sqrt_w_inv, v_inv), 05/09/2016 # if rank == 0: # print('Cov_inv_half:', Cov_inv_half) G_l_array = Gm_sets[l * N_dset * num_kout:(l + 1) * N_dset * num_kout] Gm_l = np.reshape( G_l_array, (N_dset, num_kout), 'C' ) # In Python, the default storage of a matrix follows C language format. #print Gm_l[0,:] Gm_l = np.dot(Cov_inv_half, Gm_l) cijl_true = np.dot(Cov_inv_half, cijl_true) # if rank == 0: # print('ell from rank', rank, 'is', ell, '\n') return cijl_true, Gm_l
def SNR_fun(l, rank): n_l = default_num_l_in_rank * rank + l ell = l_min + n_l * delta_l cijl_true = Cijl_sets[l*N_dset: (l+1)*N_dset] # if rank == 0: # print(cijl_true) cijl_sn = np.array(cijl_true) # Distinguish the observed C^ijl) (denoted by cijl_sn) from the true C^ij(l) cijl_sn[sn_id] = cijl_true[sn_id] + pseudo_sn # Add shape noise on C^ii terms to get cijl_sn # if rank == 0: # print('cijl_sn:', cijl_sn) Cov_cij_cpq = cal_cov_matrix(num_rbin, iu1, cijl_sn) # Get an upper-triangle matrix for Cov(C^ij, C^pq) from Fortran subroutine wrapped. Cov_cij_cpq = Cov_cij_cpq.T + np.triu(Cov_cij_cpq, k=1) # It's symmetric. Construct the whole matrix for inversion. inv_Cov_cij_cpq = linalg.inv(Cov_cij_cpq, ) inv_Cov_cij_cpq = inv_Cov_cij_cpq * ((2.0*ell+1.0)*delta_l*f_sky) # Take account of the number of modes (the denominator) SN_square_per_ell = reduce(np.dot, [cijl_true, inv_Cov_cij_cpq, cijl_true]) SN_per_ell = SN_square_per_ell**0.5 if rank == size-1: print('ell from rank', rank, 'is', ell, '\n') return ell, SN_per_ell