def stability_matrix(self, z):
        r"""
            Constructs the stability matrix of a two-step Runge-Kutta method.
            Right now just for a specific value of z.
            We ought to use Sage to do it symbolically.

            **Output**:
                M -- stability matrix evaluated at z

            WARNING: This only works for Type I & Type II methods
            right now!!!
        """
        s = self.Ahat.shape[1]
        if self.type == 'General':
            # J Y^n = K Y^{n-1}
            K1 = np.column_stack((z * self.Ahat, self.d, 1 - self.d))
            K2 = snp.zeros(s + 2)
            K2[-1] = 1
            K3 = np.concatenate(
                (z * self.bhat, np.array((self.theta, 1 - self.theta))))
            K = np.vstack((K1, K2, K3))

            J = snp.eye(s + 2)
            J[:s, :s] = J[:s, :s] - z * self.A
            J[-1, :s] = z * self.b

            M = snp.solve(J.astype('complex64'), K.astype('complex64'))
            #M = snp.solve(J, K) # This version is slower

        else:
            D = np.hstack([1. - self.d, self.d])
            thet = np.hstack([1. - self.theta, self.theta])
            A, b = self.A, self.b
            if self.type == 'Type II':
                ahat = np.zeros([self.s, 1])
                ahat[:, 0] = self.Ahat[:, 0]
                bh = np.zeros([1, 1])
                bh[0, 0] = self.bhat[0]
                A = np.hstack([ahat, self.A])
                A = np.vstack([np.zeros([1, self.s + 1]), A])
                b = np.vstack([bh, self.b])

            M1 = np.linalg.solve(np.eye(self.s) - z * self.A, D)
            L1 = thet + z * np.dot(self.b.T, M1)
            M = np.vstack([L1, [1., 0.]])
        return M
    def stability_matrix(self,z):
        r"""
            Constructs the stability matrix of a two-step Runge-Kutta method.
            Right now just for a specific value of z.
            We ought to use Sage to do it symbolically.

            **Output**:
                M -- stability matrix evaluated at z

            WARNING: This only works for Type I & Type II methods
            right now!!!
        """
        s = self.Ahat.shape[1]
        if self.type == 'General':
            # J Y^n = K Y^{n-1}
            K1 = np.column_stack((z*self.Ahat,self.d,1-self.d))
            K2 = snp.zeros(s+2); K2[-1] = 1
            K3 = np.concatenate((z*self.bhat,np.array((self.theta,1-self.theta))))
            K = np.vstack((K1,K2,K3))

            J = snp.eye(s+2)
            J[:s,:s] = J[:s,:s] - z*self.A
            J[-1,:s] = z*self.b

            M = snp.solve(J.astype('complex64'),K.astype('complex64'))
            #M = snp.solve(J, K) # This version is slower

        else:
            D=np.hstack([1.-self.d,self.d])
            thet=np.hstack([1.-self.theta,self.theta])
            A,b=self.A,self.b
            if self.type=='Type II':
                ahat = np.zeros([self.s,1]); ahat[:,0] = self.Ahat[:,0]
                bh = np.zeros([1,1]); bh[0,0]=self.bhat[0]
                A = np.hstack([ahat,self.A])
                A = np.vstack([np.zeros([1,self.s+1]),A])
                b =  np.vstack([bh,self.b])

            M1=np.linalg.solve(np.eye(self.s)-z*self.A,D)
            L1=thet+z*np.dot(self.b.T,M1)
            M=np.vstack([L1,[1.,0.]])
        return M
def downwind_shu_osher_to_butcher(alpha, alphat, beta, betat):
    r""" Accepts a Shu-Osher representation of a downwind Runge-Kutta
        method and returns the Butcher coefficients

        \\begin{align*}
        A  = & (I-\\alpha_0-\\alphat_0)^{-1} \\beta_0 \\\\
        At = & (I-\\alpha_0-\\alphat_0)^{-1} \\betat_0 \\\\
        b = & \\beta_1 + (\\alpha_1 + \\alphat_1) * A
        \\end{align*}

        **References**:
             #. [gottlieb2009]_
    """
    m = np.size(alpha, 1)
    if not np.all([np.size(alpha, 0), np.size(beta, 0), np.size(beta, 1)] == [m + 1, m + 1, m]):
        raise Exception("Inconsistent dimensions of Shu-Osher arrays")
    X = snp.eye(m) - alpha[0:m, :] - alphat[0:m, :]
    A = snp.solve(X, beta[0:m, :])
    At = snp.solve(X, betat[0:m, :])
    b = beta[m, :] + np.dot(alpha[m, :] + alphat[m, :], A)
    bt = betat[m, :] + np.dot(alpha[m, :] + alphat[m, :], At)
    return A, At, b, bt
Beispiel #4
0
def downwind_shu_osher_to_butcher(alpha, alphat, beta, betat):
    r""" Accepts a Shu-Osher representation of a downwind Runge-Kutta
        method and returns the Butcher coefficients

        \\begin{align*}
        A  = & (I-\\alpha_0-\\alphat_0)^{-1} \\beta_0 \\\\
        At = & (I-\\alpha_0-\\alphat_0)^{-1} \\betat_0 \\\\
        b = & \\beta_1 + (\\alpha_1 + \\alphat_1) * A
        \\end{align*}

        **References**:
             #. [gottlieb2009]_
    """
    m = np.size(alpha, 1)
    if not np.all([np.size(alpha, 0),
                   np.size(beta, 0),
                   np.size(beta, 1)] == [m + 1, m + 1, m]):
        raise Exception('Inconsistent dimensions of Shu-Osher arrays')
    X = snp.eye(m) - alpha[0:m, :] - alphat[0:m, :]
    A = snp.solve(X, beta[0:m, :])
    At = snp.solve(X, betat[0:m, :])
    b = beta[m, :] + np.dot(alpha[m, :] + alphat[m, :], A)
    bt = betat[m, :] + np.dot(alpha[m, :] + alphat[m, :], At)
    return A, At, b, bt