def apply(self, expr, form, evaluation): 'CoefficientList[expr_, form_]' vars = [form] if not form.has_form('List', None) else [v for v in form.leaves] # check form is not a variable for v in vars: if not(isinstance(v, Symbol)) and not(isinstance(v, Expression)): return evaluation.message('CoefficientList', 'ivar', v) # special cases for expr and form e_null = expr == Symbol('Null') f_null = form == Symbol('Null') if expr == Integer(0): return Expression('List') elif e_null and f_null: return Expression('List', Integer(0), Integer(0)) elif e_null and not f_null: return Expression('List', Symbol('Null')) elif f_null: return Expression('List', expr) elif form.has_form('List', 0): return expr sympy_expr = expr.to_sympy() sympy_vars = [v.to_sympy() for v in vars] if not sympy_expr.is_polynomial(*[x for x in sympy_vars]): return evaluation.message('CoefficientList', 'poly', expr) try: sympy_poly, sympy_opt = sympy.poly_from_expr(sympy_expr, sympy_vars) dimensions = [sympy_poly.degree(x) if x in sympy_poly.gens else 0 for x in sympy_vars] # single & multiple variables cases if not form.has_form('List', None): return Expression('List', *[_coefficient(self.__class__.__name__,expr, form, Integer(n), evaluation) for n in range(dimensions[0]+1)]) elif form.has_form('List', 1): form = form.leaves[0] return Expression('List', *[_coefficient(self.__class__.__name__, expr, form, Integer(n), evaluation) for n in range(dimensions[0]+1)]) else: def _nth(poly, dims, exponents): if not dims: return from_sympy(poly.nth(*[i for i in exponents])) result = Expression('List') first_dim = dims[0] for i in range(first_dim+1): exponents.append(i) subs = _nth(poly, dims[1:], exponents) result.leaves.append(subs) exponents.pop() return result return _nth(sympy_poly, dimensions, []) except sympy.PolificationFailed: return evaluation.message('CoefficientList', 'poly', expr)
def get_Wilkinsons_coeffs(): x = sym.Symbol('x') W = 1 for i in range(1, 21): W *= (x - i) P, d = sym.poly_from_expr(W.expand()) return np.array(P.all_coeffs())
def _get_leading(cost): """Get the leading terms in a cost polynomial.""" symbs = tuple(cost.atoms(Symbol)) poly, _ = poly_from_expr(cost, *symbs) terms = poly.terms() leading_deg = max(sum(i) for i, _ in terms) leading_cost = sum(coeff * prod_(i**j for i, j in zip(symbs, degs)) for degs, coeff in terms if sum(degs) == leading_deg) return leading_cost
def prob2(): """Randomly perturb the coefficients of the Wilkinson polynomial by replacing each coefficient c_i with c_i*r_i, where r_i is drawn from a normal distribution centered at 1 with standard deviation 1e-10. Plot the roots of 100 such experiments in a single figure, along with the roots of the unperturbed polynomial w(x). Returns: (float) The average absolute condition number. (float) The average relative condition number. """ #initialize standard roots w_roots = np.arange(1, 21) # Get the exact Wilkinson polynomial coefficients using SymPy. x, i = sy.symbols('x i') w = sy.poly_from_expr(sy.product(x - i, (i, 1, 20)))[0] w_coeffs = np.array(w.all_coeffs()) #initialize new_roots = [] perturbations = [] #run 100 pertubations checking roots at each step for _ in range(100): p = np.random.normal(1, 1e-10, len(w_coeffs)) perturbations.append(p) new_coeffs = w_coeffs * p # Use NumPy to compute the roots of the perturbed polynomial. new_roots.append(np.roots(np.poly1d(new_coeffs))) #PLOT EVERYTHING plt.scatter(np.real(new_roots), np.imag(new_roots), marker='$.$', s=2.3, label='perturbed') plt.scatter(w_roots, np.zeros_like(w_roots), marker='o', label='unperturbed') plt.legend() plt.title("True wilkinson polynomial roots and slightly perturbed roots") plt.show() #Calculate the conditioning numbers with inf norm k = la.norm(new_roots - w_roots, np.inf) / la.norm(perturbations, np.inf) return k, k * la.norm(w_coeffs, np.inf) / la.norm(w_roots, np.inf)
def prob2(): """Randomly perturb the coefficients of the Wilkinson polynomial by replacing each coefficient c_i with c_i*r_i, where r_i is drawn from a normal distribution centered at 1 with standard deviation 1e-10. Plot the roots of 100 such experiments in a single figure, along with the roots of the unperturbed polynomial w(x). Returns: (float) The average absolute condition number. (float) The average relative condition number. """ w_roots = np.arange(1, 21) # Get the exact Wilkinson polynomial coefficients using SymPy. x, i = sy.symbols('x i') w = sy.poly_from_expr(sy.product(x-i, (i, 1, 20)))[0] w_coeffs = np.array(w.all_coeffs()) new_r = np.array([]) #the absolute condition number b = [] #the relative condition number c = [] for j in range(100): r = np.random.normal(1,1e-10, size =21) new_coeffs = w_coeffs*r new_roots = np.roots(np.poly1d(new_coeffs)) new_r = np.concatenate([new_r,new_roots]) # Sort the roots to ensure that they are in the same order. w_roots = np.sort(w_roots) new_roots = np.sort(new_roots) # Estimate the absolute condition number in the infinity norm. k = la.norm(new_roots - w_roots, np.inf) / la.norm(r, np.inf) b.append(k) # Estimate the relative condition number in the infinity norm. c.append(k * la.norm(w_coeffs, np.inf) / la.norm(w_roots, np.inf)) plt.plot(new_r.real, new_r.imag, '.', markersize = 1, label = "Perturbed") plt.plot(w_roots.real, w_roots.imag, 'b.', markersize = 10, label = "Original") plt.legend() plt.xlabel("Real Axis") plt.ylabel("Imaginary Axis") plt.title("Wilkinson polynomial") plt.show() return np.mean(b), np.mean(c)
def prob2(): """Randomly perturb the coefficients of the Wilkinson polynomial by replacing each coefficient c_i with c_i*r_i, where r_i is drawn from a normal distribution centered at 1 with standard deviation 1e-10. Plot the roots of 100 such experiments in a single figure, along with the roots of the unperturbed polynomial w(x). Returns: (float) The average absolute condition number. (float) The average relative condition number. """ w_roots = np.arange(1, 21) # Get the exact Wilkinson polynomial coefficients using SymPy. x, i = sy.symbols('x i') w = sy.poly_from_expr(sy.product(x - i, (i, 1, 20)))[0] w_coeffs = np.array(w.all_coeffs()) raise NotImplementedError("Problem 2 Incomplete")
def prob2(): """Randomly perturb the coefficients of the Wilkinson polynomial by replacing each coefficient c_i with c_i*r_i, where r_i is drawn from a normal distribution centered at 1 with standard deviation 1e-10. Plot the roots of 100 such experiments in a single figure, along with the roots of the unperturbed polynomial w(x). Returns: (float) The average absolute condition number. (float) The average relative condition number. """ w_roots = np.arange(1, 21) # Get the exact Wilkinson polynomial coefficients using SymPy. x, i = sy.symbols('x i') w = sy.poly_from_expr(sy.product(x-i, (i, 1, 20)))[0] w_coeffs = np.array(w.all_coeffs()) abs_cond = [] rel_cond = [] # First, plot the Wilkinson roots. plt.ion() plt.scatter(np.real(w_roots), np.imag(w_roots), label="Original") for i in range(100): # Perturb each of the coefficients r = np.random.normal(1, 1e-10, len(w_coeffs)) new_coeffs = w_coeffs * r new_roots = np.sort(np.roots(np.poly1d(new_coeffs))) # Plot each of the perturbed results if i == 0: plt.plot(np.real(new_roots), np.imag(new_roots), ',', c='k', label="Perturbed") else: plt.plot(np.real(new_roots), np.imag(new_roots), ',', c='k') # Store the absolute and relative condition numbers k = la.norm(new_roots - w_roots, np.inf) / la.norm(r, np.inf) abs_cond.append(k) rel_k = k * la.norm(w_coeffs, np.inf) / la.norm(w_roots, np.inf) rel_cond.append(rel_k) plt.xlabel("Real Axis") plt.ylabel("Imaginary Axis") plt.legend() plt.show() # Return the average of the condition numbers return np.mean(abs_cond), np.mean(rel_cond)
def c2(n): roots = np.arange(1, n) x, i = symbols("x i") w = poly_from_expr(product(x - i, (i, 1, n - 1)))[0] coeffs = np.array(w.all_coeffs()) plt.figure(figsize=(10, 7)) plt.plot(roots, np.zeros(n - 1), "o", label="Original") for i in range(100): r = np.random.normal(loc=1, scale=1e-10, size=n) coeffs1 = coeffs * r roots1 = np.roots(np.poly1d(coeffs1)) roots = np.sort(roots) roots1 = np.sort(roots1) plt.scatter(roots1.real, roots1.imag, marker=".", c="k", s=2) print( f"The absolute condition number in the infinity norm is {norm(roots1 - roots, np.inf) / norm(r):.2f}" ) print( f"The relative condition number in the infinity norm is {norm(roots, np.inf) / norm(roots1, np.inf):.2f}" ) plt.xlabel("Real") plt.ylabel("Imaginary") plt.legend(["Original", "Perturbed"], loc="upper left") plt.show()
A = np.random.rand(6, 6) print("\nmy function:", pb1(A), "\n") print("numpy:", np.linalg.cond(A)) ###### EX 2 ################ import sympy as sy from matplotlib import pyplot as plt w_roots = np.arange(1, 21) x, i = sy.symbols('x i') w = sy.poly_from_expr(sy.product(x - i, (i, 1, 20)))[0] w_coeffs = np.array(w.all_coeffs()) h = np.random.normal(1, 1e-10, 21) new_coeffs = w_coeffs * h new_roots = np.roots(np.poly1d(new_coeffs)) plt.scatter(np.real(w_roots), np.imag(w_roots)) plt.scatter(np.real(new_roots), np.imag(new_roots)) #### EX 3 ###################### def pb3(A): lamb = scipy.linalg.eigvals(A)