def test_mon_mult_random(): np.random.seed(988) #test with random matrices possible_dim = np.random.randint(1,5, (1,10)) dim = possible_dim[0, np.random.randint(1,9)] shape = list() for i in range(dim): shape.append(np.random.randint(2,4)) matrix1 = np.random.randint(1,11,(shape)) M1 = MultiPower(matrix1) shape2 = list() for i in range(dim): shape2.append(np.random.randint(2,4)) matrix2 = np.ones(shape2) M2 = MultiPower(matrix2) M3 = M1*M2 for index, i in np.ndenumerate(M2.coeff): if sum(index) == 0: M4 = MultiPower.mon_mult(M1, index) else: M4 = M4 + MultiPower.mon_mult(M1, index) if M3.shape != M4.shape: new_M3_coeff, new_M4_coeff = utils.match_size(M3.coeff,M4.coeff) else: new_M3_coeff, new_M4_coeff = M3.coeff, M4.coeff assert np.allclose(new_M3_coeff, new_M4_coeff)
def test_add(): a1 = np.arange(27).reshape((3,3,3)) Test2 = MultiPower(a1) a2 = np.ones((3,3,3)) Test3 = MultiPower(a2) addTest = Test2 + Test3 assert (addTest.coeff == (Test2.coeff + Test3.coeff)).all()
def test_mult(): test1 = np.array([[0,1],[2,1]]) test2 = np.array([[2,2],[3,0]]) p1 = MultiPower(test1) p2 = MultiPower(test2) new_poly = p1*p2 truth = MultiPower(np.array([[0, 2, 2],[4,9,2],[6,3,0]])) assert np.allclose(new_poly.coeff, truth.coeff)
def test_evaluate_grid1(): #Evaluate 2 + yx^2 + 3y^2 - xy on grid (0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), (2,2) poly = MultiPower(np.array([[2,0,3], [0,-1,0], [0,1,0]])) x = np.arange(3) xy = np.column_stack([x,x]) sol = np.array([[2,5,14], [2,5,14], [2,7,18]]) assert(np.all(poly.evaluate_grid(xy) == sol))
def test_roots_at_inf(): g = MultiPower(np.array([[0, 0, 1], [-1, 0, 0]]).T) #f(x,y) = x^2 - y assert roots_at_inf(g) == [(0, 1)] f = MultiPower(np.array([[0, 1]])) #f(x,y) = y g = MultiPower(np.array([[0, 0, -1], [1, 0, 0]])) #f(x,y) = x - y^2 assert roots_at_inf(f) == [(1, 0)] assert roots_at_inf(g) == [(1, 0)] f = MultiPower(np.array([[5, 6, 2], [9, 3, 0], [1, 0, 0]])) assert roots_at_inf(f) == [(-2, 1), (-1, 1)]
def test_sorted_polys_coeff(): A = MultiPower(np.array([[2,0,-3,0,0], [0,1,0,0,0], [-2,0,0,0,0], [0,0,4,0,0], [0,0,0,0,-2]])) B = MultiPower(np.array([[3,0,-5,0,0,4,2,-6,3,-6], [-2,0,-1,1,-1,4,2,-6,-5,-2], [-1,3,2,-2,0,4,-1,-2,-4,6], [4,2,5,9,0,3,2,-1,-3,-3], [3,-3,-5,-2,0,4,-2,2,1,-6]])) assert([A,B] == ut.sorted_polys_coeff([A,B])) C = MultiPower(np.array([[1]])) assert([C,A,B] == ut.sorted_polys_coeff([A,B,C]))
def getPoly(deg, power): ''' A helper function for testing. Returns a random 1D polynomial of the given degree. power is a boolean indicating whether or not the polynomial should be MultiPower. ''' coeff = np.random.random_sample(deg + 1) if power: return MultiPower(coeff) else: return MultiCheb(coeff)
def test_common_root_at_inf(): f = MultiPower(np.array([[0, 1]])) #f(x,y) = y g = MultiPower(np.array([[0, 0, -1], [1, 0, 0]])) #f(x,y) = x - y^2 #assert common_root_at_inf([f,g]) == True f = MultiPower(np.array([[0, 1]])) #f(x,y) = y g = MultiPower(np.array([[0, 0, -1], [1, 0, 0]]).T) #f(x,y) = x^2 - y #assert common_root_at_inf([f,g]) == False #from ./Easy/dpdx-dpdy_ex016.mat, which is a dupliate of ./Easy/dpdx-dpdy_ex007.mat and almost the same as ./Easy/dpdx-dpdy_ex008.mat f = MultiPower( np.array([[-0.21875, 0., 1.3125, 0., -1.09375, 0., 0.21875], [0., -2.625, 0., 4.375, 0., -1.3125, 0.], [1.3125, 0., -6.5625, 0., 3.28125, 0., 0.], [0., 4.375, 0., -4.375, 0., 0., 0.], [-1.09375, 0., 3.28125, 0., 0., 0., 0.], [0., -1.3125, 0., 0., 0., 0., 0.], [0.21875, 0., 0., 0., 0., 0., 0.]])) g = MultiPower( np.array([[0., -0.65625, 0., 1.09375, 0., -0.328125], [0.65625, 0., -3.28125, 0., 1.640625, 0.], [0., 3.28125, 0., -3.28125, 0., 0.], [-1.09375, 0., 3.28125, 0., 0., 0.], [0., -1.640625, 0., 0., 0., 0.], [0.328125, 0., 0., 0., 0., 0.]])) assert common_root_at_inf([f, g]) == True #from ./Easy/dpdx-dpdy_C1.mat f = MultiPower( np.array([[0., 1., -1.5, -0.5, -1.875, 0., 0.875], [0., -3., 1.5, 1.5, -0.625, 0., 0.], [-0.125, 2.5, 0.375, -1.5, 1.25, 0., 0.], [0.125, 0.5, -0.75, 0.5, 0., 0., 0.], [0.125, -1.5, 0.375, 0., 0., 0., 0.], [-0.125, 0.5, 0., 0., 0., 0., 0.]])) g = MultiPower( np.array([[0., 0.25, 9.], [0., 0., 0.], [-0.75, -1., 0.], [0, 0, 0]])) assert common_root_at_inf([f, g]) == False f = MultiPower(np.array([[0., 0., 0., 1.]])) g = MultiPower(np.array([[0., 0., 0., 0., 1.25]])) assert common_root_at_inf([f, g]) == True
def test_mon_mult(): """ Tests monomial multiplication using normal polynomial multiplication. """ np.random.seed(4) #Simple 2D test cases cheb1 = MultiCheb(np.array([[0, 0, 0], [0, 0, 0], [0, 0, 1]])) mon1 = (1, 1) result1 = cheb1.mon_mult(mon1) truth1 = np.array([[0, 0, 0, 0], [0, 0.25, 0, 0.25], [0, 0, 0, 0], [0, 0.25, 0, 0.25]]) assert np.allclose(result1.coeff, truth1) #test with random matrices cheb2 = np.random.randint(-9, 9, (4, 4)) C1 = MultiCheb(cheb2) C2 = cheb2poly(C1) C3 = MultiCheb.mon_mult(C1, (1, 1)) C4 = MultiPower.mon_mult(C2, (1, 1)) C5 = poly2cheb(C4) assert np.allclose(C3.coeff, C5.coeff) # test results of chebyshev mult compared to power multiplication cheb3 = np.random.randn(5, 4) c1 = MultiCheb(cheb3) c2 = MultiCheb(np.ones((4, 2))) for index, i in np.ndenumerate(c2.coeff): if sum(index) == 0: c3 = c1.mon_mult(index) else: c3 = c3 + c1.mon_mult(index) p1 = cheb2poly(c1) p2 = cheb2poly(c2) p3 = p1 * p2 p4 = cheb2poly(c3) assert np.allclose(p3.coeff, p4.coeff) # test results of chebyshev mult compared to power multiplication in 3D cheb4 = np.random.randn(3, 3, 3) a1 = MultiCheb(cheb4) a2 = MultiCheb(np.ones((3, 3, 3))) for index, i in np.ndenumerate(a2.coeff): if sum(index) == 0: a3 = a1.mon_mult(index) else: a3 = a3 + a1.mon_mult(index) q1 = cheb2poly(a1) q2 = cheb2poly(a2) q3 = q1 * q2 q4 = cheb2poly(a3) assert np.allclose(q3.coeff, q4.coeff)
def test_evaluate(): # Evaluate .5xyz + 2x + y + z at (4,2,1) poly = MultiPower(np.array([[[0,1,0], [1,0,0], [0,0,0]], [[2,0,0], [0,.5,0], [0,0,0]]])) assert(poly((4,2,1)) == 15) assert(np.allclose(poly([[4,2,1],[1,1,2]]), [15,6]))
def test_evaluate2(): # Evaluate -.5x^2y + 2xy^2 - 3z^2 + yz at (7.4,2.33,.25) poly = MultiPower(np.array([[[0,0,-3], [0,1,0], [0,0,0]], [[0,0,0], [0,0,0], [2,0,0]], [[0,0,0], [-.5,0,0], [0,0,0]]])) assert(np.isclose(poly((7.4, 2.33, .25)), 16.94732))
def test_evaluate_grid2(): #Evaluate zy^2 + 3z^2 + 3x + zx^2y^2 on grid {0, 1, 2}X{0, 1, 2}X{0, 1, 2} poly = MultiPower(np.array([[[0,0,3], [0,0,0], [0,1,0]], [[3,0,0], [0,0,0], [0,0,0]], [[0,0,0], [0,0,0], [0,1,0]]])) x = np.arange(3) xyz = np.column_stack([x,x,x]) sol = np.array([[[0,3,12], [0,4,14], [0,7,20]], [[3,6,15], [3,8,19], [3,14,31]], [[6,9,18], [6,14,28], [6,29,58]]]) assert(np.all(poly.evaluate_grid(xyz) == sol))
def polyqeps(Q, eps): dim = Q.shape[0] polys = [] for i in range(dim): coeff = np.zeros([3] * dim) spot = [0] * dim for j in range(dim): spot[j] = 1 coeff[tuple(spot)] = Q[i, j] * eps spot[j] = 0 spot[i] = 2 coeff[tuple(spot)] = 1 polys.append(MultiPower(coeff)) return polys
def spolyqeps(Q, eps): dim = Q.shape[0] polys = [] const = (np.eye(dim) - eps * Q).sum(axis=1) for i in range(dim): coeff = np.zeros([3] * dim) spot = [0] * dim coeff[tuple(spot)] = const[i] for j in range(dim): spot[j] = 1 coeff[tuple(spot)] = Q[i, j] * eps if i == j: coeff[tuple(spot)] -= 2 spot[j] = 0 spot[i] = 2 coeff[tuple(spot)] = 1 polys.append(MultiPower(coeff)) return polys
def test_poly2cheb(): np.random.seed(32) P = MultiPower(np.array([[1, -1, -2], [0, 0, 0], [-2, 2, 4]])) c_new = poly2cheb(P) truth = np.array(np.array([[0, 0, 0], [0, 0, 0], [0, 1, 1]])) assert np.allclose(truth, c_new.coeff) #test2 p3 = MultiPower( np.array([[5, -19, -4, 20], [7, -3, 2, 8], [-12, -2, 24, 16]])) p4 = poly2cheb(p3) truth2 = np.array([[3, 1, 4, 7], [8, 3, 1, 2], [0, 5, 6, 2]]) assert np.allclose(truth2, p4.coeff) #Test3 p5 = MultiPower( np.array([[0, -9, 12, 12, -16], [2, -6, 0, 8, 0], [12, -4, -108, 8, 128]])) p6 = poly2cheb(p5) truth3 = np.array([[3, 1, 3, 4, 6], [2, 0, 0, 2, 0], [3, 1, 5, 1, 8]]) assert np.allclose(truth3, p6.coeff) #test4 Random 1-D matrix2 = np.random.randint(1, 100, np.random.randint(1, 10)) p7 = MultiPower(matrix2) p8 = poly2cheb(p7) p9 = cheb2poly(p8) assert np.allclose(p7.coeff, p9.coeff) #test5 Random 2D shape = list() for i in range(2): shape.append(np.random.randint(2, 10)) matrix1 = np.random.randint(1, 50, (shape)) p10 = MultiPower(matrix1) p11 = poly2cheb(p10) p12 = cheb2poly(p11) assert np.allclose(p10.coeff, p12.coeff) #test6 Random 4D shape = list() for i in range(4): shape.append(np.random.randint(2, 10)) matrix1 = np.random.randint(1, 50, (shape)) p13 = MultiPower(matrix1) p14 = poly2cheb(p13) p15 = cheb2poly(p14) assert np.allclose(p13.coeff, p15.coeff)
def _random_poly(_type, dim): ''' Generates a random linear polynomial that has the form c_1x_1 + c_2x_2 + ... + c_nx_n where n = dim and each c_i is a randomly chosen integer between 0 and 1000. Parameters ---------- _type : string Type of Polynomial to generate. "MultiCheb" or "MultiPower". dim : int Degree of polynomial to generate (?). Returns ------- Polynomial Randomly generated Polynomial. ''' _vars = get_var_list(dim) random_poly_shape = [2 for i in range(dim)] # random_poly_coeff = np.zeros(tuple(random_poly_shape), dtype=int) # for var in _vars: # random_poly_coeff[var] = np.random.randint(1000) random_poly_coeff = np.zeros(tuple(random_poly_shape), dtype=float) #np.random.seed(42) coeffs = np.random.rand(dim) coeffs /= np.linalg.norm(coeffs) for i, var in enumerate(_vars): random_poly_coeff[var] = coeffs[i] if _type == 'MultiCheb': return MultiCheb(random_poly_coeff), _vars else: return MultiPower(random_poly_coeff), _vars
def test_sorted_polys_monomial(): A = MultiPower(np.array([[3,0,-5,0,0,4,2,-6,3,-6], [-2,0,-1,1,-1,4,2,-6,-5,-2], [-1,3,2,-2,0,4,-1,-2,-4,6], [4,2,5,9,0,3,2,-1,-3,-3], [3,-3,-5,-2,0,4,-2,2,1,-6]])) x = sorted_polys_monomial([A]) assert(A == x[0]) B = MultiPower(np.array([[2,0,-3,0,0], [0,1,0,0,0], [-2,0,0,0,0], [0,0,4,0,0], [0,0,0,0,-2]])) assert(list((B,A)) == sorted_polys_monomial([B,A])) C = MultiPower(np.array([[0,0,-3,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,4,0,0], [0,0,0,0,-2]])) assert(list((C,B,A)) == sorted_polys_monomial([A,B,C])) D = MultiPower(np.array([[2,0,-3,0,0], [0,1,0,0,0], [-2,0,2,0,0], [0,0,4,0,0], [0,0,0,0,-2]])) assert(list((C,B,D,A)) == sorted_polys_monomial([B,D,C,A])) E = MultiPower(np.array([[3,0,-5,0,0,4,2,-6,3,-6], [-2,0,-1,1,-1,4,2,-6,-5,-2], [-1,3,2,-2,0,4,-1,-2,-4,6], [4,2,5,9,0,3,2,-1,-3,-3], [3,-3,-5,-2,2,4,-2,2,1,-6]])) assert(list((C,B,D,A,E)) == sorted_polys_monomial([B,D,E,C,A])) F = MultiPower(np.array([[3,0,-5,0,0,0,2,-6,3,-6], [-2,0,-1,1,-1,4,2,-6,-5,-2], [-1,3,2,-2,0,4,-1,-2,-4,6], [4,2,5,9,0,3,2,-1,-3,-3], [3,-3,-5,-2,0,4,-2,2,1,-6]])) assert(list((C,B,D,F,A,E)) == sorted_polys_monomial([F,B,D,E,C,A]))
def test_mon_mult(): """ Tests monomial multiplication using normal polynomial multiplication. """ mon = (1,2) Poly = MultiPower(np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])) mon_matr = MultiPower(np.array([[0,0,0,0],[0,0,1,0],[0,0,0,0],[0,0,0,0]])) P1 = mon_matr*Poly P2 = MultiPower.mon_mult(Poly, mon) mon2 = (0,1,1) Poly2 = MultiPower(np.arange(1,9).reshape(2,2,2)) mon_matr2 = MultiPower(np.array([[[0,0],[0,1]],[[0,0],[0,0]]])) T1 = mon_matr2*Poly2 T2 = MultiPower.mon_mult(Poly2, mon2) assert np.allclose(P1.coeff, P2.coeff, atol = 1.0e-10) assert np.allclose(T1.coeff, T2.coeff, atol = 1.0e-10)
def run_one_dimension(args, radius, eigvals): num_points = args.num_points eps = args.eps power = args.power real = args.real by_coeffs = args.coeffs root_pts = {} residuals = {} if by_coeffs: coeffs = (np.random.random(num_points + 1) * 2 - 1) * radius powerpoly = MultiPower(coeffs) chebpoly = MultiCheb(coeffs) else: r = np.sqrt(np.random.random(num_points)) * radius + eps angles = 2 * np.pi * np.random.random(num_points) if power and not real: roots = r * np.exp(angles * 1j) else: roots = 2 * r - radius root_pts = {'roots': roots} powerpoly = MultiPower(polyfromroots(roots)) chebpoly = MultiCheb(chebfromroots(roots)) n = 1000 x = np.linspace(-1, 1, n) X, Y = np.meshgrid(x, 1j * x) for solver in all_solvers: if isinstance(solver, OneDSolver): if (solver.basis == 'cheb' and args.cheb) and ((not eigvals) or solver.eigvals): name = str(solver) root_pts[name] = solver(chebpoly, eigvals) residuals[name] = maximal_residual(chebpoly, root_pts[name]) if (solver.basis == 'power' and args.power) and ((not eigvals) or solver.eigvals): name = str(solver) root_pts[name] = solver(powerpoly, eigvals) residuals[name] = maximal_residual(powerpoly, root_pts[name]) if args.hist: evaluations = {} for k, v in root_pts.items(): if k == 'roots': continue poly = powerpoly if 'power' in k else chebpoly evaluations[k] = np.abs(poly(root_pts[k])) ncols = len(evaluations) fig, ax = plt.subplots(1, ncols, sharey=True, figsize=(12, 4)) minimal = -20 maximal = 1 for i, (k, v) in enumerate(evaluations.items()): ax[i].hist(np.clip(np.log10(v), minimal, maximal), range=(minimal, maximal), bins=40) ax[i].set_xlabel(r'$log_{10}(p(r_i))$') ax[i].set_title(k) plt.suptitle("Eigenvalues" if eigvals else "Eigenvectors") plt.show() return root_pts, residuals
def test_makePolyCoeffMatrix(): A = MultiPower('1') B = MultiPower(np.array([1])) assert (A.coeff==B.coeff).all() A = MultiPower('2x0+x1+x0*x1') B = MultiPower(np.array([[0,2],[1,1]])) assert (A.coeff==B.coeff).all() A = MultiPower('-4.7x0*x1+2x1+5x0+-3') B = MultiPower(np.array([[-3,5],[2,-4.7]])) assert (A.coeff==B.coeff).all() A = MultiPower('x0^2+-x1^2') B = MultiPower(np.array([[0,0,1],[0,0,0],[-1,0,0]])) assert (A.coeff==B.coeff).all() A = MultiPower('x0+2x1+3x2+4x3') B = MultiPower(np.array( [[[[0,1],[2,0]], [[3,0],[0,0]]], [[[4,0],[0,0]], [[0,0],[0,0]]]])) assert (A.coeff==B.coeff).all() A = MultiPower('1+x0') B = MultiPower('1+x1') A1 = MultiPower(np.array([1,1])) B1 = MultiPower(np.array([[1],[1]])) assert (A.coeff==A1.coeff).all() and (B.coeff==B1.coeff).all()
def test_paper_example(): #Power form of the polys p1 = MultiPower(np.array([[1, -4, 0], [0, 3, 0], [1, 0, 0]])) #y^2 + 3xy - 4x +1 p2 = MultiPower(np.array([[3, 0, -2], [6, -6, 0], [0, 0, 0]])) #-6xy -2x^2 + 6y +3 #Cheb form of the polys c1 = MultiCheb(np.array([[2, 0, -1], [6, -6, 0], [0, 0, 0]])) #p1 in Cheb form c2 = MultiCheb(np.array([[1.5, -4, 0], [0, 3, 0], [.5, 0, 0]])) #p2 in Cheb form right_number_of_roots = 4 #~ ~ ~ Power Form, Mx Matrix ~ ~ ~ power_mult_roots = pr.solve([p1, p2], MSmatrix=1) assert len(power_mult_roots) == right_number_of_roots for root in power_mult_roots: assert np.isclose(0, p1(root), atol=1.e-8) assert np.isclose(0, p2(root), atol=1.e-8) #~ ~ ~ Cheb Form, Mx Matrix ~ ~ ~ cheb_mult_roots = pr.solve([c1, c2], MSmatrix=1) assert len(cheb_mult_roots) == right_number_of_roots for root in cheb_mult_roots: assert np.isclose(0, c1(root), atol=1.e-8) assert np.isclose(0, c1(root), atol=1.e-8) #~ ~ ~ Power Form, My Matrix ~ ~ ~ power_multR_roots = pr.solve([p1, p2], MSmatrix=2) assert len(power_multR_roots) == right_number_of_roots for root in power_multR_roots: assert np.isclose(0, p1(root), atol=1.e-8) assert np.isclose(0, p2(root), atol=1.e-8) #~ ~ ~ Cheb Form, My Matrix ~ ~ ~ cheb_multR_roots = pr.solve([c1, c2], MSmatrix=2) assert len(cheb_multR_roots) == right_number_of_roots for root in cheb_multR_roots: assert np.isclose(0, c1(root), atol=1.e-8) assert np.isclose(0, c1(root), atol=1.e-8) #~ ~ ~ Power Form, Pseudorandom Multiplication Matrix ~ ~ ~ power_multrand_roots = pr.solve([p1, p2], MSmatrix=0) assert len(power_multrand_roots) == right_number_of_roots for root in power_multrand_roots: assert np.isclose(0, p1(root), atol=1.e-8) assert np.isclose(0, p2(root), atol=1.e-8) #~ ~ ~ Cheb Form, Pseudorandom Multiplication Matrix ~ ~ ~ cheb_multrand_roots = pr.solve([c1, c2], MSmatrix=0) assert len(cheb_multrand_roots) == right_number_of_roots for root in cheb_multrand_roots: assert np.isclose(0, c1(root), atol=1.e-8) assert np.isclose(0, c1(root), atol=1.e-8) #~ ~ ~ Power Form, Division Matrix ~ ~ ~ power_div_roots = pr.solve([p1, p2], MSmatrix=-1) assert len(power_div_roots) == right_number_of_roots for root in power_div_roots: assert np.isclose(0, p1(root), atol=1.e-8) assert np.isclose(0, p2(root), atol=1.e-8) #~ ~ ~ Cheb Form, Division Matrix ~ ~ ~ cheb_div_roots = pr.solve([c1, c2], MSmatrix=-1) assert len(cheb_div_roots) == right_number_of_roots for root in cheb_div_roots: assert np.isclose(0, c1(root), atol=1.e-8) assert np.isclose(0, c2(root), atol=1.e-8)
def build_macaulay(initial_poly_list, verbose=False): """Constructs the unreduced Macaulay matrix. Removes linear polynomials by substituting in for a number of variables equal to the number of linear polynomials. Parameters -------- initial_poly_list: list The polynomials in the system we are solving. verbose : bool Prints information about how the roots are computed. Returns ----------- matrix : 2d ndarray The Macaulay matrix matrix_terms : 2d integer ndarray Array containing the ordered basis, where the ith row contains the exponent/degree of the ith basis monomial cut : int Where to cut the Macaulay matrix for the highest-degree monomials varsToRemove : list The variables removed with removing linear polynomials A : 2d ndarray A matrix giving the linear relations between the removed variables and the remaining variables Pc : 1d integer ndarray Array containing the order of the variables as the appear in the columns of A """ power = is_power(initial_poly_list) dim = initial_poly_list[0].dim poly_coeff_list = [] degree = find_degree(initial_poly_list) linear_polys = [poly for poly in initial_poly_list if poly.degree == 1] nonlinear_polys = [poly for poly in initial_poly_list if poly.degree != 1] #Choose which variables to remove if things are linear, and add linear polys to matrix if len(linear_polys) >= 1: #Linear polys involved #get the row rededuced linear coefficients A, Pc = nullspace(linear_polys) varsToRemove = Pc[:len(A)].copy() #add to macaulay matrix for row in A: #reconstruct a polynomial for each row coeff = np.zeros([2] * dim) coeff[tuple(get_var_list(dim))] = row[:-1] coeff[tuple([0] * dim)] = row[-1] if not power: poly = MultiCheb(coeff) else: poly = MultiPower(coeff) poly_coeff_list = add_polys(degree, poly, poly_coeff_list) else: #no linear A, Pc = None, None varsToRemove = [] #add nonlinear polys to poly_coeff_list for poly in nonlinear_polys: poly_coeff_list = add_polys(degree, poly, poly_coeff_list) #Creates the matrix # return (*create_matrix(poly_coeff_list, degree, dim, varsToRemove), A, Pc) return create_matrix(poly_coeff_list, degree, dim, varsToRemove)
def MSMultMatrix(polys, poly_type, max_cond_num, macaulay_zero_tol, verbose=False, MSmatrix=0): ''' Finds the multiplication matrix using the reduced Macaulay matrix. Parameters ---------- polys : array-like The polynomials to find the common zeros of poly_type : string The type of the polynomials in polys verbose : bool Prints information about how the roots are computed. MSmatrix : int Controls which Moller-Stetter matrix is constructed. The options are: 0 (default) -- The Moller-Stetter matrix of a random polynomial Some positive integer i < dimension -- The Moller-Stetter matrix of x_i max_cond_num : float The maximum condition number of the Macaulay Matrix Reduction macaulay_zero_tol : float What is considered 0 in the macaulay matrix reduction. Returns ------- multiplicationMatrix : 2D numpy array The multiplication matrix for a random polynomial f var_dict : dictionary Maps each variable to its position in the vector space basis basisDict : dict A dictionary of terms not in the vector basis a matrixes of things in the vector basis that the term can be reduced to. VB : numpy array The terms in the vector basis, each row being a term. Raises ------ ConditioningError if MacaulayReduction(...) raises a ConditioningError. ''' try: basisDict, VB, varsRemoved = MacaulayReduction( polys, max_cond_num=max_cond_num, macaulay_zero_tol=macaulay_zero_tol, verbose=verbose) except ConditioningError as e: raise e dim = max(f.dim for f in polys) # Get the polynomial to make the MS matrix of if MSmatrix == 0: #random poly f = _random_poly(poly_type, dim)[0] else: #multiply by x_i where i is determined by MSmatrix xi_ind = np.zeros(dim, dtype=int) xi_ind[MSmatrix - 1] = 1 coef = np.zeros((2, ) * dim) coef[tuple(xi_ind)] = 1 if poly_type == "MultiPower": f = MultiPower(np.array(coef)) elif poly_type == "MultiCheb": f = MultiCheb(np.array(coef)) else: raise ValueError() if verbose: print( "\nCoefficients of polynomial whose Moller-Stetter matrix we construt\n", f.coeff) #Dictionary of terms in the vector basis their spots in the matrix. VBdict = {} spot = 0 for row in VB: VBdict[tuple(row)] = spot spot += 1 # Build multiplication matrix m_f mMatrix = np.zeros((len(VB), len(VB))) for i in range(VB.shape[0]): f_coeff = f.mon_mult(VB[i], returnType='Matrix') for term in zip(*np.where(f_coeff != 0)): if term in VBdict: mMatrix[VBdict[term]][i] += f_coeff[term] else: mMatrix[:, i] -= f_coeff[term] * basisDict[term] # Construct var_dict var_dict = {} for i in range(len(VB)): mon = VB[i] if np.sum(mon) == 1 or np.sum(mon) == 0: var_dict[tuple(mon)] = i return mMatrix, var_dict, basisDict, VB
def run_n_dimension(args, radius, eigvals): num_points = args.num_points eps = args.eps power = args.power real = args.real by_coeffs = args.coeffs dim = args.dimension root_pts = {} residuals = {} powerpolys = [] chebpolys = [] if by_coeffs: for i in range(dim): from yroots.polynomial import getPoly powerpolys.append(getPoly(num_points, dim, power=True)) chebpolys.append(getPoly(num_points, dim, power=False)) else: r = np.random.random((num_points, dim)) * radius + eps roots = 2 * r - radius root_pts = {'roots': np.array(list(product(*np.rot90(roots))))} for i in range(dim): coeffs = np.zeros((num_points + 1, ) * dim) idx = [ slice(None), ] * dim idx[i] = 0 coeffs[tuple(idx)] = polyfromroots(roots[:, i]) lt = [0] * dim lt[i] = num_points powerpolys.append( MultiPower(coeffs)) #, lead_term=lt, clean_zeros=False)) coeffs[tuple(idx)] = chebfromroots(roots[:, i]) chebpolys.append( MultiCheb(coeffs)) #, lead_term=lt, clean_zeros=False)) # plt.subplot(121);plt.imshow(coeffs);plt.subplot(122);plt.imshow(chebpolys[0].coeff);plt.show() for solver in all_solvers: if not isinstance(solver, OneDSolver) and solver.basis in [ 'power', 'both' ]: # if ((not eigvals) or solver.eigvals): name = str(solver) + ' Power' root_pts[name] = solver(powerpolys) residuals[name] = maximal_residual(powerpolys, root_pts[name]) for solver in all_solvers: if not isinstance(solver, OneDSolver) and solver.basis in [ 'cheb', 'both' ]: # if ((not eigvals) or solver.eigvals): name = str(solver) + ' Cheb' root_pts[name] = solver(chebpolys) residuals[name] = maximal_residual(chebpolys, root_pts[name]) if args.hist: evaluations = {} for k, v in root_pts.items(): if k == 'roots': continue # evaluations[k] = [] polys = powerpolys if 'Power' in k else chebpolys # for poly in polys: evaluations[k] = sum(np.abs(poly(root_pts[k])) for poly in polys) ncols = len(evaluations) # plt.figure(figsize=(12,6)) fig, ax = plt.subplots(1, ncols, sharey=True, figsize=(12, 4)) minimal = -15 maximal = 1 for i, (k, v) in enumerate(evaluations.items()): ax[i].hist(np.clip(np.log10(v), minimal, maximal), range=(minimal, maximal), bins=40) ax[i].set_xlabel(r'$log_{10}(p(r_i))$') ax[i].set_title(k) plt.suptitle("Eigenvalues" if eigvals else "Eigenvectors") plt.show() return root_pts, residuals
def MacaulayReduction(initial_poly_list, max_cond_num, macaulay_zero_tol, verbose=False): """Reduces the Macaulay matrix to find a vector basis for the system of polynomials. Parameters -------- initial_poly_list: list The polynomials in the system we are solving. max_cond_num : float The maximum condition number of the Macaulay Matrix Reduction macaulay_zero_tol : float What is considered 0 in the macaulay matrix reduction. verbose : bool Prints information about how the roots are computed. Returns ----------- basisDict : dict A dictionary of terms not in the vector basis a matrixes of things in the vector basis that the term can be reduced to. VB : numpy array The terms in the vector basis, each row being a term. varsToRemove : list The variables to remove from the basis because we have linear polysnomials Raises ------ ConditioningError if rrqr_reduceMacaulay(...) raises a ConditioningError. """ power = is_power(initial_poly_list) dim = initial_poly_list[0].dim poly_coeff_list = [] degree = find_degree(initial_poly_list) linear_polys = [poly for poly in initial_poly_list if poly.degree == 1] nonlinear_polys = [poly for poly in initial_poly_list if poly.degree != 1] #Choose which variables to remove if things are linear, and add linear polys to matrix if len(linear_polys) == 1: #one linear varsToRemove = [ np.argmax(np.abs(linear_polys[0].coeff[get_var_list(dim)])) ] poly_coeff_list = add_polys(degree, linear_polys[0], poly_coeff_list) elif len(linear_polys) > 1: #multiple linear #get the row rededuced linear coefficients A, Pc = nullspace(linear_polys) varsToRemove = Pc[:len(A)].copy() #add to macaulay matrix for row in A: #reconstruct a polynomial for each row coeff = np.zeros([2] * dim) coeff[get_var_list(dim)] = row[:-1] coeff[tuple([0] * dim)] = row[-1] if power: poly = MultiPower(coeff) else: poly = MultiCheb(coeff) poly_coeff_list = add_polys(degree, poly, poly_coeff_list) else: #no linear varsToRemove = [] #add nonlinear polys to poly_coeff_list for poly in nonlinear_polys: poly_coeff_list = add_polys(degree, poly, poly_coeff_list) #Creates the matrix matrix, matrix_terms, cuts = create_matrix(poly_coeff_list, degree, dim, varsToRemove) if verbose: np.set_printoptions(suppress=False, linewidth=200) print('\nStarting Macaulay Matrix\n', matrix) print( '\nColumns in Macaulay Matrix\nFirst element in tuple is degree of x, Second element is degree of y\n', matrix_terms) print( '\nLocation of Cuts in the Macaulay Matrix into [ Mb | M1* | M2* ]\n', cuts) try: matrix, matrix_terms = rrqr_reduceMacaulay( matrix, matrix_terms, cuts, max_cond_num=max_cond_num, macaulay_zero_tol=macaulay_zero_tol) except ConditioningError as e: raise e # TODO: rrqr_reduceMacaulay2 is not working when expected. # if np.allclose(matrix[cuts[0]:,:cuts[0]], 0): # matrix, matrix_terms = rrqr_reduceMacaulay2(matrix, matrix_terms, cuts, accuracy = accuracy) # else: # matrix, matrix_terms = rrqr_reduceMacaulay(matrix, matrix_terms, cuts, accuracy = accuracy) if verbose: np.set_printoptions(suppress=True, linewidth=200) print("\nFinal Macaulay Matrix\n", matrix) print("\nColumns in Macaulay Matrix\n", matrix_terms) VB = matrix_terms[matrix.shape[0]:] basisDict = makeBasisDict(matrix, matrix_terms, VB, power) return basisDict, VB, varsToRemove