//  [python]
def HypergeometricFunction(a,b,c,z,method,accuracy):
    
    if not(method):
        method = 1
    
    if method == 1:
        if not(accuracy):
            npoints = 100
        else:
            npoints = accuracy
        
        
        n = np.arange(0,npoints+1,1)
        nfact = scipy.special.factorial(n)
        Ga= math.gamma(a)
        Gb = math.gamma(b)
        Gc = math.gamma(c)
        Gcab = math.gamma(c - a - b)
        Gca = math.gamma(c - a)
        Gcb = math.gamma(c - b)    
        Gan = np.array([math.gamma(a + k) for k in n])
        Gbn = np.array([math.gamma(b + k) for k in n])
        Gcn = np.array([math.gamma(c + k) for k in n])
        ai = a
        bi = c - b
        ci = c
        Gai = math.gamma(ai)
        Gbi = math.gamma(bi)
        Gci = math.gamma(ci)
        Gain = np.array([math.gamma(ai + k) for k in n]) 
        Gbin = np.array([math.gamma(bi + k) for k in n])
        Gcin = np.array([math.gamma(ci + k) for k in n])
             
        zsize = z.shape    
        F = np.zeros(shape=(zsize[0],zsize[1]))
        
        for i in range(0,zsize[0]):
            for j in range(0,zsize[1]):
                           
                if (z[i,j]) == 1:
                    F[i,j] = Gc*Gcab/(Gca*Gcb)
                elif (z[i,j] >= -0.5 and z[i,j] < 1) or (z[i,j] > 1 and z[i,j] < 2):
                    zi = z[i,j]
                    zn = zi**n
    
                    Gprod = (Gan*Gbn*zn)/(Gcn*nfact)
                    # here we are !!! 
                    Gprod = Gprod[np.logical_and((~np.isnan(Gprod)), (~np.isinf(Gprod)))]
                    F[i,j] = (Gc/(Ga*Gb))*np.sum(Gprod)
                else:
                    zi = z[i,j]/(z[i,j] - 1)
                    q0 = (1 - z[i,j])**(-a)
                    zn = zi**n
    
                    Gprod = (Gain*Gbin*zn)/(Gcin*nfact)
                    Gprod = Gprod[np.logical_and((~np.isnan(Gprod)), (~np.isinf(Gprod)))]
                    F[i,j] = q0*(Gci/(Gai*Gbi))*np.sum(Gprod)            
    
                
    #             if abs(z[i,j]) == 1
    #                 Gc = gamma(c)
    #                 Gcab = gamma(c - a - b)
    #                 Gca = gamma(c - a)
    #                 Gcb = gamma(c - b)
    #                 F[i,j] = Gc.*Gcab./(Gca.*Gcb)
    #             elseif (z[i,j] >= -0.5 && z[i,j] < 1) || (z[i,j] > 1 && z[i,j] < 2)
    #                 zi = z[i,j]
    #                 n = 0:1:npoints
    #                 Gan = gamma(a + n)
    #                 Gbn = gamma(b + n)
    #                 Gcn = gamma(c + n)
    #                 zn = zi.^n
    #                 nfact = factorial(n)
    # 
    #                 Ga = gamma(a)
    #                 Gb = gamma(b)
    #                 Gc = gamma(c)
    #                 Gprod = (Gan.*Gbn.*zn)./(Gcn.*nfact)
    #                 Gprod = Gprod(~isnan(Gprod))
    #                 F[i,j] = (Gc/(Ga*Gb))*sum(Gprod)
    #             else
    #                 ai = a
    #                 bi = c - b
    #                 ci = c
    #                 zi = z[i,j]/(z[i,j] - 1)
    #                 q0 = (1 - z[i,j])^(-a)
    # 
    #                 n = 0:1:npoints
    #                 Gan = gamma(ai + n)
    #                 Gbn = gamma(bi + n)
    #                 Gcn = gamma(ci + n)
    #                 zn = zi.^n
    #                 nfact = factorial(n)
    # 
    #                 Ga = gamma(ai)
    #                 Gb = gamma(bi)
    #                 Gc = gamma(ci)
    #                 Gprod = (Gan.*Gbn.*zn)./(Gcn.*nfact)
    #                 Gprod = Gprod(~isnan(Gprod))
    #                 F[i,j] = q0*(Gc/(Ga*Gb))*sum(Gprod)            
    # 
    
        
    elif method == 2:
        
        if not(accuracy):
            npoints = 100
        else:
            npoints = accuracy
        
        
        F = np.zeros(shape=(1,len(z)))
        for i in range(1,len(z)):
            zi = z[i]
            n = np.arange(0,npoints+1,1)
            Gan = [math.gamma(a + k) for k in n]
            Gbn = [math.gamma(b + k) for k in n]
            Gcn = [math.gamma(c + k) for k in n]
            zn = zi**n
            nfact = scipy.special.factorial(n)
    
            Ga = math.gamma(a)
            Gb = math.gamma(b)
            Gc = math.gamma(c)
            Gprod = (Gan*Gbn*zn)/(Gcn*nfact)
            Gprod = Gprod[~np.isnan(Gprod)]
            F[i] = (Gc/(Ga*Gb))*np.sum(Gprod)
        
    elif method == 3:
        integralfunc = lambda t: ( t**(b-1) ) * ( (1 - t)**(c - b - 1) )* ( (1 - t*z)**(-a) )
        #fff = lambda x: x**2+c
        integralvalue = integrate.quad(integralfunc, 0, 1)
    #    integral(integralfunc,0,1,'ArrayValued',true,'AbsTol',1e-12,'RelTol',1e-12)
    #     integralvalue = zeros(1,length(z))
    #     for i = 1:length(z)
    #         integralfunci = @(t) ( t.^(b-1) ) .* ( (1 - t).^(c - b - 1) ) .* ( (1 - t.*z(i)).^(-a) )
    #         integralvalue(i) = integral(integralfunci,0,1,'AbsTol',1e-2,'RelTol',1e-10)
    #     end
    
        F = (math.gamma(c)/math.gamma(b))/math.gamma(c-b)*integralvalue
        
    elif method == 4:
        
        if not(accuracy):
            npoints = 100
        else:
            npoints = accuracy
        
        F = np.zeros(shape=(1,len(z)))
        
        for i in range(1,len(z)):
            if np.abs(z[i]) == 1:
                Gc = math.gamma(c)
                Gcab = math.gamma(c - a - b)
                Gca = math.gamma(c - a)
                Gcb = math.gamma(c - b)
                F[i] = Gc*Gcab/(Gca*Gcb)
            else:
                zi = z[0,i]
                n = np.arange(0,npoints+1,1)
                qa = np.concatenate(([1], a + n[1:] - 1))
                qb = np.concatenate(([1], b + n[1:] - 1))
                qc = np.concatenate(([1], c + n[1:] - 1))
                
                qsuma = np.cumsum(np.log(qa))
                qsumb = np.cumsum(np.log(qb))
                qsumc = np.cumsum(np.log(qc))           
                neven = 2*np.floor(n/2)
                oddindex = np.remainder(n,2)
                znvect = (neven/2)*np.log(zi**2)
                nvect = [0, np.cumsum(np.log(n[1:]))]        
                allsum = qsuma + qsumb - qsumc + znvect - nvect
                zminusvect = zi*oddindex
                expsum = np.exp(allsum)*zminusvect
                F[i] = np.sum(expsum)
    
    return F