def sort_rows_tol(inp_mat: np.ndarray, tol: float) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: if tol < 0.: throw_error('wrongInput:tol', 'tol is expected to be a positive number') if not (inp_mat.ndim == 2 and is_numeric(inp_mat)): throw_error('wrongInput:inp_mat', 'input is expected to be a numeric matrix') copy_inp_mat = np.copy(inp_mat) n_cols = np.size(copy_inp_mat, 1) n_rows = np.size(copy_inp_mat, 0) if n_rows > 0: res_mat = np.copy(copy_inp_mat) for i_col in range(n_cols): ind_col_sort_vec = np.argsort(copy_inp_mat[:, i_col]) col_vec = copy_inp_mat[ind_col_sort_vec, i_col] col_diff_vec = np.diff(col_vec) is_less_vec = np.abs(col_diff_vec) <= tol col_diff_vec[is_less_vec] = 0. col_vec = np.cumsum(np.hstack((col_vec[0], col_diff_vec))) ind_col_rev_sort_vec = np.argsort(ind_col_sort_vec) copy_inp_mat[:, i_col] = col_vec[ind_col_rev_sort_vec] ind_sort_vec = np.lexsort(np.fliplr(copy_inp_mat).T) res_mat = res_mat[ind_sort_vec] else: res_mat = copy_inp_mat ind_sort_vec = np.empty((0, ), dtype=np.float64) ind_rev_sort_vec = np.argsort(ind_sort_vec) return res_mat, ind_sort_vec, ind_rev_sort_vec
def orth_transl(src_vec: np.ndarray, dst_vec: np.ndarray) -> np.ndarray: __ABS_TOL = 1e-7 n_dims = dst_vec.shape[0] src_vec = try_treat_as_real(src_vec) dst_vec = try_treat_as_real(dst_vec) dst_squared_norm = np.sum(dst_vec * dst_vec) src_squared_norm = np.sum(src_vec * src_vec) if dst_squared_norm == 0.0: throw_error('wrongInput:dst_zero', 'destination vectors are expected to be non-zero') if src_squared_norm == 0.0: throw_error('wrongInput:src_zero', 'source vectors are expected to be non-zero') dst_vec = dst_vec / np.sqrt(dst_squared_norm) src_vec = src_vec / np.sqrt(src_squared_norm) scal_prod = np.sum(src_vec * dst_vec) s_val = np.sqrt(np.maximum(1.0 - scal_prod * scal_prod, 0.0)) q_mat = np.zeros((n_dims, 2), dtype=np.float64) q_mat[:, 0] = np.squeeze(dst_vec) if np.abs(s_val) > __ABS_TOL: q_mat[:, 1] = np.squeeze((src_vec - scal_prod * dst_vec) / s_val) else: q_mat[:, 1] = 0.0 s_mat = np.array([[scal_prod - 1.0, s_val], [-s_val, scal_prod - 1.0]], dtype=np.float64) o_mat = np.identity(n_dims, dtype=np.float64) + q_mat @ s_mat @ q_mat.T return o_mat
def from_expression(expr: str, t_vec: Union[int, float, np.ndarray]) -> np.ndarray: exec("from numpy import *") # string check exp_str = expr if len(exp_str) < 1: throw_error('wrongInput', 'expr must be a non-empty string!') if exp_str[0] != "[": exp_str = "[[" + exp_str elif exp_str[1] != "[": exp_str = "[" + exp_str if exp_str[-1] != "]": exp_str = exp_str + "]]" elif exp_str[-2] != "]": exp_str = exp_str + "]" t = MatVector.__to_array(t_vec) if len(t) == 1: ret_val = np.array(eval(exp_str)) if ret_val.ndim < 2: ret_val = np.expand_dims(ret_val, 1) if ret_val.ndim < 3: ret_val = np.expand_dims(ret_val, 2) return ret_val else: time_len = len(t) ret_val = eval(exp_str) ret_val = [[ np.repeat(np.asarray(j), time_len) if type(j) != np.ndarray else j for j in i ] for i in ret_val] ret_val = np.array(ret_val) ret_shape = ret_val.shape if len(ret_shape) < 3: ret_val = np.expand_dims(ret_val, 0) return ret_val
def r_multiply_by_vec(a_arr: np.ndarray, b_mat: np.ndarray, use_sparse_matrix: bool = True) -> np.ndarray: if len(b_mat.shape) != 2: throw_error('wrongInput', 'b_mat is expected to be 2-dimensional array') n_rows = a_arr.shape[0] n_cols = a_arr.shape[1] n_time_points = a_arr.shape[2] if use_sparse_matrix: i_ind = np.arange(n_cols * n_time_points) j_ind = np.repeat(np.arange(n_time_points), n_cols) b_sparse = sp.csc_matrix( (b_mat.T.flatten(), (i_ind, j_ind)), shape=(n_cols * n_time_points, n_time_points)) ret_mat = a_arr.reshape(n_rows, n_cols * n_time_points, order='F') @ b_sparse else: ret_mat = np.zeros((n_rows, n_time_points), dtype=np.float64) for i_time_point in range(n_time_points): ret_mat[:, i_time_point] = a_arr[:, :, i_time_point] @ b_mat[:, i_time_point] return ret_mat
def get_conf_repo_mgr(): if Properties.__conf_repo_mgr is None: Properties.init() if Properties.__conf_repo_mgr is None: throw_error('noConfRepoMgr', 'cannot initialize Configuration Repo Manager') return Properties.__conf_repo_mgr
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 get_boundary(self, n_points: int = None, return_grid: bool = False) -> \ Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]: Ellipsoid._check_if_scalar(self) n_dim = self.dimension([self]).flat[0] if n_dim == 2: if n_points is None: n_points = self._n_plot_2d_points elif n_dim == 3: if n_points is None: n_points = self._n_plot_3d_points else: throw_error('wrongDim', 'ellipsoid must be of dimension 2 or 3') if return_grid: dir_mat, f_mat = sphere_tri_ext(n_dim, n_points, return_grid) else: dir_mat = sphere_tri_ext(n_dim, n_points, return_grid) f_mat = None cen_vec, q_mat = self.double() ret_mat = dir_mat @ sqrtm_pos( q_mat, self.get_abs_tol([self], f_prop_fun=None).flat[0]) cen_mat = np.tile(cen_vec.T, (dir_mat.shape[0], 1)) ret_mat = ret_mat + cen_mat if return_grid: return ret_mat, f_mat else: return ret_mat
def _get_grid_by_factor(self, factor_vec: np.ndarray = np.array( 1., dtype=np.float64)): __EPS = 1e-15 n_dim = self.dimension([self]).flat[0] if n_dim < 2 or n_dim > 3: throw_error('wrongDim:ellipsoid', 'ellipsoid must be of dimension 2 or 3') if factor_vec.ndim == 0: factor = factor_vec.flat[0] else: factor = factor_vec.flat[n_dim - 2] if n_dim == 2: n_plot_points = self._n_plot_2d_points if not (factor == 1): n_plot_points = np.floor(n_plot_points * factor) else: n_plot_points = self._n_plot_3d_points if not (factor == 1): n_plot_points = np.floor(n_plot_points * factor) v_grid_mat, f_grid_mat = sphere_tri_ext(n_dim, n_plot_points) v_grid_mat[v_grid_mat == 0] = __EPS return v_grid_mat, f_grid_mat
def from_rep_mat(cls, *args, **kwargs) -> np.ndarray: if len(args) == 0: throw_error('wrongInput', 'At least one input argument is expected') shape_vec = np.array(args[-1]).flatten() args = args[:-1] ell_obj = Ellipsoid(*args, **kwargs) return ell_obj.rep_mat(shape_vec)
def reg_mat(inp_mat: np.ndarray, reg_tol: float) -> np.ndarray: if not (np.isscalar(reg_tol) and is_numeric(reg_tol) and reg_tol > 0.): throw_error('wrongInput:reg_tol', 'reg_tol must be a positive numeric scalar') reg_tol = try_treat_as_real(reg_tol) u_mat, s_vec, v_mat = np.linalg.svd(inp_mat) s_mat = np.diag(np.maximum(s_vec, reg_tol)) res_mat = u_mat @ s_mat @ v_mat return res_mat
def polar(cls, ell_arr: Union[Iterable, np.ndarray]) -> np.ndarray: cls._check_is_me(ell_arr) if np.any(cls.is_degenerate(ell_arr)): throw_error('degenerateEllipsoid', 'The resulting ellipsoid is not bounded') pol_ell_arr = np.empty((1, ell_arr.size), dtype=cls.__class__) for i_elem in range(ell_arr.size): pol_ell_arr[i_elem] = cls._get_scalar_polar_internal( ell_arr[i_elem], True) return np.reshape(pol_ell_arr, ell_arr.shape)
def sphere_tri(depth: int) -> Tuple[np.ndarray, np.ndarray]: def normvert(x: np.ndarray) -> np.ndarray: return x / ml.repmat(np.sqrt(np.sum(x * x, 1)).reshape(-1, 1), 1, 3) if not (np.isscalar(depth) and is_numeric(np.array(depth)) and 0 <= depth == np.fix(depth)): throw_error('wrong_input', 'depth is expected to be a non-negative integer scalar') v_mat, f_mat = icosahedron() v_mat, f_mat = shrink_face_tri(v_mat, f_mat, 0, depth, normvert) return v_mat, f_mat
def inv_mat(q_mat: np.ndarray) -> np.ndarray: if q_mat.ndim != 2: throw_error('wrongInput:q_mat', 'input must be a matrix') q_mat_dim_m, q_mat_dim_n = np.shape(q_mat) if q_mat_dim_m != q_mat_dim_n: throw_error('wrongInput:q_mat', 'input matrix must be square') b_mat = np.linalg.inv(q_mat) i_mat = np.linalg.inv(b_mat @ q_mat) @ b_mat return i_mat
def is_mat_not_deg(q_mat: np.ndarray, abs_tol: float = 0.0) -> bool: if abs_tol < 0.0: throw_error('wrongInput:abs_tolNegative', 'abs_tol is expected to be non-negative') if abs_tol == 0.0: return True else: min_sing = np.min(np.linalg.svd(q_mat, compute_uv=False)) if min_sing < abs_tol: return False else: return True
def is_mat_symm(q_mat: np.ndarray, abs_tol: float = 0.) -> bool: if q_mat.ndim != 2: throw_error('wrongInput:nonSquareMat', 'q_mat should be a matrix') n_rows = q_mat.shape[0] n_cols = q_mat.shape[1] if n_rows != n_cols: throw_error('wrongInput:nonSquareMat', 'q_mat should be a square matrix') abs_func: Callable[[np.ndarray], np.ndarray] = lambda x: np.abs(x) is_symm, *_ = abs_rel_compare(q_mat, q_mat.T, abs_tol, None, abs_func) return is_symm
def sphere_tri_ext(n_dim: int, n_points: int, return_f_grid: bool = False) \ -> Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]: def spherebndr_2d(n_points_2d: int, return_f_vec: bool = False) -> \ Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]: bp_mat = circle_part(n_points_2d) if return_f_vec: f_mat = np.vstack( (np.arange(0, n_points_2d), np.arange(1, n_points_2d + 1))).T f_mat[n_points_2d - 1, 1] = 0 return bp_mat, f_mat return bp_mat def spherebndr_3d(n_points_3d: int) -> Tuple[np.ndarray, np.ndarray]: sphere_triang_num = calc_depth(n_points_3d) bp_mat, f_mat = sphere_tri(sphere_triang_num) return bp_mat, f_mat def calc_depth(num_points: int) -> int: # Initial icosaeder parameters: __VERTICES_NUM = 12 __FACES_NUM = 20 __EDGES_NUM = 30 vert_num = __VERTICES_NUM face_num = __FACES_NUM edge_num = __EDGES_NUM # cur_depth = 0 is_stop = False while not is_stop: cur_depth = cur_depth + 1 vert_num = vert_num + edge_num edge_num = 2 * edge_num + 3 * face_num face_num = 4 * face_num is_stop = vert_num >= num_points triang_depth = cur_depth return triang_depth if not (np.isscalar(n_points) and is_numeric(np.array(n_points)) and 0 < n_points == np.fix(n_points)): throw_error( 'wrong_input', 'n_points is expected to be a positive integer scalar number') if n_dim == 2: if return_f_grid: v_grid_mat, f_grid_mat = spherebndr_2d(n_points, return_f_grid) else: v_grid_mat = spherebndr_2d(n_points) v_grid_mat[np.equal(v_grid_mat, 0)] = np.finfo(float).eps return v_grid_mat else: v_grid_mat, f_grid_mat = spherebndr_3d(n_points) v_grid_mat[np.equal(v_grid_mat, 0)] = np.finfo(float).eps return v_grid_mat, f_grid_mat
def sphere_part(n_points: int) -> np.ndarray: from ellipy.gras.geom.tri.tri import sphere_tri def unique_directions(a_mat: np.ndarray, tol: float) -> np.ndarray: n_rows = a_mat.shape[0] is_remove_vec = np.zeros(n_rows, dtype=bool) for i_row in range(0, n_rows - 1): diff_mat = a_mat[-(n_rows - i_row - 1):, :] + np.tile( a_mat[i_row, :], ([n_rows - i_row - 1, 1])) diff_norm_vec = np.sqrt(np.sum(diff_mat * diff_mat, 1)) ind_remove_vec = np.nonzero(diff_norm_vec < tol)[0] if ind_remove_vec.size > 0: if np.sum(a_mat[i_row, :]) < 0: is_remove_vec[i_row + ind_remove_vec[0] + 1] = True else: is_remove_vec[i_row] = True return a_mat[is_remove_vec, :] def sphere_distance(a_mat: np.ndarray, b_vec: np.ndarray) -> np.ndarray: dot_prod_vec = np.sum(a_mat * np.tile(b_vec, ([a_mat.shape[0], 1])), 1) return np.arccos(dot_prod_vec) if n_points <= 0: throw_error('wrongInput:n_points', 'n_points should be positive integer') if n_points < 21: depth = 1 else: depth = math.ceil(np.log2((n_points - 1.) / 5) / 2) p_mat = unique_directions(sphere_tri(depth)[0], 1e-8) x_dist_vec = sphere_distance(p_mat, np.array([1, 0, 0])) y_dist_vec = sphere_distance(p_mat, np.array([0, 1, 0])) z_dist_vec = sphere_distance(p_mat, np.array([0, 0, 1])) r_mat = np.zeros(shape=(n_points, 3), dtype=np.float64) for i_point in range(n_points): mod_i = np.mod(i_point, 3) if mod_i == 1: i_min = np.argmin(x_dist_vec) x_dist_vec[i_min] = 2 * np.pi elif mod_i == 2: i_min = np.argmin(y_dist_vec) y_dist_vec[i_min] = 2 * np.pi else: i_min = np.argmin(z_dist_vec) z_dist_vec[i_min] = 2 * np.pi r_mat[i_point] = p_mat[i_min] return r_mat
def __compare_arrays(bp_arr: np.ndarray, f_arr: np.ndarray, bp_right_arr: np.ndarray, f_right_arr: np.ndarray) -> bool: __ABSTOL__ = 1.0e-12 is_equal_1 = True is_equal_2 = True if not (bp_arr.size == f_arr.size): throw_error('wrongInput', 'bp_arr and f_arr must be of the same size') for i in range(bp_arr.size): is_equal_1 = is_equal_1 and \ abs_rel_compare(bp_right_arr[i], bp_arr[i], __ABSTOL__, __ABSTOL__, np.linalg.norm)[0] is_equal_2 = is_equal_2 and \ abs_rel_compare(f_right_arr[i], f_arr[i], __ABSTOL__, __ABSTOL__, np.linalg.norm)[0] return is_equal_1 and is_equal_2
def lr_svd_multiply(inp_b_arr: np.ndarray, inp_a_arr: np.ndarray, flag: str = 'R') -> np.ndarray: u_array, s_array = SymmetricMatVector.__array_svd(inp_b_arr) ua_array = None if flag == 'L': ua_array = SquareMatVector.r_multiply( u_array, MatVector.transpose(inp_a_arr)) elif flag == 'R': ua_array = SquareMatVector.r_multiply(u_array, inp_a_arr) else: throw_error('wrongInput:flag', 'flag %s is not supported' % flag) out_array = SquareMatVector.lr_multiply(s_array, ua_array, flag) return out_array
def reg_pos_def_mat(inp_mat: np.ndarray, reg_tol: float) -> np.ndarray: if not (np.isscalar(reg_tol) and is_numeric(reg_tol) and np.real(reg_tol) > 0.0): throw_error('wrongInput:reg_tol', 'reg_tol must be a positive numeric scalar') reg_tol = try_treat_as_real(reg_tol) if not (is_mat_symm(inp_mat)): throw_error('wrongInput:inp_mat', 'matrix must be symmetric') d_mat, v_mat = np.linalg.eig(inp_mat) m_mat = np.diag(np.maximum(0.0, reg_tol - d_mat)) m_mat = v_mat @ m_mat @ v_mat.T regular_mat = inp_mat + m_mat regular_mat = 0.5 * (regular_mat + regular_mat.T) return regular_mat
def ell_valign(v: np.ndarray, x: np.ndarray) -> np.ndarray: if (not is_numeric(v)) or (not is_numeric(x)): throw_error('wrongInput:v,x', 'ELL_VALIGN: both arguments must be vectors in R^n.') if v.size != max(v.shape): throw_error('wrongInput:v', 'ELL_VALIGN: first argument must be a vector.') if x.size != max(x.shape): throw_error('wrongInput:x', 'ELL_VALIGN: second argument must be a vector.') if v.ndim == 0: v = np.expand_dims(v, axis=0) else: v = np.squeeze(v) if x.ndim == 0: x = np.expand_dims(x, axis=0) else: x = np.squeeze(x) if v.shape[0] != x.shape[0]: throw_error('wrongInput:v,x', 'ELL_VALIGN: both vectors must be of the same dimension.') u1_mat, _, v1_mat = svd(np.expand_dims(v, axis=1), full_matrices=True) u2_mat, _, v2_mat = svd(np.expand_dims(x, axis=1), full_matrices=True) v2_mat = v2_mat[0, 0] v1_mat = v1_mat[0, 0] t_mat = v1_mat * v2_mat * u1_mat @ u2_mat.T return t_mat
def mat_dot(inp_arr1: np.ndarray, inp_arr2: np.ndarray) -> np.ndarray: inp_arr1 = np.array(inp_arr1) inp_arr2 = np.array(inp_arr2) if not (inp_arr2.shape == inp_arr1.shape): throw_error('wrongInput:size', 'input matrices have the different size') if not (inp_arr1.shape[0] == inp_arr1.shape[1]): throw_error( 'wrongInput:not_square', 'input matrices aren' 't square matrices or square matrix arrays') mat_sum = np.sum(np.sum(inp_arr1 * inp_arr2, keepdims=True, axis=1), keepdims=True, axis=0) res_arr = mat_sum / inp_arr1.shape[0] return res_arr
def r_svd_multiply_by_vec(inp_mat_arr: np.ndarray, inp_vec_arr: np.ndarray) -> np.ndarray: u_array, s_array = SymmetricMatVector.__array_svd(inp_mat_arr) uv_array = MatVector.r_multiply_by_vec(u_array, inp_vec_arr) if inp_vec_arr.ndim != 2: throw_error('wrongInput:inp_vec_arr', 'inpVecArray is expected to be 2-dimensional array') m_size_vec = np.shape(s_array) v_size_vec = np.shape(uv_array) out_vec_array = np.zeros((m_size_vec[0], v_size_vec[1]), dtype=np.float64) for t in range(v_size_vec[1]): out_vec_array[:, t] = u_array[:, :, t].T @ s_array[:, :, t] @ uv_array[:, t] return out_vec_array
def is_mat_pos_def(q_mat: np.ndarray, abs_tol: float = 0., is_flag_sem_def_on: bool = False) -> bool: if abs_tol < 0.: throw_error('wrongInput:abs_tolNegative', 'abs_tol is expected to be nonnegative') if not is_mat_symm(q_mat, abs_tol): throw_error('wrongInput:nonSymmMat', 'input matrix must be symmetric') eig_vec = np.linalg.eigvalsh(q_mat) min_eig = min(eig_vec) is_pos_def = True if is_flag_sem_def_on: if min_eig < -abs_tol: is_pos_def = False else: if min_eig <= abs_tol: is_pos_def = False return is_pos_def
def _check_is_me_internal(cls, ell_arr: Union[Iterable, np.ndarray], var_name: str = '', err_tag: str = 'wrongInput', err_msg: str = None) -> None: if var_name != '': err_tag += ':' + var_name if err_msg is None: err_msg = 'input argument must be {}'.format(cls.__name__) if isinstance(ell_arr, collections.Iterable): ell_arr = np.array(ell_arr) if ell_arr.size > 0: ell_flatten_arr = ell_arr.flatten() for i_ell in range(ell_flatten_arr.size): if not isinstance(ell_flatten_arr[i_ell], cls): throw_error(err_tag, err_msg) elif not isinstance(ell_arr, cls): throw_error(err_tag, err_msg)
def __check_res(test_ell_res_arr, comp_list, operation): __VEC_COMP_METHODS_LIST = ['uminus', 'plus', 'minus', 'move_2_origin', 'get_move_2_origin'] __MAT_COMP_METHODS_LIST = ['inv', 'shape', 'get_inv', 'get_shape'] # test_ell_res_centers_vec_list = np.array([[elem.get_center_vec() for elem in test_ell_res_arr.flatten()]]) test_ell_res_shape_mat_list = np.array([[elem.get_shape_mat() for elem in test_ell_res_arr.flatten()]]) if np.isin(operation, __VEC_COMP_METHODS_LIST): eq_arr = [np.array_equal(x, y) for (x, y) in zip(test_ell_res_centers_vec_list.flatten(), comp_list.flatten())] elif np.isin(operation, __MAT_COMP_METHODS_LIST): eq_arr = [np.array_equal(x, y) for (x, y) in zip(test_ell_res_shape_mat_list.flatten(), comp_list.flatten())] else: eq_arr = [] expr = ' '.join(__VEC_COMP_METHODS_LIST + __MAT_COMP_METHODS_LIST) throw_error('wrongInput:badMethodName', 'Allowed method names: {}. Input name: {}'.format(expr, operation)) test_is_right = np.all(np.equal(eq_arr[:], 1)) assert test_is_right
def try_treat_as_real(inp_mat: Union[bool, int, float, complex, np.ndarray], tol_val: float = np.finfo(float).eps) \ -> np.ndarray: if not (np.isscalar(tol_val) and is_numeric(tol_val) and tol_val > 0.0): throw_error('wrongInput:tol_val', 'tol_val must be a positive numeric scalar') if np.all(np.isreal(inp_mat)): return inp_mat else: img_inp_mat = inp_mat.imag if np.isscalar(img_inp_mat): norm_value = np.abs(img_inp_mat) else: norm_value = linalg.norm(img_inp_mat, np.inf) if norm_value < tol_val: return np.real(inp_mat.real) else: throw_error( 'wrongInput:inp_mat', 'Norm of imaginary part of source object = {}. It can not be more then tol_val = {}.' .format(norm_value, tol_val))
def make_pos_definite_by_eig(data_arr: np.ndarray, value: float = 1e-12) -> np.ndarray: size_vec = data_arr.shape res_data_arr = np.zeros(size_vec) if data_arr.ndim == 2: if not is_mat_symm(data_arr): throw_error('wrongInput:non SymmMat', 'input matrix must be symetric') d_vec, v_mat = np.linalg.eigh(data_arr) d_vec[d_vec < 0.] = value res_data_arr = (v_mat @ np.diag(d_vec) @ v_mat.T).real else: for t in range(size_vec[2]): if not is_mat_symm(data_arr[:, :, t]): throw_error('wrongInput:non SymmMat', 'input matrix must be symetric') d_vec, v_mat = np.linalg.eigh(data_arr[:, :, t]) d_vec[d_vec < 0.] = value res_data_arr[:, :, t] = (v_mat @ np.diag(d_vec) @ v_mat.T).real return res_data_arr
def parse_prop( args: Dict[str, Any], needed_prop_name_list: List[str] = None ) -> Tuple[List[Any], Dict[str, Any]]: if needed_prop_name_list is None: needed_prop_name_list = ParsePropMixin.__PROP_NAME_LIST check_func_list = ParsePropMixin.__PROP_CHECK_FUNC_LIST else: is_there_vec, ind_there_vec = is_member( needed_prop_name_list, ParsePropMixin.__PROP_NAME_LIST) if ~np.all(is_there_vec): throw_error( 'wrongInput', 'properties {} are unknown'.format([ pair[0] for pair in zip(needed_prop_name_list, np.logical_not(is_there_vec)) if pair[1] ])) check_func_list = [ ParsePropMixin.__PROP_CHECK_FUNC_LIST[ind] for ind in list(ind_there_vec) ] pre_prop = p.Properties.Properties.get_prop_dict() prop_list = [] args = args.copy() for i_prop in range(len(needed_prop_name_list)): prop_name = needed_prop_name_list[i_prop] check_func = check_func_list[i_prop] if prop_name in args: prop_val = args[prop_name] del args[prop_name] else: prop_val = pre_prop[prop_name] if not check_func(prop_val): throw_error('wrongInput', 'Property {} has wrong values'.format(prop_name)) prop_list.append(prop_val) return prop_list, args
def var_replace(m_mat: np.ndarray, from_var_name: str, to_var_name: str) -> np.ndarray: if not m_mat.size: throw_error('wrongInput:m_mat', 'm_mat must not be empty') if not isinstance(from_var_name, str): throw_error('wrongInput:from_var_name', 'from_var_name is expected to be a string') if not isinstance(to_var_name, str): throw_error('wrongInput:to_var_name', 'to_var_name is expected to be a string') def _str(elem): __PRECISION = 15 if not isinstance(elem, str): if not isinstance(elem, Integral): elem = np.format_float_positional(elem, precision=__PRECISION, trim='.') else: elem = str(elem) return elem m_mat = np.vectorize(_str)(m_mat) to_var_name = '(' + to_var_name + ')' def _replace(elem, to_replace, value): return elem.replace(to_replace, value) m_mat = np.vectorize(_replace)(m_mat, ' ', '') m_mat = np.vectorize(re.sub)(r'\b' + from_var_name + r'\b', to_var_name, m_mat) return m_mat