(func)
Create a formula object representing the hypergeometric function ``func``.
Create a formula object representing the hypergeometric function ``func``.
Create a formula object representing the hypergeometric function func .
def build_hypergeometric_formula(func):
    """
    Create a formula object representing the hypergeometric function ``func``.

    """
    # We know that no `ap` are negative integers, otherwise "detect poly"
    # would have kicked in. However, `ap` could be empty. In this case we can
    # use a different basis.
    # I'm not aware of a basis that works in all cases.
    from sympy import zeros, Matrix, eye
    z = Dummy('z')
    if func.ap:
        afactors = [_x + a for a in func.ap]
        bfactors = [_x + b - 1 for b in func.bq]
        expr = _x*Mul(*bfactors) - z*Mul(*afactors)
        poly = Poly(expr, _x)
        n = poly.degree()
        basis = []
        M = zeros(n)
        for k in xrange(n):
            a = func.ap[0] + k
            basis += [hyper([a] + list(func.ap[1:]), func.bq, z)]
            if k < n - 1:
                M[k, k] = -a
                M[k, k + 1] = a
        B = Matrix(basis)
        C = Matrix([[1] + [0]*(n - 1)])
        derivs = [eye(n)]
        for k in xrange(n):
            derivs.append(M*derivs[k])
        l = poly.all_coeffs()
        l.reverse()
        res = [0]*n
        for k, c in enumerate(l):
            for r, d in enumerate(C*derivs[k]):
                res[r] += c*d
        for k, c in enumerate(res):
            M[n - 1, k] = -c/derivs[n - 1][0, n - 1]/poly.all_coeffs()[0]
        return Formula(func, z, None, [], B, C, M)
    else:
        # Since there are no `ap`, none of the `bq` can be non-positive
        # integers.
        basis = []
        bq = list(func.bq[:])
        for i in range(len(bq)):
            basis += [hyper([], bq, z)]
            bq[i] += 1
        basis += [hyper([], bq, z)]
        B = Matrix(basis)
        n = len(B)
        C = Matrix([[1] + [0]*(n - 1)])
        M = zeros(n)
        M[0, n - 1] = z/Mul(*func.bq)
        for k in range(1, n):
            M[k, k - 1] = func.bq[k - 1]
            M[k, k] = -func.bq[k - 1]
        return Formula(func, z, None, [], B, C, M)
def build_hypergeometric_formula ( func ) : # We know that no `ap` are negative integers, otherwise "detect poly" # would have kicked in. However, `ap` could be empty. In this case we can # use a different basis. # I'm not aware of a basis that works in all cases. from sympy import zeros , Matrix , eye z = Dummy ( 'z' ) if func . ap : afactors = [ _x + a for a in func . ap ] bfactors = [ _x + b - 1 for b in func . bq ] expr = _x * Mul ( * bfactors ) - z * Mul ( * afactors ) poly = Poly ( expr , _x ) n = poly . degree ( ) basis = [ ] M = zeros ( n ) for k in xrange ( n ) : a = func . ap [ 0 ] + k basis += [ hyper ( [ a ] + list ( func . ap [ 1 : ] ) , func . bq , z ) ] if k < n - 1 : M [ k , k ] = - a M [ k , k + 1 ] = a B = Matrix ( basis ) C = Matrix ( [ [ 1 ] + [ 0 ] * ( n - 1 ) ] ) derivs = [ eye ( n ) ] for k in xrange ( n ) : derivs . append ( M * derivs [ k ] ) l = poly . all_coeffs ( ) l . reverse ( ) res = [ 0 ] * n for k , c in enumerate ( l ) : for r , d in enumerate ( C * derivs [ k ] ) : res [ r ] += c * d for k , c in enumerate ( res ) : M [ n - 1 , k ] = - c / derivs [ n - 1 ] [ 0 , n - 1 ] / poly . all_coeffs ( ) [ 0 ] return Formula ( func , z , None , [ ] , B , C , M ) else : # Since there are no `ap`, none of the `bq` can be non-positive # integers. basis = [ ] bq = list ( func . bq [ : ] ) for i in range ( len ( bq ) ) : basis += [ hyper ( [ ] , bq , z ) ] bq [ i ] += 1 basis += [ hyper ( [ ] , bq , z ) ] B = Matrix ( basis ) n = len ( B ) C = Matrix ( [ [ 1 ] + [ 0 ] * ( n - 1 ) ] ) M = zeros ( n ) M [ 0 , n - 1 ] = z / Mul ( * func . bq ) for k in range ( 1 , n ) : M [ k , k - 1 ] = func . bq [ k - 1 ] M [ k , k ] = - func . bq [ k - 1 ] return Formula ( func , z , None , [ ] , B , C , M )