Beispiel #1
0
 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
Beispiel #2
0
 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
Beispiel #4
0
    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)))
Beispiel #6
0
    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)))
Beispiel #7
0
 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
Beispiel #9
0
    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
Beispiel #10
0
 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)
Beispiel #11
0
    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