def eval_vol(self, vol_true, vol_est): norm_true = anorm(vol_true) err = anorm(vol_true - vol_est) rel_err = err / norm_true corr = acorr(vol_true, vol_est) 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 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 = vol_to_vec(eigs_est).T @ vol_to_vec(eigs_true) 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 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 an L-by-L-by-L array (default `mean_true`). :param eig_vols: A set of eigenvolumes in an L-by-L-by-L-by-K array (default `eigs`). :return: """ if mean_vol is None: mean_vol = self.mean_true() if eig_vols is None: eig_vols = self.eigs()[0] vols = self.vols - np.expand_dims(mean_vol, 3) coords = vol_to_vec(eig_vols).T @ vol_to_vec(vols) res = vols - vec_to_vol(vol_to_vec(eig_vols) @ coords) res_norms = np.diag(anorm(res, (0, 1, 2))) res_inners = vol_to_vec(mean_vol).T @ vol_to_vec(res) return coords.squeeze(), res_norms, res_inners
def eval_coords(self, mean_vol, eig_vols, coords_est): """ Evaluate coordinate estimation :param mean_vol: A mean volume in the form of an L-by-L-by-L array. :param eig_vols: A set of eigenvolumes in an L-by-L-by-L-by-K array. :param coords_est: The estimated coordinates in the affine space defined centered at `mean_vol` and spanned by `eig_vols`. :return: """ 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 = np.asscalar( vol_to_vec(mean_vol).T @ vol_to_vec(eig_vols)) 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}