def create_reduce(poly_list, Power, last_iteration=False, r_type='poly'): if last_iteration == False: """ matrix, matrix_terms = create_matrix(poly_list) rows_good, rows_trash, Q = utils.row_linear_dependencies(matrix) poly_list = get_polys_from_matrix(matrix, matrix_terms, rows_good, Power, r_type) """ matrix, matrix_terms = create_matrix(poly_list) print("Before: ", matrix.shape) matrix = utils.rrqr_reduce2(matrix) print("After: ", matrix.shape) matrix = clean_zeros_from_matrix(matrix) non_zero_rows = np.sum(np.abs(matrix), axis=1) != 0 matrix = matrix[non_zero_rows, :] #Only keeps the non_zero_polymonials #rows = get_good_rows(matrix, matrix_terms) poly_list = get_polys_from_matrix(matrix, matrix_terms, np.arange(matrix.shape[0]), Power, r_type) return poly_list else: matrix, matrix_terms = create_matrix(poly_list) print(matrix.shape) matrix = utils.rrqr_reduce2(matrix) matrix = clean_zeros_from_matrix(matrix) non_zero_rows = np.sum(np.abs(matrix), axis=1) != 0 matrix = matrix[non_zero_rows, :] #Only keeps the non_zero_polymonials matrix = triangular_solve(matrix) matrix = clean_zeros_from_matrix(matrix) rows = get_good_rows(matrix, matrix_terms) poly_list = get_polys_from_matrix(matrix, matrix_terms, rows, Power, r_type) return poly_list
def full_cheb_approximate(f, a, b, deg, tol=1.e-8): """Gives the full chebyshev approximation and checks if it's good enough. Called recursively. Parameters ---------- f : function The function we approximate. a : numpy array The lower bound on the interval. b : numpy array The upper bound on the interval. deg : int The degree to approximate with. tol : float How small the high degree terms must be to consider the approximation accurate. Returns ------- coeff : numpy array The coefficient array of the interpolation. If it can't get a good approximation and needs to subdivide, returns None. """ dim = len(a) degs = np.array([deg] * dim) coeff = interval_approximate_nd(f, a, b, degs) coeff2 = interval_approximate_nd(f, a, b, degs * 2) coeff2[slice_top(coeff)] -= coeff clean_zeros_from_matrix(coeff2, 1.e-16) if np.sum(np.abs(coeff2)) > tol: return None else: return coeff
def triangular_cheb_approx(poly, hyperplane, inv_rotation, dim, deg, accuracy=1.e-10): '''Gives an n-dimensional triangular interpolation of polynomial on a given hyperplace after a given rotation. It calls the normal nD-interpolation, but then cuts off the small non-triangular part to make it triangular. Parameters ---------- poly : Polynomial This is one of the given polynomials in projective space. So it must be projected into proejective space first. hyperplace : int Which hyperplance we want to approximate in. Between 0 and n inclusive when the original polynomials are n-1 dimensional. So the projective space polynomials are n dimensional. n is the original space. inv_rotation : numpy array The inverse of the rotation of the projective space. dim : int The dimension of the chebysehv polynomial we want. deg : int The degree of the chebyshev polynomial we want. Returns ------- triangular_cheb_approx : MultiCheb The chebyshev polynomial we want. ''' cheb = cheb_interpND(poly, hyperplane, inv_rotation, dim, deg) clean_zeros_from_matrix(cheb) return MultiCheb(cheb)
def matrixReduce(matrix, triangular_solve=False, global_accuracy=1.e-10): ''' Reduces the matrix into row echelon form, so each row has a unique leading term. If triangular_solve is True it is reduces to reduced row echelon form, so everything above the leading terms is 0. Parameters ---------- matrix : (M,N) ndarray The matrix of interest. triangular_solve : bool Defaults to False. If True then triangular solve is preformed. global_accuracy : float Defaults to 1.e-10. What is determined to be zero when searching for the pivot columns. Returns ------- matrix : (M,N) ndarray The reduced matrix. It should look like this if triangluar_solve is False. a - - - - - - - 0 b - - - - - - 0 0 0 c - - - - 0 0 0 0 d - - - 0 0 0 0 0 0 0 e If triangular solve is True it will look like this. a 0 - 0 0 - - 0 0 b - 0 0 - - 0 0 0 0 c 0 - - 0 0 0 0 0 d - - 0 0 0 0 0 0 0 0 e ''' independentRows, dependentRows, Q = utils.row_linear_dependencies( matrix, accuracy=global_accuracy) matrix = matrix[independentRows] pivotColumnMatrix = findPivotColumns(matrix, global_accuracy=global_accuracy) pivotColumns = list(np.where(pivotColumnMatrix == 1)[1]) otherColumns = list() for i in range(matrix.shape[1]): if i not in pivotColumns: otherColumns.append(i) matrix = matrix[:, pivotColumns + otherColumns] Q, R = qr(matrix) if triangular_solve: R = clean_zeros_from_matrix(R) X = solve_triangular(R[:, :R.shape[0]], R[:, R.shape[0]:]) reduced = np.hstack((np.eye(X.shape[0]), X)) else: reduced = R matrix = reduced[:, utils.inverse_P(pivotColumns + otherColumns)] matrix = clean_zeros_from_matrix(matrix) return matrix
def row_echelon(matrix, accuracy=1.e-10): '''Reduces the matrix to row echelon form and removes all zero rows. Parameters ---------- matrix : (M,N) ndarray The matrix of interest. Returns ------- reduced_matrix : (M,N) ndarray The matrix in row echelon form with all zero rows removed. ''' independent_rows, dependent_rows, Q = utils.row_linear_dependencies( matrix, accuracy=accuracy) full_rank_matrix = matrix[independent_rows] reduced_matrix = utils.rrqr_reduce2(full_rank_matrix) reduced_matrix = utils.clean_zeros_from_matrix(reduced_matrix) non_zero_rows = np.sum(abs(reduced_matrix), axis=1) != 0 if np.sum(non_zero_rows) != reduced_matrix.shape[0]: warnings.warn("Full rank matrix has zero rows.", InstabilityWarning) reduced_matrix = reduced_matrix[ non_zero_rows, :] #Only keeps the non-zero polymonials return reduced_matrix
def Macaulay(initial_poly_list, global_accuracy=1.e-10): """ Accepts a list of polynomials and use them to construct a Macaulay matrix. parameters -------- initial_poly_list: list Polynomials for Macaulay construction. global_accuracy : float Round-off parameter: values within global_accuracy of zero are rounded to zero. Defaults to 1e-10. Returns ------- final_polys : list Reduced Macaulay matrix that can be passed into the root finder. """ Power = is_power(initial_poly_list) poly_coeff_list = [] degree = find_degree(initial_poly_list) for i in initial_poly_list: poly_coeff_list = add_polys(degree, i, poly_coeff_list) matrix, matrix_terms = create_matrix(poly_coeff_list) plt.matshow(matrix) plt.show() #rrqr_reduce2 and rrqr_reduce same pretty matched on stability, though I feel like 2 should be better. matrix = utils.rrqr_reduce2(matrix, global_accuracy=global_accuracy) # here matrix = clean_zeros_from_matrix(matrix) non_zero_rows = np.sum(np.abs(matrix), axis=1) != 0 matrix = matrix[non_zero_rows, :] #Only keeps the non_zero_polymonials matrix = triangular_solve(matrix) matrix = clean_zeros_from_matrix(matrix) #The other reduction option. I thought it would be really stable but seems to be the worst of the three. #matrix = matrixReduce(matrix, triangular_solve = True, global_accuracy = global_accuracy) rows = get_good_rows(matrix, matrix_terms) final_polys = get_polys_from_matrix(matrix, matrix_terms, rows, Power) return final_polys