def _ith_coeff(self, i): if (i % 2) == 0: return 0.0 else: b = float(bernoulli(i + 1)) p = float(2**(i + 1)) f = float(factorial(i + 1)) return b * p * (p - 1) / f
def _ith_coeff(self, i): if (i%2) == 0: return 0.0 else: b = float(bernoulli(i+1)) p = float(2 ** (i+1)) f = float(factorial(i+1)) return b*p*(p-1)/f
def compute_normal_form_and_generating_function(self, h_term): """ Given the next iso-grade part of the original Hamiltonian, compute the next iso-grade parts of the normalised Hamiltonian and the generator. @param h_term: if the next row to be computed is i, then this shuld be the (i + 2)-iso-grade part of the original Hamiltonian, extracted directly from teh Hamiltonian, without any manipulation of factorial pre-factors. NOTES: Note that this method returns a pair of polynomials that may be added directly to the generator and the normalised Hamiltonian. These quantities are _NOT_ the $w_i$ and $k_i$; they are factorially-weighted versions of them. Internally, we store a list of the actual $w_i$. If it is needed to make a polynomial from these, one must sum them being careful to include the proper factorial denominator, i.e., $K = \sum \frac{1}{n!}K_i$. """ #prepare triangle row self._current_row += 1 i = self._current_row assert (i >= 0) assert (len(self._w) == i) #prepare hamiltonian term, removing factorial division to give h_i assert self._lie_alg.is_isograde(h_term, i + 2) pre_factor = float(factorial(i)) h_i = pre_factor * h_term self._h_ij[_make_db_key(i, 0)] = h_i #partition the known terms into normalised and remainder logger.info('Computing triangle row minus unknown term') known_terms = self.triangle_minus_unknown_term(0, i) logger.info('Partitioning the known terms') normalised, remainder = known_terms.partition(self.filter) k_i = normalised self._correct_row_using_partition(normalised, remainder) #solve homological equation w_i = self.solve_homological_eqn(remainder) self._w.append(w_i) self._check_homological_equation(remainder) logger.info('Step: %d, grade: %d', i, i+2) logger.info('H: %d, N: %d, R: %d', len(known_terms), len(normalised), len(remainder)) #return polynomial terms (must include factorial prefactor) return (1.0 / pre_factor) * k_i, (1.0 / pre_factor) * w_i
def compute_normal_form_and_generating_function(self, h_term): """ Given the next iso-grade part of the original Hamiltonian, compute the next iso-grade parts of the normalised Hamiltonian and the generator. @param h_term: if the next row to be computed is i, then this shuld be the (i + 2)-iso-grade part of the original Hamiltonian, extracted directly from teh Hamiltonian, without any manipulation of factorial pre-factors. NOTES: Note that this method returns a pair of polynomials that may be added directly to the generator and the normalised Hamiltonian. These quantities are _NOT_ the $w_i$ and $k_i$; they are factorially-weighted versions of them. Internally, we store a list of the actual $w_i$. If it is needed to make a polynomial from these, one must sum them being careful to include the proper factorial denominator, i.e., $K = \sum \frac{1}{n!}K_i$. """ #prepare triangle row self._current_row += 1 i = self._current_row assert (i >= 0) assert (len(self._w) == i) #prepare hamiltonian term, removing factorial division to give h_i assert self._lie_alg.is_isograde(h_term, i + 2) pre_factor = float(factorial(i)) h_i = pre_factor * h_term self._h_ij[_make_db_key(i, 0)] = h_i #partition the known terms into normalised and remainder logger.info('Computing triangle row minus unknown term') known_terms = self.triangle_minus_unknown_term(0, i) logger.info('Partitioning the known terms') normalised, remainder = known_terms.partition(self.filter) k_i = normalised self._correct_row_using_partition(normalised, remainder) #solve homological equation w_i = self.solve_homological_eqn(remainder) self._w.append(w_i) self._check_homological_equation(remainder) logger.info('Step: %d, grade: %d', i, i + 2) logger.info('H: %d, N: %d, R: %d', len(known_terms), len(normalised), len(remainder)) #return polynomial terms (must include factorial prefactor) return (1.0 / pre_factor) * k_i, (1.0 / pre_factor) * w_i
def poly_to_inner_taylor(self, poly, i): """ Convert a polynomial to an inner Taylor coefficient by taking the grade (i+offset) part and multiplying by factorial(i). """ self.alg.check_elt(poly) return (factorial(i)*self.alg.isograde(poly, (i+self.offset)))
def poly_to_inner_taylor(self, poly, i): """ Convert a polynomial to an inner Taylor coefficient by taking the grade (i+offset) part and multiplying by factorial(i). """ self.alg.check_elt(poly) return (factorial(i) * self.alg.isograde(poly, (i + self.offset)))
def _ith_term(self, i): if i%2: powers = [0,]*self.n_vars powers[self.index] = i if i%4 == 3: sign = -1 else: sign = 1 return (float(sign)/float(factorial(i)))*Polynomial.Monomial(tuple(powers)) else: return Polynomial(self.n_vars)
def inner_taylor_to_poly(self, poly, i): """ Convert an inner Taylor coefficient of grade (i+offset) to a polynomial by dividing by factorial(i). """ self.alg.check_elt(poly) gra = self.alg.grade(poly) assert (gra == 0) or (gra == i+self.offset) return (1.0/factorial(i))*poly
def inner_taylor_to_poly(self, poly, i): """ Convert an inner Taylor coefficient of grade (i+offset) to a polynomial by dividing by factorial(i). """ self.alg.check_elt(poly) gra = self.alg.grade(poly) assert (gra == 0) or (gra == i + self.offset) return (1.0 / factorial(i)) * poly
def _ith_term(self, i): if i % 2: powers = [ 0, ] * self.n_vars powers[self.index] = i if i % 4 == 3: sign = -1 else: sign = 1 return (float(sign) / float(factorial(i))) * Polynomial.Monomial( tuple(powers)) else: return Polynomial(self.n_vars)
def moyal_product(self, pol_a, pol_b, tolerance=1.0e-15): """ This implementation of the Moyal product is adapted from one by Dr. Holger Waalkens, 2005. """ self.check_elt(pol_a) self.check_elt(pol_b) n_max = min(self.grade(pol_a), self.grade(pol_b)) d = self.dof() result = self.zero() for n in xrange(0, n_max+1): for po_a, co_a in pol_a.powers_and_coefficients(): for po_b, co_b in pol_b.powers_and_coefficients(): m = [0,]*(2*d+1) if (n==0): #usual product: for k in xrange(0, 2*d+1): m[k] = po_a[k] + po_b[k] c = co_a * co_b result += self.monomial(Powers(m), c) #end case n==0: else: for N in xrange(0, (n+1)**(2*d)): Nnew = N for k in xrange(2*d, d, -1): ii = (k - d)-1 #integer div assert 0<=ii<d, ii ip = 2*ii+1 assert 0<=ip<2*d m[ip] = int(Nnew) // int((n+1)**(k-1)) Nnew -= m[ip]*((n+1)**(k-1)) for k in xrange(d, 0, -1): ii = k - 1 #integer div assert 0<=ii<d, ii iq = 2*ii assert 0<=iq<2*d m[iq] = int(Nnew) // int((n+1)**(k-1)) Nnew -= m[iq]*((n+1)**(k-1)) diff_orderis = 0 for k in xrange(0, 2*d): diff_orderis += m[k] if (diff_orderis == n): cc = (0.0+0.5J)**(n) n_mono = [0,]*(2*d+1) n_mono[-1] = n + po_a[-1] + po_b[-1] cc *= (co_a*co_b) for k in xrange(0, 2*d): cc /= float(factorial(m[k])) sign_exp = 0 for k in xrange(1, 2*d, 2): #ip sign_exp += m[k] cc *= float((-1)**sign_exp) for k in xrange(0, 2*d-1, 2): #iq iq = k ip = k+1 pak, qbk = po_a[ip], po_b[iq] if (m[iq] <= pak) and (m[iq] <= qbk): n_mono[ip] += pak - m[iq] n_mono[iq] += qbk - m[iq] cc *= float(factorial(pak))/float(factorial(pak-m[iq])) cc *= float(factorial(qbk))/float(factorial(qbk-m[iq])) else: cc = 0.0+0.0J qak, pbk = po_a[iq], po_b[ip] if (m[ip] <= qak) and (m[ip] <= pbk): n_mono[iq] += qak - m[ip] n_mono[ip] += pbk - m[ip] cc *= float(factorial(qak))/float(factorial(qak-m[ip])) cc *= float(factorial(pbk))/float(factorial(pbk-m[ip])) else: cc = 0.0+0.0J if (abs(cc) > tolerance): result[Powers(n_mono)] += cc #end diff_order==n #end for N #end case n!=0 #end pol_b #end pol_a #end for n return result