def setUp(self): """Set up an example from Hill's equations.""" x_2 = Powers((2, 0, 0, 0, 0, 0)) px2 = Powers((0, 2, 0, 0, 0, 0)) y_2 = Powers((0, 0, 2, 0, 0, 0)) py2 = Powers((0, 0, 0, 2, 0, 0)) z_2 = Powers((0, 0, 0, 0, 2, 0)) pz2 = Powers((0, 0, 0, 0, 0, 2)) xpy = Powers((1, 0, 0, 1, 0, 0)) ypx = Powers((0, 1, 1, 0, 0, 0)) terms = { px2: 0.5, py2: 0.5, pz2: 0.5, xpy: -1.0, ypx: 1.0, x_2: -4.0, y_2: 2.0, z_2: 2.0 } assert len(terms) == 8 self.h_2 = Polynomial(6, terms=terms) self.lie = LieAlgebra(3) self.diag = Diagonalizer(self.lie) self.eq_type = 'scc' e = [] e.append(+sqrt(2.0 * sqrt(7.0) + 1.0)) e.append(-e[-1]) e.append(complex(0.0, +sqrt(2.0 * sqrt(7.0) - 1.0))) e.append(-e[-1]) e.append(complex(0.0, +2.0)) e.append(-e[-1]) self.eig_vals = e
def test_cf_hamilton_linear_to_quadratic_matrix(self): """Compare the results of (1) asking directly for the linear matrix for a given Hamiltonian, and (2) forming Hamilton's equations and then linearizing them.""" dof = 3 terms = { Powers((2, 0, 0, 0, 0, 0)): -0.3, Powers((1, 1, 0, 0, 0, 0)): 0.33, Powers((0, 1, 0, 1, 1, 0)): 7.2, Powers((0, 1, 0, 0, 1, 0)): 7.12, Powers((0, 0, 3, 0, 1, 0)): -4.0 } h = Polynomial(2 * dof, terms=terms) alg = LieAlgebra(dof) diag = Diagonalizer(alg) lin = diag.linear_matrix(h) rhs = diag.hamiltons_equations_rhs(h) rhs_lin = tuple([alg.isograde(h_term, 1) for h_term in rhs]) for i, pol in enumerate(rhs_lin): for m, c in pol.powers_and_coefficients(): mon = alg.monomial(m, c) self.assertEquals(alg.grade(mon), 1) for j, f in enumerate(m): if f == 1: self.assertEquals(lin[i, j], c)
def diagonalize(self): logger.info('Diagonalizing...') self.dia = Diagonalizer(self.alg) logger.info('Equilibrium Hamiltonian has %d terms' % self.h_er.n_terms()) logger.info('Computing the eigensystem...') self.eig = self.dia.compute_eigen_system(self.h_er, self.tolerance) logger.info('...done computing the eigensystem.') logger.info('Computing the diagonal change...') self.dia.compute_diagonal_change() logger.info('...done computing the diagonal change.') logger.info('Measuring error in symplectic identities...') mat = self.dia.get_matrix_diag_to_equi() assert self.dia.matrix_is_symplectic(mat) logger.info('...done measuring error in symplectic identities.') logger.info('Converting the matrix into vec<poly> representation...') er_in_terms_of_dr = self.dia.matrix_as_vector_of_row_polynomials(mat) self.er_in_terms_of_dr = er_in_terms_of_dr logger.info('... done converting the matrix into vec<poly> repn.') logger.info('Applying diagonalizing change to equilibrium H...') self.h_dr = self.h_er.substitute(er_in_terms_of_dr) logger.info('...done applying diagonalizing change to equilibrium H.') del er_in_terms_of_dr logger.info('Real diagonal Hamiltonian has %d terms' % self.h_dr.n_terms()) err = self.h_dr.imag().l_infinity_norm() logger.info('Size of imaginary part: %s', err) assert err < tol_diag_real_imag_part logger.info('WARNING! Removing imaginary terms') self.h_dr = self.h_dr.real() logger.info('Real diagonal Hamiltonian has %d terms' % self.h_dr.n_terms()) logger.info('WARNING! Removing small coefficients of size <=%s' % tol_diag_real_coeffs) self.h_dr = self.h_dr.with_small_coeffs_removed(tol_diag_real_coeffs) logger.info('Real diagonal Hamiltonian has %d terms' % self.h_dr.n_terms()) #logger.info('Real Diagonal Hamiltonian (terms up to gra 3)') #logger.info(truncated_poly(self.alg, self.h_dr)) logger.info('Quadratic part') logger.info(truncated_poly(self.alg, self.alg.isograde(self.h_dr, 2))) logger.info('Terms in quadratic part %d' % (self.alg.isograde(self.h_dr, 2).n_terms())) logger.info('...done diagonalizing.')
def test_example_skew(self): """Multiply the skew-symmetric matrix by a specific vector.""" dof = 3 lie = LieAlgebra(dof) diag = Diagonalizer(lie) J = diag.skew_symmetric_matrix() x = (1, 2, 3, 4, 5, 6) y = matrixmultiply(J, x) # self.assertEquals(y, (2,-1,4,-3,6,-5)) z = y == (2, -1, 4, -3, 6, -5) self.assertTrue(z.all())
def test_skew_symmetric_diagonal_2x_2(self): """Test the basic structure of the skew-symmetric matrix.""" dof = 3 lie = LieAlgebra(dof) diag = Diagonalizer(lie) J = diag.skew_symmetric_matrix() for qi in xrange(0, dof, 2): pi = qi + 1 self.assertEquals(J[qi, qi], 0.0) self.assertEquals(J[qi, pi], +1.0) self.assertEquals(J[pi, qi], -1.0) self.assertEquals(J[pi, pi], 0.0)
def test_matrix_as_polynomials(self): dof = 1 mat = ((1, 2), (3, 4)) alg = LieAlgebra(dof) diag = Diagonalizer(alg) vp = diag.matrix_as_vector_of_row_polynomials(mat) self.assert_(vp[0]((0.0, 0.0)) == 0.0) self.assert_(vp[0]((1.0, 0.0)) == 1.0) self.assert_(vp[0]((1.0, 1.0)) == 3.0) self.assert_(vp[0]((0.0, 1.0)) == 2.0) self.assert_(vp[1]((0.0, 0.0)) == 0.0) self.assert_(vp[1]((1.0, 0.0)) == 3.0) self.assert_(vp[1]((1.0, 1.0)) == 7.0) self.assert_(vp[1]((0.0, 1.0)) == 4.0)
def test_saddle(self): lie = LieAlgebra(1) diag = Diagonalizer(lie) q = lie.q p = lie.p orig = q(0) * p(0) eq_type = 's' comp = Complexifier(lie, eq_type) r2c = comp.calc_sub_complex_into_real() c2r = comp.calc_sub_real_into_complex() comp = orig.substitute(r2c) real = comp.substitute(c2r) diff = orig - real for m, c in diff.powers_and_coefficients(): self.assert_(abs(c) < 1.0e-15)
def test_quadratic_terms(self): tolerance = 1.0e-15 n = 0 #bath modes sb = new_random_system_bath(n, 1.0, imag_harm_freq_barr, 0.6, random_seed=54321) lie = sb.lie_algebra() h = sb.hamiltonian_real() #Sanity checks: assert h.degree() == 4 assert h.n_vars() == 2 * n + 2 assert len(h) == (3) + (2 * n) + (n) #system+bath+coupling h_2 = h.homogeneous(2) self.assert_(h_2) #non-zero diag = Diagonalizer(lie) eig = diag.compute_eigen_system(h_2, tolerance) diag.compute_diagonal_change() eq_type = eig.get_equilibrium_type() self.assertEquals(eq_type, 's') eigs = [pair.val for pair in eig.get_raw_eigen_value_vector_pairs()] mat = diag.get_matrix_diag_to_equi() assert diag.matrix_is_symplectic(mat) sub_diag_into_equi = diag.matrix_as_vector_of_row_polynomials(mat) comp = Complexifier(lie, eq_type) sub_complex_into_real = comp.calc_sub_complex_into_real() h_2_diag = h_2.substitute(sub_diag_into_equi) h_2_comp = h_2_diag.substitute(sub_complex_into_real) h_2_comp = h_2_comp.with_small_coeffs_removed(tolerance) self.assert_(lie.is_diagonal_polynomial(h_2_comp)) h_diag = h.substitute(sub_diag_into_equi) h_comp = h_diag.substitute(sub_complex_into_real) h_comp = h_comp.with_small_coeffs_removed(tolerance) h_comp_2 = h_comp.homogeneous(2) self.assert_((h_comp_2 - h_2_comp).l1_norm() < tolerance, '%s != %s' % (h_comp_2, h_2_comp)) self.assert_(not h_comp.homogeneous(1))
def test_mutual_inverses(self): lie = LieAlgebra(6) diag = Diagonalizer(lie) pol = lie.zero() for i in xrange(6): pol += lie.q(i) pol += lie.p(i) eq_type = 'scccsc' comp = Complexifier(lie, eq_type) sub_c_into_r = comp.calc_sub_complex_into_real() sub_r_into_c = comp.calc_sub_real_into_complex() pol_c = pol.substitute(sub_c_into_r) pol_r = pol_c.substitute(sub_r_into_c) self.assert_(len(pol_r) == len(pol)) for i in xrange(6): self.assert_((pol_r - pol).l_infinity_norm() < 1.0e-15) self.assert_((pol_r - pol).l_infinity_norm() < 1.0e-15)
def test_centre_saddle(self): lie = LieAlgebra(2) diag = Diagonalizer(lie) q = lie.q p = lie.p cent = (0.5 * q(0)**2) + (0.5 * p(0)**2) sadd = (1.0 * q(1)) * (1.0 * p(1)) orig = cent + sadd self.assertEquals(len(orig), 3) eq_type = 'cs' comp = Complexifier(lie, eq_type) r2c = comp.calc_sub_complex_into_real() c2r = comp.calc_sub_real_into_complex() comp = orig.substitute(r2c) self.assertEquals(len(comp), 2) real = comp.substitute(c2r) diff = orig - real for m, c in diff.powers_and_coefficients(): self.assert_(abs(c) < 1.0e-15)
def test_centre(self): lie = LieAlgebra(1) diag = Diagonalizer(lie) q = lie.q p = lie.p orig = (0.5 * q(0)**2) + (0.5 * p(0)**2) self.assertEquals(len(orig), 2) eq_type = 'c' comp = Complexifier(lie, eq_type) r2c = comp.calc_sub_complex_into_real() c2r = comp.calc_sub_real_into_complex() comp = orig.substitute(r2c) self.assertEquals(len(comp), 1) for m, c in comp.powers_and_coefficients(): self.assert_(c.real == 0.0) self.assert_(m[0] == 1) self.assert_(m[1] == 1) real = comp.substitute(c2r) diff = orig - real for m, c in diff.powers_and_coefficients(): self.assert_(abs(c) < 1.0e-15)
def diagonalize(self, dof, h): tolerance = 5.0e-15 self.diag = Diagonalizer(self.alg) self.eig = self.diag.compute_eigen_system(h, tolerance) self.diag.compute_diagonal_change() mat = self.diag.get_matrix_diag_to_equi() assert self.diag.matrix_is_symplectic(mat) sub_diag_into_equi = self.diag.matrix_as_vector_of_row_polynomials(mat) h_diag = h.substitute(sub_diag_into_equi) self.eq_type = self.eig.get_equilibrium_type() self.comp = Complexifier(self.alg, self.eq_type) self.sub_c_into_r = self.comp.calc_sub_complex_into_real() self.sub_r_into_c = self.comp.calc_sub_real_into_complex() h_comp = h_diag.substitute(self.sub_c_into_r) h_comp = h_comp.with_small_coeffs_removed(tolerance) assert (self.alg.is_diagonal_polynomial(self.alg.isograde(h_comp, 2))) return h_comp
def test_eigensystem(self): """Multiply eigenvectors and the original matrix by the eigenvalues in order to check the integrity of the eigensystem.""" dof = 3 terms = { Powers((2, 0, 0, 0, 0, 0)): -0.3, Powers((1, 1, 0, 0, 0, 0)): 0.33, Powers((0, 0, 1, 0, 1, 0)): 7.2, Powers((0, 0, 0, 0, 0, 2)): 7.2, Powers((0, 0, 0, 1, 1, 0)): 7.12 } g = Polynomial(2 * dof, terms=terms) alg = LieAlgebra(dof) diag = Diagonalizer(alg) lin = diag.linear_matrix(g) val_vec_pairs = diag.eigenvalue_eigenvector_pairs(g) for p in val_vec_pairs: prod_s = p.vec * p.val prod_v = matrixmultiply(lin, p.vec) for x in prod_s - prod_v: self.assert_(abs(x) < 1.0e-15)
def diagonalize(self, dof, h): tolerance = 5.0e-15 lie = self.alg diag = Diagonalizer(lie) eig = diag.compute_eigen_system(h, tolerance=tolerance) diag.compute_diagonal_change() mat = diag.get_matrix_diag_to_equi() assert diag.matrix_is_symplectic(mat) sub_diag_into_equi = diag.matrix_as_vector_of_row_polynomials(mat) h_diag = h.substitute(sub_diag_into_equi) eq_type = eig.get_equilibrium_type() comp = Complexifier(lie, eq_type) self.sub_c_into_r = comp.calc_sub_complex_into_real() self.sub_r_into_c = comp.calc_sub_real_into_complex() h_comp = h_diag.substitute(self.sub_c_into_r) h_comp = h_comp.with_small_coeffs_removed(tolerance) self.assert_(lie.is_diagonal_polynomial(h_comp.homogeneous(2))) return h_comp
def compare_normal_form(dir_name1, dir_name2, grade=4): def compare_matrix(dia, mat1, mat2, comment): print dia.matrix_norm(array(mat1, Float) - array(mat2, Float)), comment print "Comparing data in Normal form files upto grade %d" % (grade) print print "Reading python data" first = NormalFormData(dir_name1, is_xxpp_format=True, degree=grade) ring = PolynomialRing(first.equi_to_tham.n_vars()) print print "Comparing python data with cpp files upto grade %d" % (grade) print "l_infinity_norm \t l1_norm \t\t polynomials" ringIO = PolynomialRingIO(ring) file_istr = open("hill_l1_18--norm_to_diag.vpol", 'r') pv_norm_to_diag = ringIO.read_sexp_vector_of_polynomials(file_istr) compare_poly_vec(first.norm_to_diag, pv_norm_to_diag, "norm_to_diag", grade=grade - 1) file_istr = open("hill_l1_18--diag_to_norm.vpol", 'r') pv_diag_to_norm = ringIO.read_sexp_vector_of_polynomials(file_istr) compare_poly_vec(first.diag_to_norm, pv_diag_to_norm, "diag_to_norm", grade=grade - 1) print print "Reading mathematica data" n_ints = len(first.ints_to_freq) # get the frequencies to find the order of the planes order_f = [poly((0.0, ) * n_ints) for poly in first.ints_to_freq] second = NormalFormData(dir_name2, order_f=order_f, is_xxpp_format=True, degree=grade) from Diagonal import Diagonalizer lie = LieAlgebra(n_ints) dia = Diagonalizer(lie) grade_ints = grade / 2 dia.matrix_is_symplectic(array(first.diag_to_equi, Float)) dia.matrix_is_symplectic(array(second.diag_to_equi, Float)) dia.matrix_is_symplectic(array(first.equi_to_diag, Float)) dia.matrix_is_symplectic(array(second.equi_to_diag, Float)) # For the case develloped, Hill, there is a 45deg rotation between the # diagonalised coordinates in each of the centre planes. Thus: # These matrices are different #compare_matrix(dia, first.diag_to_equi, second.diag_to_equi, "diag_to_equi") #compare_matrix(dia, first.equi_to_diag, second.equi_to_diag, "equi_to_diag") # We neeed to convert between the diagonal planes and back to # compare the nonlinear normalisation plolynomials # second.diag_to_first.diag = first.diag_in_terms_of_second.diag = fd_in_sd = dia.matrix_as_vector_of_row_polynomials( matrixmultiply(array(first.equi_to_diag, Float), array(second.diag_to_equi, Float))) sd_in_fd = dia.matrix_as_vector_of_row_polynomials( matrixmultiply(array(second.equi_to_diag, Float), array(first.diag_to_equi, Float))) print print "Comparing mathematica data with cpp files upto grade %d" % (grade - 1) compare_poly_vec(pv_norm_to_diag, poly_vec_substitute( fd_in_sd, poly_vec_substitute( poly_vec_isograde(second.norm_to_diag, grade - 1), sd_in_fd)), "norm_to_diag", grade=grade - 1) print "Comparing mathematica data with cpp files upto grade %d" % (grade - 1) compare_poly_vec(pv_diag_to_norm, poly_vec_substitute( fd_in_sd, poly_vec_substitute( poly_vec_isograde(second.diag_to_norm, grade - 1), sd_in_fd)), "diag_to_norm", grade=grade - 1) print print "Comparing mathematica data with python upto grade %d" % (grade) compare_poly(first.equi_to_tham, second.equi_to_tham, "equi_to_tham", grade=grade) compare_poly_vec(first.ints_to_freq, second.ints_to_freq, "ints_to_freq", grade=grade_ints - 1) ring_ints = PolynomialRing(second.ints_to_tham.n_vars()) poly_2 = ring_ints.isograde(second.ints_to_tham, 0, up_to=grade_ints + 1) compare_poly(first.ints_to_tham, poly_2, "ints_to_tham") compare_poly_vec(first.norm_to_ints, second.norm_to_ints, "norm_to_ints", grade=grade) second.diag_to_norm = poly_vec_isograde(second.diag_to_norm, grade) second.norm_to_diag = poly_vec_isograde(second.norm_to_diag, grade) compare_poly_vec(first.norm_to_diag, poly_vec_substitute( fd_in_sd, poly_vec_substitute(second.norm_to_diag, sd_in_fd)), "norm_to_diag", grade=grade - 1) compare_poly_vec(first.diag_to_norm, poly_vec_substitute( fd_in_sd, poly_vec_substitute(second.diag_to_norm, sd_in_fd)), "diag_to_norm", grade=grade - 1) compare_poly_vec(first.diag_to_norm, second.diag_to_norm, "diag_to_norm", grade=grade - 1) compare_poly_vec(first.diag_to_norm, poly_vec_substitute( fd_in_sd, poly_vec_substitute(second.diag_to_norm, sd_in_fd)), "diag_to_norm", grade=grade) compare_poly_vec(first.equi_to_tvec, second.equi_to_tvec, "equi_to_tvec", grade=grade - 1)