def eval_vol(self, vol_true, vol_est): norm_true = anorm(vol_true) err = anorm(vol_true - vol_est) rel_err = err / norm_true # RCOPT corr = acorr(vol_true.asnumpy(), vol_est.asnumpy()) return {"err": err, "rel_err": rel_err, "corr": corr}
def eval_volmat(self, volmat_true, volmat_est): """ Evaluate volume matrix estimation accuracy :param volmat_true: The true volume matrices in the form of an L-by-L-by-L-by-L-by-L-by-L-by-K array. :param volmat_est: The estimated volume matrices in the same form. :return: """ norm_true = anorm(volmat_true) err = anorm(volmat_true - volmat_est) rel_err = err / norm_true corr = acorr(volmat_true, volmat_est) return {"err": err, "rel_err": rel_err, "corr": corr}
def vol_coords(self, mean_vol=None, eig_vols=None): """ Coordinates of simulation volumes in a given basis :param mean_vol: A mean volume in the form of a Volume Instance (default `mean_true`). :param eig_vols: A set of k volumes in a Volume instance (default `eigs`). :return: """ if mean_vol is None: mean_vol = self.mean_true() if eig_vols is None: eig_vols = self.eigs()[0] assert isinstance(mean_vol, Volume) assert isinstance(eig_vols, Volume) vols = self.vols - mean_vol # note, broadcast V = vols.to_vec() EV = eig_vols.to_vec() coords = EV @ V.T res = vols - Volume.from_vec(coords.T @ EV) res_norms = anorm(res.asnumpy(), (1, 2, 3)) res_inners = mean_vol.to_vec() @ res.to_vec().T return coords.squeeze(), res_norms, res_inners
def eval_eigs(self, eigs_est, lambdas_est): """ Evaluate covariance eigendecomposition accuracy :param eigs_est: The estimated volume eigenvectors in an L-by-L-by-L-by-K array. :param lambdas_est: The estimated eigenvalues in a K-by-K diagonal matrix (default `diag(ones(K, 1))`). :return: """ eigs_true, lambdas_true = self.eigs() B = eigs_est.to_vec() @ eigs_true.to_vec().T norm_true = anorm(lambdas_true) norm_est = anorm(lambdas_est) inner = ainner(B @ lambdas_true, lambdas_est @ B) err = np.sqrt(norm_true**2 + norm_est**2 - 2 * inner) rel_err = err / norm_true corr = inner / (norm_true * norm_est) # TODO: Determine Principal Angles and return as a dict value return {"err": err, "rel_err": rel_err, "corr": corr}
def eval_coords(self, mean_vol, eig_vols, coords_est): """ Evaluate coordinate estimation :param mean_vol: A mean volume in the form of a Volume instance. :param eig_vols: A set of eigenvolumes in an Volume instance. :param coords_est: The estimated coordinates in the affine space defined centered at `mean_vol` and spanned by `eig_vols`. :return: """ assert isinstance(mean_vol, Volume) assert isinstance(eig_vols, Volume) coords_true, res_norms, res_inners = self.vol_coords(mean_vol, eig_vols) # 0-indexed states vector states = self.states - 1 coords_true = coords_true[states] res_norms = res_norms[states] res_inners = res_inners[:, states] mean_eigs_inners = (mean_vol.to_vec() @ eig_vols.to_vec().T).item() coords_err = coords_true - coords_est err = np.hypot(res_norms, coords_err) mean_vol_norm2 = anorm(mean_vol) ** 2 norm_true = np.sqrt( coords_true ** 2 + mean_vol_norm2 + 2 * res_inners + 2 * mean_eigs_inners * coords_true ) norm_true = np.hypot(res_norms, norm_true) rel_err = err / norm_true inner = ( mean_vol_norm2 + mean_eigs_inners * (coords_true + coords_est) + coords_true * coords_est + res_inners ) norm_est = np.sqrt( coords_est ** 2 + mean_vol_norm2 + 2 * mean_eigs_inners * coords_est ) corr = inner / (norm_true * norm_est) return {"err": err, "rel_err": rel_err, "corr": corr}
mean_coeff=mean_coeff_est, covar_coeff=covar_coeff_est, noise_var=noise_var, ) # Convert Fourier-Bessel coefficients back into 2D images imgs_est = ffbbasis.evaluate(coeff_est) # Evaluate the results # Calculate the difference between the estimated covariance and the "true" # covariance estimated from the clean Fourier-Bessel coefficients. covar_coeff_diff = covar_coeff - covar_coeff_est # Calculate the deviation between the clean estimates and those obtained from # the noisy, filtered images. diff_mean = anorm(mean_coeff_est - mean_coeff) / anorm(mean_coeff) diff_covar = covar_coeff_diff.norm() / covar_coeff.norm() # Calculate the normalized RMSE of the estimated images. nrmse_ims = (imgs_est - imgs_clean).norm() / imgs_clean.norm() logger.info(f"Deviation of the noisy mean estimate: {diff_mean}") logger.info(f"Deviation of the noisy covariance estimate: {diff_covar}") logger.info(f"Estimated images normalized RMSE: {nrmse_ims}") # plot the first images at different stages idm = 0 plt.subplot(2, 2, 1) plt.imshow(-imgs_noise[idm], cmap="gray") plt.colorbar() plt.title("Noise") plt.subplot(2, 2, 2)
logger.info( f"Finish normal FB expansion of original images in {dtime:.4f} seconds.") # Reconstruct images from the expansion coefficients based on FB basis fb_images = fb_basis.evaluate(fb_coeffs) logger.info( "Finish reconstruction of images from normal FB expansion coefficients.") # Calculate the mean value of maximum differences between the FB estimated images and the original images fb_meanmax = np.mean(np.max(abs(fb_images - org_images), axis=2)) logger.info( f"Mean value of maximum differences between FB estimated images and original images: {fb_meanmax}" ) # Calculate the normalized RMSE of the FB estimated images fb_nrmse_ims = anorm(fb_images - org_images) / anorm(org_images) logger.info(f"FB estimated images normalized RMSE: {fb_nrmse_ims}") # plot the first images using the normal FB method plt.subplot(1, 3, 1) plt.imshow(np.real(org_images[0]), cmap="gray") plt.title("Original") plt.subplot(1, 3, 2) plt.imshow(np.real(fb_images[0]), cmap="gray") plt.title("FB Image") plt.subplot(1, 3, 3) plt.imshow(np.real(org_images[0] - fb_images[0]), cmap="gray") plt.title("Differences") plt.tight_layout() # %%