def Nystrom(k):
    r"""
    Construct the k-step explicit Nystrom linear multistep method.
    The methods are explicit and have order k.
    They have the form:

    `y_{n+1} = y_{n-1} + h \sum_{j=0}^{k-1} \beta_j f(y_n-k+j+1)`

    They are generated using equations (1.13) and (1.7) from 
    [hairer1993]_ III.1, along with the binomial expansion
    and the relation in exercise 4 on p. 367.

    Note that the term "Nystrom method" is also commonly used to refer
    to a class of methods for second-order ODEs; those are NOT
    the methods generated by this function.

    **Examples**::

        >>> import linear_multistep_method as lm
        >>> nys3=lm.Nystrom(6)
        >>> nys3.order()
        6

        References:
            #. [hairer1993]_
    """
    import sympy
    from sympy import Rational

    one = Rational(1,1)

    alpha = snp.zeros(k+1)
    alpha[k] = one
    alpha[k-2] = -one

    beta  = snp.zeros(k+1)
    kappa = snp.zeros(k)
    gamma = snp.zeros(k)
    gamma[0]  =   one
    kappa[0]  = 2*one
    beta[k-1] = 2*one
    betaj = snp.zeros(k+1)
    for j in range(1,k):
        gamma[j] = one-sum(gamma[:j]/snp.arange(j+1,1,-1))
        kappa[j] = 2 * gamma[j] - gamma[j-1]
        for i in range(0,j+1):
            betaj[k-i-1] = (-one)**i*sympy.combinatorial.factorials.binomial(j,i)*kappa[j]
        beta = beta+betaj
    name = str(k)+'-step Nystrom'
    return LinearMultistepMethod(alpha,beta,name=name,shortname='Nys'+str(k))
def Milne_Simpson(k):
    r"""
        Construct the k-step, Milne-Simpson method.
        The methods are implicit and (for k>=3) have order k+1.
        They have the form:

        `y_{n+1} = y_{n-1} + h \sum_{j=0}^{k} \beta_j f(y_n-k+j+1)`

        They are generated using equation (1.15), the equation in 
        Exercise 3, and the relation in exercise 4, all from Hairer & Wanner
        III.1, along with the binomial expansion.

        **Examples**::

            >>> import linear_multistep_method as lm
            >>> ms3=lm.Milne_Simpson(3)
            >>> ms3.order()
            4

        References:
            [hairer1993]_
    """
    import sympy

    alpha = snp.zeros(k+1)
    beta  = snp.zeros(k+1)
    alpha[k] = 1
    alpha[k-2] = -1
    gamma = snp.zeros(k+1)
    kappa = snp.zeros(k+1)
    gamma[0] = 1
    kappa[0] = 2
    beta[k]  = 2
    betaj = snp.zeros(k+1)
    for j in range(1,k+1):
        gamma[j] = -sum(gamma[:j]/snp.arange(j+1,1,-1))
        kappa[j] = 2 * gamma[j] - gamma[j-1]
        for i in range(0,j+1):
            betaj[k-i] = (-1)**i*sympy.combinatorial.factorials.binomial(j,i)*kappa[j]
        beta = beta+betaj
    name = str(k)+'-step Milne-Simpson'
    return LinearMultistepMethod(alpha,beta,name=name,shortname='MS'+str(k))
Example #3
0
def Adams_Bashforth(k):
    r""" 
    Construct the k-step, Adams-Bashforth method.
    The methods are explicit and have order k.
    They have the form:

    `y_{n+1} = y_n + h \sum_{j=0}^{k-1} \beta_j f(y_n-k+j+1)`

    They are generated using equations (1.5) and (1.7) from 
    [hairer1993]_ III.1, along with the binomial expansion.

    **Examples**::

        >>> import linear_multistep_method as lm
        >>> ab3=lm.Adams_Bashforth(3)
        >>> ab3.order()
        3

        References:
            #. [hairer1993]_
    """
    import sympy
    from sympy import Rational

    one = Rational(1,1)

    alpha=snp.zeros(k+1)
    beta=snp.zeros(k+1)
    alpha[k]=one
    alpha[k-1]=-one
    gamma=snp.zeros(k)
    gamma[0]=one
    beta[k-1]=one
    betaj=snp.zeros(k+1)
    for j in range(1,k):
        gamma[j]=one-sum(gamma[:j]/snp.arange(j+1,1,-1))
        for i in range(0,j+1):
            betaj[k-i-1]=(-one)**i*sympy.combinatorial.factorials.binomial(j,i)*gamma[j]
        beta=beta+betaj
    name=str(k)+'-step Adams-Bashforth method'
    return LinearMultistepMethod(alpha,beta,name=name)
Example #4
0
def Adams_Moulton(k):
    r""" 
        Construct the k-step, Adams-Moulton method.
        The methods are implicit and have order k+1.
        They have the form:

        `y_{n+1} = y_n + h \sum_{j=0}^{k} \beta_j f(y_n-k+j+1)`

        They are generated using equation (1.9) and the equation in 
        Exercise 3 from Hairer & Wanner III.1, along with the binomial 
        expansion.

        **Examples**::

            >>> import linear_multistep_method as lm
            >>> am3=lm.Adams_Moulton(3)
            >>> am3.order()
            4

        References:
            [hairer1993]_
    """
    import sympy

    alpha=snp.zeros(k+1)
    beta=snp.zeros(k+1)
    alpha[k]=1
    alpha[k-1]=-1
    gamma=snp.zeros(k+1)
    gamma[0]=1
    beta[k]=1
    betaj=snp.zeros(k+1)
    for j in range(1,k+1):
        gamma[j]= -sum(gamma[:j]/snp.arange(j+1,1,-1))
        for i in range(0,j+1):
            betaj[k-i]=(-1)**i*sympy.combinatorial.factorials.binomial(j,i)*gamma[j]
            #betaj[k-i]=(-1.)**i*comb(j,i)*gamma[j]
        beta=beta+betaj
    name=str(k)+'-step Adams-Moulton method'
    return LinearMultistepMethod(alpha,beta,name=name)
Example #5
0
 def _satisfies_order_conditions(self,p,tol):
     """ Return True if the linear multistep method satisfies 
         the conditions of order p (only) """
     ii=snp.arange(len(self.alpha))
     return abs(sum(ii**p*self.alpha-p*self.beta*ii**(p-1)))<tol