def rho_mat(ell_shape_mat: np.ndarray, dirs_mat: np.ndarray, abs_tol: float = None, ell_center_vec: np.ndarray = None) -> Tuple[np.ndarray, np.ndarray]: if abs_tol is None: abs_tol = Properties.get_abs_tol() m = ell_shape_mat.shape[0] if ell_center_vec is None: ell_center_vec = np.zeros((m, 1)) nd = dirs_mat.shape[1] if nd == 1: sq = sqrt_pos(dirs_mat.T @ ell_shape_mat @ dirs_mat) sup_arr = ell_center_vec.T @ dirs_mat + sq bp_mat = (ell_shape_mat @ dirs_mat) / sq if np.any(np.isnan(bp_mat)): bp_mat[:] = 0. bp_mat = bp_mat + ell_center_vec else: temp_mat = sqrt_pos(np.sum(dirs_mat.T @ ell_shape_mat * dirs_mat.T, axis=1), abs_tol).T sup_arr = ell_center_vec.T @ dirs_mat + temp_mat bp_mat = ell_shape_mat @ dirs_mat / np.tile(temp_mat, (m, 1)) is_nan_bp_mat = np.isnan(bp_mat) is_nan_vec = np.any(is_nan_bp_mat, 0) if np.any(is_nan_vec): bp_mat[:, is_nan_vec] = 0. bp_mat = bp_mat + np.tile(ell_center_vec, (1, nd)) return sup_arr, bp_mat
def is_bigger(self, sec_ell) -> bool: from ellipy.elltool.core.core import ell_sim_diag self._check_is_me(sec_ell, 'second') self._check_if_scalar(sec_ell) sec_ell = np.array(sec_ell).flatten()[0] n_dim_vec, n_rank_vec = self.dimension([self, sec_ell], return_rank=True) if n_dim_vec[0] != n_dim_vec[1]: throw_error( 'wrongInput', 'both arguments must be single ellipsoids of the same dimension.' ) if n_rank_vec[0] < n_rank_vec[1]: return False first_shape_mat = self.get_shape_mat() sec_shape_mat = sec_ell.get_shape_mat() if self.is_degenerate([self]).flatten()[0]: if Properties.get_is_verbose(): logger = get_logger() logger.info( 'IS_BIGGER: Warning! First ellipsoid is degenerate.') logger.info(' Regularizing...') first_shape_mat = self._regularize(first_shape_mat, self._abs_tol) _, abs_tol = self.get_abs_tol([self, sec_ell], lambda z: np.min(z)) t_mat = ell_sim_diag(first_shape_mat, sec_shape_mat, abs_tol) return np.max(np.abs(np.diag( t_mat @ sec_shape_mat @ t_mat.T))) < (1 + self._abs_tol)
def __init__(self, hyp_norm_vec: np.ndarray = np.array([0.], dtype=np.float64), hyp_shift=0., **kwargs): ABasicEllipsoid.__init__(self) prop_list, _ = Properties.parse_prop(kwargs, ['abs_tol', 'rel_tol']) self._abs_tol = prop_list[0] self._rel_tol = prop_list[1] self._normal_vec = hyp_norm_vec self._shift = hyp_shift
def f_add_sh(sing_ell: Ellipsoid, abs_tol: float) -> Tuple[np.array, float]: from ellipy.gras.geom.ell.ell import quad_mat sh_mat = sing_ell.get_shape_mat() if sing_ell.is_degenerate([sing_ell]).flat[0]: if Properties.get_is_verbose(): logger = get_logger() logger.info( 'MINKSUM_IA: Warning! Degenerate ellipsoid.') logger.info(' Regularizing...') sh_mat = cls._regularize(sh_mat, abs_tol) fst_coef = np.sqrt(quad_mat(sh_mat, dir_vec)) return ((1 / fst_coef) * sh_mat), fst_coef
def f_rot_arr(ell_ind: int) -> Tuple[np.ndarray, np.ndarray]: from ellipy.gras.la.la import ml_orth_transl ell_obj = ell_arr[ell_ind] abs_tol = abs_tol_arr[ell_ind] sh_mat = ell_obj.get_shape_mat() if ell_obj.is_degenerate([ell_obj]).flat[0]: if Properties.get_is_verbose(): logger = get_logger() logger.info('MINKSUM_IA: Warning! Degenerate ellipsoid.') logger.info(' Regularizing...') sh_mat = cls._regularize(sh_mat, abs_tol) sh_sqrt_mat = sqrtm_pos(sh_mat, abs_tol) dst_mat = sh_sqrt_mat @ dir_mat return sh_sqrt_mat, np.reshape(ml_orth_transl(dst_mat, src_mat), [n_dims, n_dims, n_cols])
def f_single_case(sing_ell: np.ndarray, abs_tol: np.float64) -> bool: from ellipy.gras.geom.ell.ell import inv_mat is_pos = False c_vec = (x_vec - np.array([sing_ell.flat[0].get_center_vec().T])).T sh_mat = sing_ell.flat[0].get_shape_mat() if sing_ell.flat[0].is_degenerate([sing_ell]).flat[0]: if Properties.get_is_verbose(): logger = get_logger() logger.info( 'ISINTERNAL: Warning! There is degenerate ellipsoid in the array.' ) logger.info(' Regularizing...') sh_mat = Ellipsoid._regularize(sh_mat, abs_tol) r_val = np.sqrt(c_vec.T @ inv_mat(sh_mat) @ c_vec) if r_val < 1.0 or np.all(np.abs(r_val - 1.0) < abs_tol): is_pos = True return is_pos
def __init__(self, *args, **kwargs): AEllipsoid.__init__(self) prop_list, _ = Properties.parse_prop( kwargs, ['abs_tol', 'rel_tol', 'n_plot_2d_points', 'n_plot_3d_points']) self._abs_tol = prop_list[0] self._rel_tol = prop_list[1] self._n_plot_2d_points = prop_list[2] self._n_plot_3d_points = prop_list[3] if len(args) == 0: self._center_vec = np.zeros((0, ), dtype=np.float64) self._shape_mat = np.zeros((0, 0), dtype=np.float64) elif len(args) == 1: self._shape_mat = args[0] self._center_vec = np.zeros((self._shape_mat.shape[0], ), dtype=np.float64) else: self._center_vec = args[0] self._shape_mat = args[1] if self._center_vec.size != self._shape_mat.shape[0]: throw_error( 'wrongInput', 'dimensions of center_vec and shape_mat must agree')
def _calc_diff_one_dir( first_ell, sec_ell, l_mat: np.ndarray, p_univ_vec: np.ndarray, is_good_dir_vec: np.ndarray) -> Tuple[np.ndarray, bool]: __ABS_TOL = 1e-14 abs_tol = Properties.get_abs_tol() _, min_ell_pts_mat = first_ell.rho(first_ell, l_mat) _, sub_ell_pts_mat = sec_ell.rho(sec_ell, l_mat) if first_ell.dimension(first_ell) == 3: is_plot_center_3d = True else: is_plot_center_3d = False def calc_diff(is_good: bool, ind: int) -> np.ndarray: if is_good: diff_bnd_mat = min_ell_pts_mat[:, ind] - sub_ell_pts_mat[:, ind] else: _, diff_bnd_mat = rho_mat( (1 - p_univ_vec[ind]) * sec_ell.get_shape_mat() + (1 - 1 / p_univ_vec[ind]) * first_ell.get_shape_mat(), l_mat[:, ind], abs_tol, first_ell.get_center_vec() - sec_ell.get_center_vec()) if np.all( np.abs(diff_bnd_mat - first_ell.get_center_vec() + sec_ell.get_center_vec()) < __ABS_TOL): diff_bnd_mat = first_ell.get_center_vec( ) - sec_ell.get_center_vec() else: nonlocal is_plot_center_3d is_plot_center_3d = False return diff_bnd_mat diff_bound_mat = np.array([ calc_diff(x, y) for x, y in zip(is_good_dir_vec, np.arange(0, l_mat.shape[1])) ]) return diff_bound_mat, is_plot_center_3d
def test_is_mat_pos_and_pos_sem_def(self): abs_tol = Properties.get_abs_tol() def check(f): assert f(np.array([[1]]), abs_tol) test_mat_check = np.random.rand(10, 10) test_mat_check = test_mat_check.T @ test_mat_check _, v_mat = np.linalg.eigh(test_mat_check) d_mat = np.diag(np.arange(1, 11)) test_mat_check = v_mat.T @ d_mat @ v_mat test_mat_check = 0.5 * (test_mat_check.T + test_mat_check) is_ok = f(test_mat_check, abs_tol) assert is_ok def check_mult_times(): test_mat_check = np.random.rand(5, 5) test_mat_check = test_mat_check.T @ test_mat_check _, v_mat = np.linalg.eigh(test_mat_check) d_mat = np.diag(np.arange(1, 6)) test_mat_check = v_mat.T @ d_mat @ v_mat test_mat_check = -0.5 * (test_mat_check.T + test_mat_check) is_false = is_mat_pos_def(test_mat_check, abs_tol, True) assert is_false is False with pytest.raises(Exception) as s: sqrtm_pos(test_mat_check, abs_tol) assert 'wrongInput:notPosSemDef' in str(s.value) def check_determ(orth3mat_check, diag_vec_check, is_true, is_sem_pos_def: bool = None): test_mat_check = orth3mat_check.T @ np.diag( diag_vec_check) @ orth3mat_check test_mat_check = 0.5 * (test_mat_check + test_mat_check.T) if is_sem_pos_def is None: is_ok = is_mat_pos_def(test_mat_check, abs_tol) else: is_ok = is_mat_pos_def(test_mat_check, abs_tol, is_sem_pos_def) assert is_true == is_ok def f_is_mat_pos_sem_def(q_mat, abs_tol_test): return is_mat_pos_def(q_mat, abs_tol_test, True) def f_is_mat_pos_def(q_mat, abs_tol_test): return is_mat_pos_def(q_mat, abs_tol_test, False) check(is_mat_pos_def) check(f_is_mat_pos_sem_def) check(f_is_mat_pos_def) test_mat = np.random.rand(10, 10) test_mat = test_mat.T @ test_mat test_mat = 0.5 * (test_mat + test_mat.T) assert f_is_mat_pos_sem_def(test_mat.T @ test_mat, abs_tol) test_mat = np.array([[1, 5], [5, 25]]) assert not is_mat_pos_def(test_mat, abs_tol) assert f_is_mat_pos_sem_def(test_mat, abs_tol) assert not f_is_mat_pos_def(test_mat, abs_tol) assert is_mat_pos_def(np.eye(3)) with pytest.raises(Exception) as e: is_mat_pos_def(np.eye(3, 5), abs_tol) assert 'wrongInput:nonSquareMat' in str(e.value) with pytest.raises(Exception) as e: is_mat_pos_def(np.array([[1, -1], [1, 1]]), abs_tol) assert 'wrongInput:nonSymmMat' in str(e.value) n_times = 50 for i_time in range(n_times): check_mult_times() is_pos_or_sem_def = True orth3mat = np.array( [[-0.206734513608356, -0.439770172956299, 0.873992583413099], [0.763234588112547, 0.486418086920488, 0.425288617559045], [-0.612155049306781, 0.754983204908957, 0.23508840021067]]) diag_vec = [1, 2, 3] check_determ(orth3mat, diag_vec, is_pos_or_sem_def) diag_vec = [1, -1, 3] check_determ(orth3mat, diag_vec, not is_pos_or_sem_def) diag_vec = [0, 1, 1] check_determ(orth3mat, diag_vec, not is_pos_or_sem_def) diag_vec = [0, 1, 2] check_determ(orth3mat, diag_vec, is_pos_or_sem_def, True) diag_vec = [0, -1, 2] check_determ(orth3mat, diag_vec, not is_pos_or_sem_def, True) diag_vec = [-1, 1, -2] check_determ(orth3mat, diag_vec, not is_pos_or_sem_def, False) check_determ(orth3mat, diag_vec, not is_pos_or_sem_def, True)