def interp(self, y, eigvals, eigvectors, eigval=1, verbose=False):
        """Interpolate solution eigenvector and it's derivative onto y

        Parameters
        ----------
            y : array
                Interpolation points
            eigvals : array
                All computed eigenvalues
            eigvectors : array
                All computed eigenvectors
            eigval : int, optional
                The chosen eigenvalue, ranked with descending imaginary
                part. The largest imaginary part is 1, the second
                largest is 2, etc.
            verbose : bool, optional
                Print information or not
        """
        N = self.N
        nx, eigval = self.get_eigval(eigval, eigvals, verbose)
        phi_hat = np.zeros(N, np.complex)
        phi_hat[:-4] = np.squeeze(eigvectors[:, nx])

        if not len(self.P4) == len(y):
            SB = Basis(N, 'C', bc='Biharmonic', quad=self.quad)
            self.P4 = SB.evaluate_basis_all(x=y)
            self.T4x = SB.evaluate_basis_derivative_all(x=y, k=1)
        phi = np.dot(self.P4, phi_hat)
        dphidy = np.dot(self.T4x, phi_hat)

        return eigval, phi, dphidy
    def interp(self, y, eigvals, eigvectors, eigval=1, verbose=False):
        """Interpolate solution eigenvector and it's derivative onto y

        Parameters
        ----------
            y : array
                Interpolation points
            eigvals : array
                All computed eigenvalues
            eigvectors : array
                All computed eigenvectors
            eigval : int, optional
                The chosen eigenvalue, ranked with descending imaginary
                part. The largest imaginary part is 1, the second
                largest is 2, etc.
            verbose : bool, optional
                Print information or not
        """
        N = self.N
        nx, eigval = self.get_eigval(eigval, eigvals, verbose)
        phi_hat = np.zeros(N, np.complex)
        phi_hat[:-4] = np.squeeze(eigvectors[:, nx])

        if not len(self.P4) == len(y):
            SB = Basis(N, 'C', bc='Biharmonic', quad=self.quad)
            self.P4 = SB.evaluate_basis_all(x=y)
            self.T4x = SB.evaluate_basis_derivative_all(x=y, k=1)
        phi = np.dot(self.P4, phi_hat)
        dphidy = np.dot(self.T4x, phi_hat)

        return eigval, phi, dphidy
    def assemble(self):
        N = self.N
        SB = Basis(N, 'C', bc='Biharmonic', quad=self.quad)
        SB.plan((N, N), 0, np.float, {})

        x, _ = self.x, self.w = SB.points_and_weights(N)

        # Trial function
        P4 = SB.evaluate_basis_all(x=x)

        # Second derivatives
        T2x = SB.evaluate_basis_derivative_all(x=x, k=2)

        # (u'', v)
        K = np.zeros((N, N))
        K[:-4, :-4] = inner_product((SB, 0), (SB, 2)).diags().toarray()

        # ((1-x**2)u, v)
        xx = np.broadcast_to((1 - x**2)[:, np.newaxis], (N, N))
        #K1 = np.dot(w*P4.T, xx*P4)  # Alternative: K1 = np.dot(w*P4.T, ((1-x**2)*P4.T).T)
        K1 = np.zeros((N, N))
        K1 = SB.scalar_product(xx * P4, K1)
        K1 = extract_diagonal_matrix(
            K1).diags().toarray()  # For improved roundoff

        # ((1-x**2)u'', v)
        K2 = np.zeros((N, N))
        K2 = SB.scalar_product(xx * T2x, K2)
        K2 = extract_diagonal_matrix(
            K2).diags().toarray()  # For improved roundoff

        # (u'''', v)
        Q = np.zeros((self.N, self.N))
        Q[:-4, :-4] = inner_product((SB, 0), (SB, 4)).diags().toarray()

        # (u, v)
        M = np.zeros((self.N, self.N))
        M[:-4, :-4] = inner_product((SB, 0), (SB, 0)).diags().toarray()

        Re = self.Re
        a = self.alfa
        B = -Re * a * 1j * (K - a**2 * M)
        A = Q - 2 * a**2 * K + a**4 * M - 2 * a * Re * 1j * M - 1j * a * Re * (
            K2 - a**2 * K1)
        return A, B
    def assemble(self):
        N = self.N
        SB = Basis(N, 'C', bc='Biharmonic', quad=self.quad)
        SB.plan((N, N), 0, np.float, {})

        x, _ = self.x, self.w = SB.points_and_weights(N)

        # Trial function
        P4 = SB.evaluate_basis_all(x=x)

        # Second derivatives
        T2x = SB.evaluate_basis_derivative_all(x=x, k=2)

        # (u'', v)
        K = np.zeros((N, N))
        K[:-4, :-4] = inner_product((SB, 0), (SB, 2)).diags().toarray()

        # ((1-x**2)u, v)
        xx = np.broadcast_to((1-x**2)[:, np.newaxis], (N, N))
        #K1 = np.dot(w*P4.T, xx*P4)  # Alternative: K1 = np.dot(w*P4.T, ((1-x**2)*P4.T).T)
        K1 = np.zeros((N, N))
        K1 = SB.scalar_product(xx*P4, K1)
        K1 = extract_diagonal_matrix(K1).diags().toarray() # For improved roundoff

        # ((1-x**2)u'', v)
        K2 = np.zeros((N, N))
        K2 = SB.scalar_product(xx*T2x, K2)
        K2 = extract_diagonal_matrix(K2).diags().toarray() # For improved roundoff

        # (u'''', v)
        Q = np.zeros((self.N, self.N))
        Q[:-4, :-4] = inner_product((SB, 0), (SB, 4)).diags().toarray()

        # (u, v)
        M = np.zeros((self.N, self.N))
        M[:-4, :-4] = inner_product((SB, 0), (SB, 0)).diags().toarray()

        Re = self.Re
        a = self.alfa
        B = -Re*a*1j*(K-a**2*M)
        A = Q-2*a**2*K+a**4*M - 2*a*Re*1j*M - 1j*a*Re*(K2-a**2*K1)
        return A, B