Exemple #1
0
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 compare_m_mat_with_numerics(m_mat, cor_mat, res_mat):
        def cmp_up_to_digits(first_num_str, second_num_str, n_cmp_digits):
            first_list = first_num_str.split('.')
            second_list = second_num_str.split('.')
            is_res_ok = first_list[0] == second_list[0] and len(
                first_list) == len(second_list)
            if is_res_ok and len(first_list) > 1:
                is_res_ok = first_list[1][0:n_cmp_digits - 1] == \
                            second_list[1][0:n_cmp_digits - 1]
            return is_res_ok

        is_num_mat = np.reshape(
            [is_numeric(el) for el in list(m_mat.flatten())], m_mat.shape)
        if np.any(is_num_mat.flatten()):
            if not np.array_equal(cor_mat[~is_num_mat], res_mat[~is_num_mat]):
                return False
        if not np.all(is_num_mat.flatten()):
            if not np.all(
                    np.array([
                        cmp_up_to_digits(cor_el, res_el,
                                         TestSym.__N_COMPARE_DECIMAL_DIGITS)
                        for cor_el, res_el in zip(list(cor_mat[is_num_mat]),
                                                  list(res_mat[is_num_mat]))
                    ])):
                return False
        return True
Exemple #3
0
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
Exemple #4
0
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 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
Exemple #6
0
def ell_sim_diag(a_mat: np.ndarray, b_mat: np.ndarray,
                 abs_tol: float) -> np.ndarray:
    if not (is_numeric(a_mat) and is_numeric(b_mat)):
        throw_error('wrongInput', 'both arguments must be numeric matrices')
    if not is_mat_pos_def(a_mat, abs_tol):
        throw_error(
            'wrongInput:a_mat',
            'first argument must be a symmetric positive definite matrix')
    if not is_mat_symm(b_mat):
        throw_error('wrongInput:b_mat',
                    'second argument must be a symmetric matrix')
    if a_mat.shape[0] != b_mat.shape[0]:
        throw_error('wrongInput',
                    'both matrices must be of the same dimension')

    u1_mat, s_vec, _ = np.linalg.svd(a_mat, full_matrices=True)
    u_mat = np.linalg.lstsq(
        sqrtm_pos(np.diag(s_vec), abs_tol).T, u1_mat.T, -1)[0].T
    u2_mat, _, _ = np.linalg.svd(u_mat.T @ b_mat @ u_mat)
    return u2_mat.T @ u_mat.T
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
Exemple #8
0
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
Exemple #9
0
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 rep_mat(self, shape_vec: Union[Iterable, np.ndarray]) -> np.ndarray:
     shape_vec = np.array(shape_vec)
     if not is_numeric(shape_vec):
         throw_error('wrongInput:shape_vec', 'size array should be numeric')
     shape_vec = try_treat_as_real(shape_vec)
     if shape_vec.size == 0 or shape_vec.size != np.max(shape_vec.shape):
         throw_error(
             'wrongInput:shape_vec',
             'size vector must have at least two elements and be not a matrix'
         )
     shape_vec = shape_vec.flatten()
     if not np.all(
             np.logical_and(shape_vec == np.fix(shape_vec),
                            shape_vec >= 0)):
         throw_error(
             'wrongInput:shape_vec',
             'size vector must contain non-negative integer values')
     n_elems = np.prod(shape_vec).flatten()[0]
     shape_vec = tuple(shape_vec)
     ell_arr = np.empty((n_elems, ), dtype=np.object)
     for i_elem in range(n_elems):
         ell_arr[i_elem] = self._get_single_copy()
     ell_arr = np.reshape(ell_arr, shape_vec)
     return ell_arr
Exemple #11
0
def quad_mat(q_mat: np.ndarray,
             x_vec: np.ndarray,
             c_vec: Union[int, float, np.ndarray] = 0.,
             mode: str = 'plain') -> float:

    if not is_numeric(q_mat):
        throw_error('wrongInput:q_mat', 'q_mat must be numeric')
    if not is_numeric(x_vec):
        throw_error('wrongInput:x_vec', 'x_vec must be numeric')
    if not is_numeric(c_vec):
        throw_error('wrongInput:c_vec', 'c_vec must be numeric')
    if mode.lower() not in ['plain', 'inv', 'invadv']:
        throw_error('wrongInput:mode', 'mode must be one of the next types: ' +
                    "'plain', 'inv', 'invadv'")

    if q_mat.ndim != 2:
        throw_error('wrongInput:q_mat', 'q_mat must be a matrix')

    q_matm_elems, q_matn_elems = q_mat.shape

    if q_matm_elems != q_matn_elems:
        throw_error('wrongInput:q_mat', 'q_mat must be square')

    if x_vec.ndim > 2:
        throw_error('wrongInput:x_vec', 'x_vec must be a vector')
    elif x_vec.ndim == 1:
        x_vec = np.expand_dims(x_vec, axis=0)

    x_vecm_elems, x_vecn_elems = x_vec.shape

    if x_vecm_elems > 1 and x_vecn_elems > 1:
        throw_error('wrongInput:x_vec', 'x_vec must be a vector')
    elif x_vecm_elems > 1:
        x_vec = x_vec.T
        x_vecn_elems = x_vec.shape[1]

    c_vec = np.array(c_vec, dtype=np.float64)
    if c_vec.size == 1 and np.all(c_vec.flatten()[0] == 0.):
        c_vec = np.zeros((1, x_vecn_elems), dtype=np.float64)
    elif c_vec.ndim > 2:
        throw_error('wrongInput:c_vec', 'c_vec must be a vector')
    elif c_vec.ndim <= 1:
        c_vec = np.reshape(c_vec, (1, c_vec.size))

    if x_vecn_elems != q_matn_elems:
        throw_error('wrongInput:q_mat:x_vec',
                    'Dimensions of q_mat and x_vec must be coordinated')

    c_vecm_elems, c_vecn_elems = c_vec.shape
    if (c_vecm_elems > 1) & (c_vecn_elems > 1):
        throw_error('wrongInput:c_vec', 'c_vec must be a vector')
    elif c_vecm_elems > 1:
        c_vec = c_vec.T
        c_vecn_elems = c_vec.shape[1]

    if c_vecn_elems != q_matn_elems:
        throw_error('wrongInput:q_mat:c_vec',
                    'Dimensions of q_mat and c_vec must be coordinated')

    if mode.lower() == 'plain':
        res = np.dot(x_vec - c_vec, q_mat @ (x_vec - c_vec).T)
    elif mode.lower() == 'invadv':
        res = np.dot(x_vec - c_vec, inv_mat(q_mat) @ (x_vec - c_vec).T)
    else:
        res = (x_vec - c_vec) @ np.linalg.lstsq(q_mat, (x_vec - c_vec).T, -1)[0]

    return res
            def comp_fun(x, y, comp_abs_tol: float,
                         comp_rel_tol: float) -> Tuple[bool, str]:
                comp_report_str = ''

                x_dtype = np.asarray(x).dtype.kind
                y_dtype = np.asarray(y).dtype.kind
                x_type = type(x)

                if x_type != type(y) or x_dtype != y_dtype:
                    comp_report_str = 'Different types'
                    return False, comp_report_str

                if is_numeric(x) and x_type != list:
                    x_arr = np.array(x)
                    y_arr = np.array(y)
                    x_shape_vec = x_arr.shape
                    y_shape_vec = y_arr.shape
                    if x_shape_vec != y_shape_vec:
                        comp_report_str = 'Different sizes (left: {}, right: {})'.format(
                            x_shape_vec, y_shape_vec)
                        return False, comp_report_str
                    if x_dtype in 'ui':
                        x_arr = np.array(x_arr, dtype=np.float)
                        y_arr = np.array(y_arr, dtype=np.float)
                    if x_dtype == 'fc':
                        if not np.array_equal(np.isnan(x_arr),
                                              np.isnan(y_arr)):
                            comp_report_str = 'Nans are on the different places'
                            return False, comp_report_str
                        if not np.array_equal(x_arr == -np.inf, y_arr
                                              == -np.inf):
                            comp_report_str = '-Infs are on the different places'
                            return False, comp_report_str
                        if not np.array_equal(x_arr == np.inf, y_arr
                                              == np.inf):
                            comp_report_str = '+Infs are on the different places'
                            return False, comp_report_str
                        is_comp_arr = np.isfinite(x_arr)
                    else:
                        is_comp_arr = np.ones(x_arr.shape, dtype=bool)
                    is_comp_eq, _, _, _, _, comp_report_str = abs_rel_compare(
                        x_arr[is_comp_arr], y_arr[is_comp_arr], comp_abs_tol,
                        comp_rel_tol, lambda z: np.abs(z))
                    if not is_comp_eq:
                        comp_report_str = 'Max. ' + comp_report_str
                        return False, comp_report_str
                elif x_type in [dict, list, np.ndarray]:
                    is_dict = x_type == dict
                    if not is_dict and x_type == np.ndarray and x.size > 0:
                        is_dict = type(x.flatten()[0]) == dict
                    if is_dict:
                        is_comp_eq, comp_report_str = dict_compare(
                            x, y, comp_abs_tol, comp_rel_tol)
                        if not is_comp_eq:
                            return False, comp_report_str
                    else:
                        n_comp_elems = len(x)
                        if n_comp_elems == 0:
                            return True, ''
                        is_comp_eq = True
                        for i_comp_elem in range(n_comp_elems):
                            is_comp_eq, comp_report_str = comp_fun(
                                x[i_comp_elem], y[i_comp_elem], comp_abs_tol,
                                comp_rel_tol)
                            if not is_comp_eq:
                                comp_report_str = '{' + str(
                                    i_comp_elem) + '}' + comp_report_str
                                break
                        if not is_comp_eq:
                            return False, comp_report_str
                elif x != y:
                    return False, 'values are different'
                return True, comp_report_str