Esempio n. 1
0
def coupling_N(F, P, E, eps, eps_R):
    """Function to evaluate the (N,N) coupling matrix."""
    F = s_to_w(F); P = s_to_w(P); E = s_to_w(E)
    nfz = len(P) - 1
    const_mult = np.conjugate(eps) / eps * (-1) ** nfz
    EF_plus = E + F / eps_R
    EF_plus_conj = const_mult * EF_plus.conj()
    EF_minus = E - F / eps_R
    EF_minus_conj = const_mult * EF_minus.conj()
    y11_Num = 1j * (EF_minus + EF_minus_conj)
    y21_Num = 2j * P / eps
    y_Den = EF_plus - EF_plus_conj
    # The function "signal.residue" takes only 1D arrays!
    resid11, poles11, const11 = signal.residue(y11_Num[:, 0], y_Den[:, 0])
    resid21, poles21, const21 = signal.residue(y21_Num[:, 0], y_Den[:, 0])
    # Gramm_Schmidt orthonormalization
    T1k = np.sqrt(resid11); lambdk = -poles11; TNk = resid21 / T1k
    RS_L1 = sum(T1k ** 2); RL_LN = sum(TNk ** 2)    
    T = np.eye(len(T1k), len(T1k))
    T[0, :] = T1k; T[1, :] = TNk
    np.set_printoptions(precision=6, suppress=True)
    T = Gramm_Schmidt(T) # "normalizing of T1k, TNk" is done in this step
    # swapping the second and last rows after normalization is finished
    temp = np.copy(T[1, :]); T[1, :] = T[-1, :]; T[-1, :] = temp
    Lamb = np.diag(lambdk) # diagonal eigenvalue matrix
    M = np.dot(T, np.dot(Lamb, T.T)) # (N,N) coupling matrix
    return M, RS_L1, RL_LN
Esempio n. 2
0
def coupling_N2(F, P, E, eps, eps_R):
    r"""
    Function to evaluate the (N+2,N+2) coupling matrix.
    
    :param F:       Polynomial F, i.e., numerator of S11 (in s-domain)
    :param P:       Polynomial P, i.e., numerator of S21 (in s-domain)
    :param E:       polynomial E is the denominator of S11 and S21 (in s-domain)
    :param eps:     Constant term associated with S21
    :param eps_R:   Constant term associated with S11
                  
    :rtype:         Returns (N+2,N+2) coupling matrix 
    """
    F = s_to_w(F); P = s_to_w(P); E = s_to_w(E)
    nfz = len(P) - 1; N = len(E) - 1
    const_mult = np.conjugate(eps) / eps * (-1) ** nfz
    EF_plus = E + F / eps_R
    EF_plus_conj = const_mult * EF_plus.conj()
    EF_minus = E - F / eps_R
    EF_minus_conj = const_mult * EF_minus.conj()
    y11_Num = 1j * (EF_minus + EF_minus_conj)
    y21_Num = -2j * P / eps
    y_Den = EF_plus - EF_plus_conj
    # The function "signal.residue" takes only 1D arrays!
    resid11, poles11, const11 = signal.residue(y11_Num[:, 0], y_Den[:, 0])
    resid21, poles21, const21 = signal.residue(y21_Num[:, 0], y_Den[:, 0])
    MSk = np.sqrt(resid11); lambdk = -poles11; MLk = resid21 / MSk
    JSL = -const21
    M = np.zeros((N + 2, N + 2), dtype=complex)
    M[0, 1:N + 1] = np.reshape(MSk, (-1, N))
    M[-1, 1:N + 1] = np.reshape(MLk, (-1, N))
    M[:, 0] = M[0, :]; M[:, -1] = M[-1, :]
    M[0, -1] = JSL[0]; M[-1, 0] = JSL[0]
    diag1 = np.diag(lambdk); M[1:N + 1, 1:N + 1] = diag1
    return M
Esempio n. 3
0
def coupling_N(F, P, E, eps, eps_R):
    r"""
    Function to evaluate the (N,N) coupling matrix.
    
    :param F:       Polynomial F, i.e., numerator of S11 (in s-domain)
    :param P:       Polynomial P, i.e., numerator of S21 (in s-domain)
    :param E:       polynomial E is the denominator of S11 and S21 (in s-domain)
    :param eps:     Constant term associated with S21
    :param eps_R:   Constant term associated with S11
                  
    :rtype:         [M, RS_L1, RL_LN] ... M is the NbyN coupling matrix and RS_L1 and RL_LN
                    are the ratios of RS/L1 and RL/LN.
    """
    N = len(F)
    nfz = len(P)
    if (((N + nfz) % 2 == 0) and (abs(eps.real) > 0)):
        warnings.warn(
            "'eps' value should be pure imaginary when (N+nfz) is an even number"
        )
    elif (((N + nfz + 1) % 2 == 0) and (abs(eps.imag) > 0)):
        warnings.warn(
            "'eps' value should be pure real when (N+nfz) is an odd number")
    F = s_to_w(F)
    P = s_to_w(P)
    E = s_to_w(E)
    nfz = len(P) - 1
    const_mult = np.conjugate(eps) / eps * (-1)**nfz
    EF_plus = E + F / eps_R
    EF_plus_conj = const_mult * EF_plus.conj()
    EF_minus = E - F / eps_R
    EF_minus_conj = const_mult * EF_minus.conj()
    y11_Num = 1j * (EF_minus + EF_minus_conj)
    y21_Num = 2j * P / eps
    y_Den = EF_plus - EF_plus_conj
    # The function "signal.residue" takes only 1D arrays!
    resid11, poles11, const11 = signal.residue(y11_Num[:, 0], y_Den[:, 0])
    resid21, poles21, const21 = signal.residue(y21_Num[:, 0], y_Den[:, 0])
    # Gramm_Schmidt orthonormalization
    T1k = np.sqrt(resid11)
    lambdk = -poles11
    TNk = resid21 / T1k
    RS_L1 = sum(T1k**2)
    RL_LN = sum(TNk**2)
    T = np.eye(len(T1k), len(T1k), dtype='complex')
    T[0, :] = T1k
    T[1, :] = TNk
    np.set_printoptions(precision=6, suppress=True)
    T = Gramm_Schmidt(T)  # "normalizing of T1k, TNk" is done in this step
    # swapping the second and last rows after normalization is finished
    temp = np.copy(T[1, :])
    T[1, :] = T[-1, :]
    T[-1, :] = temp
    Lamb = np.diag(lambdk)  # diagonal eigenvalue matrix
    M = np.dot(T, np.dot(Lamb, T.T))  # (N,N) coupling matrix
    return M, RS_L1, RL_LN
Esempio n. 4
0
def coupling_N(F, P, E, eps, eps_R):
    r"""
    Function to evaluate the (N,N) coupling matrix.
    
    :param F:       Polynomial F, i.e., numerator of S11 (in s-domain)
    :param P:       Polynomial P, i.e., numerator of S21 (in s-domain)
    :param E:       polynomial E is the denominator of S11 and S21 (in s-domain)
    :param eps:     Constant term associated with S21
    :param eps_R:   Constant term associated with S11
                  
    :rtype:         [M, RS_L1, RL_LN] ... M is the NbyN coupling matrix and RS_L1 and RL_LN
                    are the ratios of RS/L1 and RL/LN.
    """
    N = len(F)
    nfz = len(P)
    if ((N + nfz) % 2 == 0) and (abs(eps.real) > 0):
        warnings.warn("'eps' value should be pure imaginary when (N+nfz) is an even number")
    elif ((N + nfz + 1) % 2 == 0) and (abs(eps.imag) > 0):
        warnings.warn("'eps' value should be pure real when (N+nfz) is an odd number")
    F = s_to_w(F)
    P = s_to_w(P)
    E = s_to_w(E)
    nfz = len(P) - 1
    const_mult = np.conjugate(eps) / eps * (-1) ** nfz
    EF_plus = E + F / eps_R
    EF_plus_conj = const_mult * EF_plus.conj()
    EF_minus = E - F / eps_R
    EF_minus_conj = const_mult * EF_minus.conj()
    y11_Num = 1j * (EF_minus + EF_minus_conj)
    y21_Num = 2j * P / eps
    y_Den = EF_plus - EF_plus_conj
    # The function "signal.residue" takes only 1D arrays!
    resid11, poles11, const11 = signal.residue(y11_Num[:, 0], y_Den[:, 0])
    resid21, poles21, const21 = signal.residue(y21_Num[:, 0], y_Den[:, 0])
    # Gramm_Schmidt orthonormalization
    T1k = np.sqrt(resid11)
    lambdk = -poles11
    TNk = resid21 / T1k
    RS_L1 = sum(T1k ** 2)
    RL_LN = sum(TNk ** 2)
    T = np.eye(len(T1k), len(T1k), dtype="complex")
    T[0, :] = T1k
    T[1, :] = TNk
    np.set_printoptions(precision=6, suppress=True)
    T = Gramm_Schmidt(T)  # "normalizing of T1k, TNk" is done in this step
    # swapping the second and last rows after normalization is finished
    temp = np.copy(T[1, :])
    T[1, :] = T[-1, :]
    T[-1, :] = temp
    Lamb = np.diag(lambdk)  # diagonal eigenvalue matrix
    M = np.dot(T, np.dot(Lamb, T.T))  # (N,N) coupling matrix
    return M, RS_L1, RL_LN
Esempio n. 5
0
    def _get_coeff(self, b, a):
        # multiply by 1/s (step)
        a = np.append(a, 0)

        # do partial fraction expansion
        # r: Residues
        # p: Poles
        # k: Coefficients of the direct polynomial term
        r, p, _ = signal.residue(b, a)

        d_s = np.array([])
        d_d_real = np.array([])
        d_d_imag = np.array([])
        d_i = np.array([])

        poles_real = np.array([])
        poles_imag = np.array([])
        integrador = 0
        i = 0
        for i in range(np.size(p)):
            if (p[i] == 0):
                if (integrador):
                    d_i = np.append(d_i, r[i].real)
                else:
                    d_s = np.append(d_s, r[i].real)
                    integrador += 1
            else:
                d_d_real = np.append(d_d_real, r[i].real)
                d_d_imag = np.append(d_d_imag, r[i].imag)
                poles_real = np.append(poles_real, p[i].real)
                poles_imag = np.append(poles_imag, p[i].imag)
        if (d_i.size == 0):
            d_i = np.append(d_i, 0)
        return d_s, d_d_real, d_d_imag, d_i, poles_real, poles_imag
Esempio n. 6
0
 def _get_coeff(self, b, a):
     # multiply by 1/s (step)
     a = np.append(a, 0)
     # do partial fraction expansion
     r, p, k = signal.residue(b, a)
     # r: Residues
     # p: Poles
     # k: Coefficients of the direct polynomial term
     d_s = np.array([])
     # d_d = np.array([])
     d_d = np.zeros(self.na)
     d_i = np.array([])
     poles = np.zeros(self.na)
     integrador = 0
     i = 0
     for i in range(np.size(p)):
         if (p[i] == 0):
             if (integrador):
                 d_i = np.append(d_i, r[i])
             else:
                 d_s = np.append(d_s, r[i])
                 integrador += 1
         else:
             d_d[i] = r[i]
             poles[i] = p[i]
             i += 1
     if (d_i.size == 0):
         d_i = np.append(d_i, 0)
     return d_s, d_d, d_i, poles
Esempio n. 7
0
  def __init__(self, b, a, Ts=1.):
    # multiple roots are not supported
    if ( np.any( sig.unique_roots( np.roots(a) )[1] > 1 ) ):
      raise("Roots with multiplicity > 1 not supported")
    self.b = b;
    self.a = a;

    # Partial Fraction Decomposition
    (r, p, k) = sig.residue(b,a)
    if ( k != 0. ):
      raise("System with direct term not supported ATM")


    # roots in half-plane with imag-part >= 0
    posIP   = np.imag(p) >= 0.0
    r       = r[posIP]
    p       = p[posIP]
	# going into the discrete domain
    P       = np.exp(p*Ts)
    self.PS = list()
    for rp in zip(r,P):
      self.PS.append( firstOrderSys(rp) )

    # must make sure polynomial computation doesn't overflow
    # NOTE: if there are multiple channels then all must be normalized
    #       by the *same* number

    maxResp = self.maxPolyResponse()
    if self.maxPolyResponse() > 1.0:
      raise RuntimeError("Polynomial too large (would overflow); reduce numerator by", maxResp)
Esempio n. 8
0
    def residue(self, tol=1e-3, verbose=0):
        """from scipy.signal.residue:

        Compute residues/partial-fraction expansion of b(s) / a(s).

        If M = len(b) and N = len(a)

                b(s)     b[0] s**(M-1) + b[1] s**(M-2) + ... + b[M-1]
        H(s) = ------ = ----------------------------------------------
                a(s)     a[0] s**(N-1) + a[1] s**(N-2) + ... + a[N-1]

                 r[0]       r[1]             r[-1]
             = -------- + -------- + ... + --------- + k(s)
               (s-p[0])   (s-p[1])         (s-p[-1])

        If there are any repeated roots (closer than tol), then the
        partial fraction expansion has terms like

            r[i]      r[i+1]              r[i+n-1]
          -------- + ----------- + ... + -----------
          (s-p[i])  (s-p[i])**2          (s-p[i])**n

          returns r, p, k
          """
        r,p,k = signal.residue(self.num, self.den, tol=tol)
        if verbose>0:
            print('r='+str(r))
            print('')
            print('p='+str(p))
            print('')
            print('k='+str(k))

        return r, p, k
Esempio n. 9
0
def impinvar(b_in, a_in, fs=1, tol=0.0001):
    """
    # Copyright (c) 2007 R.G.H. Eschauzier <*****@*****.**>
    # Copyright (c) 2011 Carnë Draug <*****@*****.**>
    # Copyright (c) 2011 Juan Pablo Carbajal <*****@*****.**>
    # Copyright (c) 2016 Sascha Eichstädt <*****@*****.**>
    #
    # This program is free software; you can redistribute it and/or modify it under
    # the terms of the GNU General Public License as published by the Free Software
    # Foundation; either version 3 of the License, or (at your option) any later
    # version.
    #
    # This program is distributed in the hope that it will be useful, but WITHOUT
    # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
    # details.
    #
    # You should have received a copy of the GNU General Public License along with
    # this program; if not, see <https://www.gnu.org/licenses/>.
    """

    ts = 1 / fs  # we should be using sampling frequencies to be compatible with Matlab

    [r_in, p_in, k_in] = dsp.residue(b_in, a_in)  # partial fraction expansion

    n = len(r_in)  # Number of poles/residues

    if len(k_in
           ) > 0:  # Greater than zero means we cannot do impulse invariance
        if abs(k_in) > 0:
            raise ValueError("Order numerator >= order denominator")

    r_out = np.zeros(n, dtype=complex)  # Residues of H(z)
    p_out = np.zeros(n, dtype=complex)  # Poles of H(z)
    k_out = np.zeros(1)  # Constant term of H(z)

    i = 0
    while i < n:
        m = 0
        first_pole = p_in[i]  # Pole in the s-domain
        while (i < (n - 1) and np.abs(first_pole - p_in[i + 1]) < tol
               ):  # Multiple poles at p(i)
            i += 1  # Next residue
            m += 1  # Next multiplicity
        [r, p, k] = z_res(r_in[i - m:i + 1], first_pole,
                          ts)  # Find z-domain residues
        k_out += k  # Add direct term to output
        p_out[i - m:i + 1] = p  # Copy z-domain pole(s) to output
        r_out[i - m:i + 1] = r  # Copy z-domain residue(s) to output

        i += 1  # Next s-domain residue/pole

    [b_out, a_out] = dsp.invres(r_out, p_out, k_out, tol=tol)
    a_out = to_real(a_out)  # Get rid of spurious imaginary part
    b_out = to_real(b_out)

    # Shift results right to account for calculating in z instead of z^-1
    b_out = b_out[:-1]

    return b_out, a_out
Esempio n. 10
0
def impinvar(b_in, a_in, fs = 1, tol = 0.0001):
	"""

	## Copyright (c) 2007 R.G.H. Eschauzier <*****@*****.**>
	## Copyright (c) 2011 Carnë Draug <*****@*****.**>
	## Copyright (c) 2011 Juan Pablo Carbajal <*****@*****.**>
	## Copyright (c) 2016 Sascha Eichstaedt <*****@*****.**>
	##
	## This program is free software; you can redistribute it and/or modify it under
	## the terms of the GNU General Public License as published by the Free Software
	## Foundation; either version 3 of the License, or (at your option) any later
	## version.
	##
	## This program is distributed in the hope that it will be useful, but WITHOUT
	## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
	## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
	## details.
	##
	## You should have received a copy of the GNU General Public License along with
	## this program; if not, see <http://www.gnu.org/licenses/>.
	"""

	ts = 1 / fs  # we should be using sampling frequencies to be compatible with Matlab

	[r_in, p_in, k_in] = dsp.residue(b_in, a_in)  # partial fraction expansion

	n = len(r_in)  # Number of poles/residues

	if (len(k_in) > 0):  # Greater than zero means we cannot do impulse invariance
		if abs(k_in)>0:
			raise ValueError("Order numerator >= order denominator")

	r_out = np.zeros(n, dtype = complex)  # Residues of H(z)
	p_out = np.zeros(n, dtype = complex)  # Poles of H(z)
	k_out = np.zeros(n)  # Constant term of H(z)

	i = 0
	while (i < n):
		m = 0
		first_pole = p_in[i]  # Pole in the s-domain
		while (i < (n-1) and np.abs(first_pole - p_in[i + 1]) < tol):  # Multiple poles at p(i)
			i += 1 # Next residue
			m += 1  # Next multiplicity
		[r, p, k] = z_res(r_in[i - m:i+1], first_pole, ts) # Find z-domain residues
		k_out += k  # Add direct term to output
		p_out[i - m:i+1]   = p  # Copy z-domain pole(s) to output
		r_out[i - m:i+1]   = r  # Copy z-domain residue(s) to output

		i += 1  # Next s-domain residue/pole

	[b_out, a_out] = dsp.invres(r_out, p_out, k_out, tol=tol)
	a_out = to_real(a_out)  # Get rid of spurious imaginary part
	b_out = to_real(b_out)

	## Shift results right to account for calculating in z instead of z^-1
	b_out = b_out[:-1]

	return b_out, a_out
Esempio n. 11
0
def coupling_N2(F, P, E, eps, eps_R):
    r"""
    Function to evaluate the (N+2,N+2) coupling matrix.
    
    :param F:       Polynomial F, i.e., numerator of S11 (in s-domain)
    :param P:       Polynomial P, i.e., numerator of S21 (in s-domain)
    :param E:       polynomial E is the denominator of S11 and S21 (in s-domain)
    :param eps:     Constant term associated with S21
    :param eps_R:   Constant term associated with S11
                  
    :rtype:         Returns (N+2,N+2) coupling matrix 
    """
    F = s_to_w(F)
    P = s_to_w(P)
    E = s_to_w(E)
    nfz = len(P) - 1
    N = len(E) - 1
    const_mult = np.conjugate(eps) / eps * (-1) ** nfz
    EF_plus = E + F / eps_R
    EF_plus_conj = const_mult * EF_plus.conj()
    EF_minus = E - F / eps_R
    EF_minus_conj = const_mult * EF_minus.conj()
    y11_Num = 1j * (EF_minus + EF_minus_conj)
    y21_Num = -2j * P / eps
    y_Den = EF_plus - EF_plus_conj
    # The function "signal.residue" takes only 1D arrays!
    resid11, poles11, const11 = signal.residue(y11_Num[:, 0], y_Den[:, 0])
    resid21, poles21, const21 = signal.residue(y21_Num[:, 0], y_Den[:, 0])
    MSk = np.sqrt(resid11)
    lambdk = -poles11
    MLk = resid21 / MSk
    JSL = -const21
    M = np.zeros((N + 2, N + 2), dtype=complex)
    M[0, 1 : N + 1] = np.reshape(MSk, (-1, N))
    M[-1, 1 : N + 1] = np.reshape(MLk, (-1, N))
    M[:, 0] = M[0, :]
    M[:, -1] = M[-1, :]
    M[0, -1] = JSL[0]
    M[-1, 0] = JSL[0]
    diag1 = np.diag(lambdk)
    M[1 : N + 1, 1 : N + 1] = diag1
    return M
Esempio n. 12
0
 def green_components(self):
     mult = {}
     simple_decomp_coeffs, poles, k = residue(self.Q, self.P)
     components = []
     for i, p in enumerate(poles):
         if p in mult:
             mult[p] += 1
         else:
             mult[p] = 1
         m = mult[p]
         components.append((simple_decomp_coeffs[i], m, p))
     return components
Esempio n. 13
0
def gpa_72aa_pf(alf):
    '''
    This code computes the residues (weights) and poles of the partial fraction 
    decomposition of the global Pad\'e approximant, type (7,2) for \alpha = \beta.
    
    Signature: gpa_72aa_pf(alf)
               
    Parameters: alf 
                positive number in (0, 1)
    
    Returns: r : ndarray
                 Residues (or Weights).
             p : ndarray
                 Poles
         The partial fraction decomposition can be assumed to take the form
         r[0]       r[1]        r[2]         r[3]
       -------- + -------- +  ---------  + ---------
       (s-p[0])   (s-p[1])    (s-p[2])     (s-p[3])  
    '''
    a = gamma(-alf)/gamma(alf)
    b = gamma(-alf)/gamma(2*alf)
    c = gamma(-alf)/gamma(3*alf)
    d = gamma(-alf)/gamma(4*alf)
    e = gamma(-alf)/gamma(5*alf)
    f = gamma(-alf)/gamma(-2*alf)
    
    p2 = a*(a**4 - 2*a**2*c - a**2*d*f + 2*a*b**2 + 2*a*b*c*f - b**3*f - b*d + 
    c**2)/(a**3*e - 2*a**2*b*d - a**2*c**2 + 3*a*b**2*c - a*c*e + a*d**2 - b**4 
    + b**2*e - 2*b*c*d + c**3)
    
    p3 = (-a*b*e + a*c*d - a*(a**2*d - 2*a*b*c + b**3) + b**2*d - b*c**2 + 
    f*(-a**3*e + 2*a**2*b*d + a**2*c**2 - 3*a*b**2*c + b**4))/(a**3*e - 
    2*a**2*b*d - a**2*c**2 + 3*a*b**2*c - a*c*e + a*d**2 - b**4 + b**2*e - 
    2*b*c*d + c**3)
    
    q0 = (a**2*c - a*b**2 - a*(a**3 - a*c + b**2) + b*d - c**2 + f*(a**2*d - 
    2*a*b*c + b**3))/(a**3*e - 2*a**2*b*d - a**2*c**2 + 3*a*b**2*c - a*c*e + 
    a*d**2 - b**4 + b**2*e - 2*b*c*d + c**3)
    
    q1 = (-a**3*b + a**2*d + a**2*e*f - a*b*d*f - a*c**2*f - b**3 + b**2*c*f + 
    b*e - c*d)/(a**3*e - 2*a**2*b*d - a**2*c**2 + 3*a*b**2*c - a*c*e + a*d**2 - 
    b**4 + b**2*e - 2*b*c*d + c**3)
    
    q2 = (-a**2*e + 2*a*b*d + a*(a**2*c - a*b**2 + b*d - c**2) - b**2*c + c*e - 
    d**2 + f*(a*b*e - a*c*d - b**2*d + b*c**2))/(a**3*e - 2*a**2*b*d - a**2*c**2
    + 3*a*b**2*c - a*c*e + a*d**2 - b**4 + b**2*e - 2*b*c*d + c**3)
    
    q3 = (-a*b*e + a*c*d - a*(a**2*d - 2*a*b*c + b**3) + b**2*d - b*c**2 + 
    f*(-a*c*e + a*d**2 + b**2*e - 2*b*c*d + c**3))/(a**3*e - 2*a**2*b*d - 
    a**2*c**2 + 3*a*b**2*c - a*c*e + a*d**2 - b**4 + b**2*e - 2*b*c*d + c**3)
    
    return residue([0,0,1,p3,p2],[-gamma(-alf), -gamma(-alf)*q3, 
    -gamma(-alf)*q2, -gamma(-alf)*q1, -gamma(-alf)*q0])
Esempio n. 14
0
def gpa8_13_4_ml_pf(alf, bet):
    coeff = gpa8_13_4_ml_coff(alf, bet)

    num = [
        1, coeff[6, 0], coeff[5, 0], coeff[4, 0], coeff[3, 0], coeff[2, 0],
        coeff[1, 0], coeff[0, 0]
    ]
    denum = gamma(bet - alf) * np.array([
        1, coeff[14, 0], coeff[13, 0], coeff[12, 0], coeff[11, 0],
        coeff[10, 0], coeff[9, 0], coeff[8, 0], coeff[7, 0]
    ])

    return residue(num, denum)
Esempio n. 15
0
 def _order(self):
     H = self.H
     na = np.zeros((self.ny, self.nu), dtype='int')
     for i in range(self.ny):
         for j in range(self.nu):
             try:
                 b = H[i, j].num
                 a = H[i, j].den
                 _, p, _ = signal.residue(b, a)
                 na[i, j] = (p != 0).sum()
             except:
                 na[i, j] = 0
     return na
def LinearRecurrenceSequence(name, size, a, b, c=[1], d=[]):
    print('Name: {}\n'.format(name))
    print(
        'Type: {}'.format('non-homogeneous' if len(d) > 0 else 'homogeneous'))
    print('Degree: {}'.format(len(a)))
    print()
    print('Recurrence coefficients')
    print('a: ', a)
    print('Initial conditions')
    print('b: ', b)
    print()
    if len(d) != 0:
        print('Non-homogeneous rational polynomials')
        print('QI:')
        print(np.poly1d(c))
        print('PI:')
        print(np.poly1d(d))
        print()
    P, Q = CreateG(a, b, c, d)
    print('Generating function')
    print('P:')
    print(P)
    print('Q:')
    print(Q)
    r, p, h = signal.residue(P.c, Q.c)
    print()
    print('Partial fraction expantion')
    print('residue (r)  : ')
    print(r)
    print('poles: (eta) : ')
    print(p)
    print('remainder (h): ')
    print(h)
    print()
    if len(d) > 0 and len(h) == 1 and h[0] == 0:
        print('Can be reduce to homogeneous type')
        print('Recurrence coefficients')
        print('a: ', [-x for x in Q.c[-2::-1]])
        print('Initial conditions')
        print(
            'b: ',
            [EvalCloseForm(r, p, h, n, format='real') for n in range(len(p))])
    print()
    print('Sequence ({})'.format(size))
    for n in range(size):
        print(EvalCloseForm(r, p, h, n), end=', ')
    print()
    print()
    print('------------------------')
    print()
Esempio n. 17
0
def coupling_N2(F, P, E, eps, eps_R):
    """Function to evaluate the (N+2,N+2) coupling matrix."""
    F = s_to_w(F); P = s_to_w(P); E = s_to_w(E)
    nfz = len(P) - 1; N = len(E) - 1
    const_mult = np.conjugate(eps) / eps * (-1) ** nfz
    EF_plus = E + F / eps_R
    EF_plus_conj = const_mult * EF_plus.conj()
    EF_minus = E - F / eps_R
    EF_minus_conj = const_mult * EF_minus.conj()
    y11_Num = 1j * (EF_minus + EF_minus_conj)
    y21_Num = -2j * P / eps
    y_Den = EF_plus - EF_plus_conj
    # The function "signal.residue" takes only 1D arrays!
    resid11, poles11, const11 = signal.residue(y11_Num[:, 0], y_Den[:, 0])
    resid21, poles21, const21 = signal.residue(y21_Num[:, 0], y_Den[:, 0])
    MSk = np.sqrt(resid11); lambdk = -poles11; MLk = resid21 / MSk
    JSL = -const21
    M = np.zeros((N + 2, N + 2), dtype=complex)
    M[0, 1:N + 1] = np.reshape(MSk, (-1, N))
    M[-1, 1:N + 1] = np.reshape(MLk, (-1, N))
    M[:, 0] = M[0, :]; M[:, -1] = M[-1, :]
    M[0, -1] = JSL[0]; M[-1, 0] = JSL[0]
    diag1 = np.diag(lambdk); M[1:N + 1, 1:N + 1] = diag1
    return M
Esempio n. 18
0
def find_exp_decay(t, data, n, p0=None, t0=None, removebg=True):
    background = 0
    if removebg:
        background = np.median(data[-1000:])
        data = data - background
    if p0 is None:
        p0 = 1 / (t[np.argmin(abs(data - max(data) / 2))] - t[0])
        print('p0 : %.4e' % p0)
    if t0 is None:
        t0 = t[0]
    dis = Calculate_di(t - t0, data, p0, n)
    bis = Calculate_bi(dis)
    ais = Calculate_ai(bis, dis)
    A, gamma, _ = signal.residue(np.flip(ais),
                                 np.concatenate((np.flip(bis), [1])))
    gamma = abs(gamma) - p0
    #    error = np.sum((decay(t,A,gamma,t0,background)-(data+background))**2/(data+background))
    error = R2(data + background, decay(t, A, gamma, t0, background))
    return A, gamma, t0, background, error
Esempio n. 19
0
    def debug_plot(self, h_step, dt, ps, zs, scale):
        t = np.array(range(len(h_step))) * dt

        zs = zs[np.isfinite(zs)]
        ps = ps[np.isfinite(ps)]

        from scipy.signal import residue
        r, p, k = residue(np.poly(zs), np.poly(ps))

        h_step_est = np.zeros(h_step.shape)
        for coef, pole in zip(r, p):
            h_step_est = h_step_est + scale * coef * np.exp(pole*t)
            print('Added coef', scale*coef, 'for pole', pole)

        plt.figure()
        plt.plot(t, h_step, '--+')
        plt.plot(t, h_step_est, '-+')
        plt.legend(['Step response', 'Fit'])
        plt.grid()
        plt.show()
        pass
Esempio n. 20
0
print(fs)

cutoff_freq = 4000.0

Wn = 1.5 * cutoff_freq / sampl_freq

b, a = signal.butter(order, Wn, 'low')

output_signal = signal.filtfilt(b, a, input_signal)

sf.write('Sound_with_Reduced_Noise.wav', output_signal, fs)

input_signal, ft = sf.read('Sound_with_Reduced_Noise.wav')
print(ft)

r, p, k = signal.residue(b, a, tol=0.001, rtype='avg')
print(r)
print(p)
print(k)
print(b)
x = range(500)
plt.xlim(0, 500)
hn = [0]

for j in range(500):
    t = 0
    for i in range(4):
        t += r[i] * p[i]**j
    hn.append(t)

plt.plot(hn)
Esempio n. 21
0
def compute_RationalApproximation_AAA_new(alpha, beta=None, MaxOrder=100, tol = 1.e-12, nPoints = 1000, verbose=False):

    # deal with divisions by zero
    np.seterr(divide='ignore', invalid='ignore')

    if beta:
        func = lambda x: x**(1-alpha) * (x-1)**(-beta)
    else:
        func = lambda x: x**(1-alpha)

    M = nPoints
    Z = np.linspace(1+1.e-3, 1000, M).reshape([M,1])
    M = Z.size
    F = func(Z)
    SF = scipy.sparse.spdiags(F.flatten(),0,M,M)
    J = np.arange(M)
    z = np.array([]).reshape([0,1])
    f = np.array([]).reshape([0,1])
    C = np.array([]).reshape([M,0])
    errvec = np.array([])
    R = np.mean(F)*np.ones_like(F)
    for m in range(MaxOrder):
        j = np.argmax(np.abs(F-R))
        z = np.vstack([z, Z[j]])
        f = np.vstack([f, F[j]])
        J = J[J!=j]
        C = np.hstack([ C, 1/(Z-Z[j]) ])
        Sf = np.diag(f.flatten())
        A = SF @ C - C @ Sf
        U,S,V = scipy.linalg.svd(A[J,:])
        w = V[m,:].reshape([-1,1])
        N = C @ (w*f)
        D = C @ w
        R[:] = F
        R[J] = N[J]/D[J]
        err = np.linalg.norm(F-R, ord=np.inf)
        errvec = np.append(errvec, err)
        if verbose: print(err)
        if err <= tol: break
    if verbose: print('degree',m)


    m = w.size
    B = np.eye(m+1)
    B[0,0] = 0
    E = np.block([ [ 0, w.reshape([1,m]) ], [ np.ones([m,1]), np.diag(z.flatten()) ] ])
    pol = scipy.linalg.eig(E,B, left=False, right=False)
    pol = pol[~np.isinf(pol)]
    E = np.block([ [ 0, (w*f).reshape([1,m]) ], [ np.ones([m,1]), np.diag(z.flatten()) ] ])
    zer = scipy.linalg.eig(E,B, left=False, right=False)
    zer = zer[~np.isinf(zer)]

    assert( np.all(np.isclose(np.imag(zer),0)) )
    assert( np.all(np.isclose(np.imag(pol),0)) )

    pc0 = np.sum(w*f)
    pd0 = np.sum(w)

    pc = np.poly(zer)
    pd = np.poly(pol)

    pd = np.append(pd, 0)

    c, d, k = residue(pc, pd)
    assert(all(k==0))

    d = -d
    c *= pc0/pd0

    # x = np.linspace(100, 1000, 10000)
    # plt.plot(x, [ np.sum(c/(z+d)) - func(z)/z for z in x] )
    # plt.show()

    return c, d
Esempio n. 22
0
plt.plot(t,y)
plt.grid(True)
plt.ylabel('y(t)')
plt.title('Hand Solved y(t)')

plt.subplot(2,1,2)
plt.plot(tout, yout)
plt.grid(True)
plt.ylabel('y(t)')
plt.title('y(t) using sig.step()')

plt.show();
denH = [1,10,24,0]

print('Part 1:')
r,p,_ = sig.residue(numH, denH, tol=1e-3)
print('r='+str(r))
print('')
print('p='+str(p))




##-----------------------------Part 2 -----------------------------------##
print('')
print('Part 2:')
numH = [0,0,0,0,0,25250]
denH = [1,18,218,2036,9085,25250,0]
r,p,_ = sig.residue(numH, denH, tol=1e-3)
print('r='+str(r))
print('')
input_signal , fs = sf.read('Sound_Noise.wav')
sampl_freq = fs
order = 4
cutoff_freq = 4000.0

Wn = 2*cutoff_freq/sampl_freq

b,a = signal.butter(order,Wn,'low')

output_signal = signal.filtfilt(b,a,input_signal)

b = b[::-1]
a = a[::-1]


r, p,k = signal.residue(b,a)

n = np.linspace(0,30)
h = []
for i in range(0,30):
    s = 0
    for j in range(0,order):
        s = s - r[j]/(p[j]**(i+1))
    if (i==0):
        s=s+k[0]
    h.append(np.real(s))

y1=np.convolve(input_signal,h)
y = []
for i in range(0,input_signal.size):
     s = 0
Esempio n. 24
0
tout, yout = sig.step((num, den), T=t)

plt.figure(figsize=(10, 7))
plt.plot(tout, yout)
plt.grid()
plt.xlabel('t [s]')
plt.ylabel('x(t)')
plt.title('Python sig.step')

#%% Part 1 Task 3

num = [1, 6, 12]
den = [1, 10, 24, 0]

[R, P, _] = sig.residue(num, den)
print("R1 =", R, "\nP1 = ", P)

#%% Part 2 Task 1

num = [25250]
den = [1, 18, 218, 2036, 9085, 25250, 0]

[R, P, _] = sig.residue(num, den)
print("\nR2 =", R, "\nP2 = ", P)

#%% Part 2 Task 2


def cos2_method(R, P, t):
    y = 0
plt.subplot(2,1,2)
plt.plot(tout, yout)
plt.grid()
plt.ylabel('y(t), python')
plt.ylim([0,1])



plt.xlabel('Time')
plt.show()


num = [1,6,12]
den = [1, 10,24,0]

R, P, _ = sig.residue(num,den)

print (R,P)



#%%Part 2


num = [25250]
den = [1,18,218,2036,9085,25250,0]

R, P, _ = sig.residue(num,den)

print (R,P)
def partial_fraction_expansion(b, a):
    "Return the pole, residue, and polynomial of a partial fraction expansion"

    return signal.residue(b, a)
Esempio n. 27
0
plt.xlabel('time (s)')
plt.show()
tout2, yout2 = sig.step((num, den), T=t)
myFigSize = (10, 10)
plt.figure(figsize=myFigSize)
plt.plot(tout2, yout2)
plt.grid(True)
plt.ylabel('Coded Step Response')
plt.title('Part 1')
plt.xlabel('time (s)')
plt.show()

num2 = [1, 6, 12]
den2 = [1, 10, 24, 0]
[R, P, _] = sig.residue(num2, den2)  #partial fraction expansion
print(R)
print(P)

#---------------------------Part 2-------------------------------------------#
num3 = [25250]
den3 = [1, 18, 218, 2036, 9085, 25250, 0]
[R, P, _] = sig.residue(num3, den3)
print(R)
print(P)


def cosine(R, P, t):
    y = np.zeros(t.shape)
    for i in range(len(R)):  #goes through entire range of fraction expansion
        a = P[i].real  #real part using alpha variable
def find_sysd_impulse(Ts,sys): #Find the discrete-time transfer function for the impulse invariant method
    #Partial Fraction Decomposition
    N = sys.num[0][0].tolist()
    D = sys.den[0][0].tolist()
    R,P,k = signal.residue(N,D)
    valc = abs(sys.horner(0)[0][0])
    r = []
    p = []
    for l in range(len(P)):
        r.append(R[l])
        p.append(P[l])
    sysd = 0
    #Construct transfer function
    z = Symbol('z')
    k = 0
    poles = []
    while k < len(p):
        b = p[k]
        a = exp(b*Ts)
        number = p.count(b)
        for t in range(number):
            poles.append(a)
        if number == 1:
            c = r[k]
            new = (Ts*c*z)/(z-a)
            sysd = sysd + new
        if number == 2:
            c1 = r[k]
            c2 = r[k+1]
            new = (Ts*c1*z)/(z-a) + ((Ts**2)*c2*a*z)/(z**2 -2*a*z+a**2)
            sysd = sysd + new
        if number == 3:
            c1 = r[k]
            c2 = r[k+1]
            c3 = r[k+2]
            new = (Ts*c1*z)/(z-a) + ((Ts**2)*c2*a*z)/(z**2 -2*a*z+a**2) + ((Ts**3)*c3*a*(z**2)*(1/2) + (Ts**3)*(1/2)*c3*(a**2)*z)/((z**3)-a*(z**2)+(a**2)*z-(a**3))
            sysd = sysd + new
        if number == 4:
            c1 = r[k]
            c2 = r[k+1]
            c3 = r[k+2]
            c4 = r[k+3]
            new = (Ts*c1*z)/(z-a) + ((Ts**2)*c2*a*z)/(z**2 -2*a*z+a**2) + ((Ts**3)*c3*a*(z**2)*(1/2) + (Ts**3)*(1/2)*c3*(a**2)*z)/((z**3)-a*(z**2)+(a**2)*z-(a**3)) + ((Ts**4)*(1/6)*c4*a*(z**3)+4*(Ts**4)*(1/6)*c4*(a**2)*(z**2)+(Ts**4)*(1/6)*c4*(a**3)*z)/((z**4)-4*a*(z**3)+6*(a**2)*(z**2)-4*z*(a**3)+(a**4))
            sysd = sysd + new
        k = k + number
    func = sysd
    gfun = sysd
    #Compute gain
    for n in range(len(poles)):
        func = func * (z-poles[n])
    zeros = solve(func, z)
    num,den = signal.zpk2tf(zeros,poles,1)
    num = num.tolist()
    den = den.tolist()
    for k in range(len(num)):
        try:
            num[k] = float(num[k])
        except:
            num[k] = num[k]
    for k in range(len(den)):
        try:
            den[k] = float(den[k])
        except:
            den[k] = den[k]
    sysd = TransferFunction(num,den)
    gain = gfun.subs(z,1)/sysd.horner(1)[0][0]
    #Construct final version
    num,den = signal.zpk2tf(zeros,poles,gain)
    num = num.tolist()
    den = den.tolist()
    for k in range(len(num)):
        try:
            num[k] = float(num[k])
        except:
            num[k] = num[k]
    for k in range(len(den)):
        try:
            den[k] = float(den[k])
        except:
            den[k] = den[k]
    sysd = TransferFunction(num,den,Ts)
    return sysd
Esempio n. 29
0
def rfp(frf, omega, denom_order, numer_order):
    """Computes estimates for the modal parameters of the given FRF, in the
    frequency range given by omega, utilizing polynomials of order "numer_order"
    and "denom_order", and following the RFP method as described by Richardson and
    Formenti [1].

    Arguments:
        frf (numpy complex array):
            - Frequency Response Function vector (receptance).
        omega (numpy array):
            - Angular velocity range (rad/s)
        - denom_order (int):
            - Order of the denominator polynomial.
        - numer_order (int):
            - Order of the numerator polynomial.

    Returns:
        modal_params (array list):
            - Modal parameter  for the estimated FRF Modal parameter list:
                [freq_n, xi_n, modal_mag_n, modal_ang_n]
        alpha (numpy complex array):
            - Estimated receptance FRF in the given frequency range.

    [1] Richardson, M. H. & Formenti D. L. "Parameter estimation from frequency
    response measurements using rational fraction polynomials", 1st IMAC Conference,
    Orlando, FL, 1986.
    """

    omega_norm = omega / np.max(omega)  # omega normalization
    m = numer_order  # number of polynomial terms in numerator
    n = denom_order  # number of polynomial terms in denominator
    d = np.zeros(n + 1)  # Orthogonal denominator polynomial coefficients

    # computation of Forsythe orthogonal polynomials
    Phi, Gamma_phi = forsythe_polys_rfp(omega_norm, np.ones(len(omega_norm)),
                                        m)
    Theta, Gamma_theta = forsythe_polys_rfp(omega_norm, np.abs(frf)**2, n)

    T = np.diag(frf) @ Theta[:, :-1]
    W = frf * Theta[:, -1]
    X = -2 * np.real(Phi.T.conj() @ T)
    H = 2 * np.real(Phi.T.conj() @ W)

    d[:-1] = -np.linalg.inv(np.eye(X.shape[1]) - X.T @ X) @ X.T @ H
    d[-1] = 1
    c = H - X @ d[:-1]  # Orthogonal numerator polynomial coefficients

    # calculation of the estimated FRF (alpha)
    numer = Phi @ c
    denom = Theta @ d
    alpha = numer / denom

    a = np.flipud(Gamma_phi @ c)  # Standard polynomial numerator coefficients
    b = np.flipud(
        Gamma_theta @ d)  # Standard polynomial denominator coefficients

    # Calculation of the poles and residues
    res, pol, _ = signal.residue(a, b)
    residues = res[::2] * np.max(omega)
    poles = pol[::2] * np.max(omega)

    freq_n = np.abs(poles) / 2 / np.pi  # Natural frequencies (rad/sec)
    xi_n = -np.real(poles) / np.abs(poles)  # Damping ratios
    modal_const = 1j * 2 * residues * np.imag(poles)
    modal_mag_n = np.abs(modal_const)  # Modal constant magnitude
    modal_ang_n = np.angle(modal_const)  # Modal constant phase

    modal_params = [freq_n, xi_n, modal_mag_n, modal_ang_n]  # Modal Parameters

    return modal_params, alpha
Esempio n. 30
0
def grfp_parameters(frf, omega, denom, denom_coeff, numer_order):
    """Computes an estimate of the modal parameters for each of the FRFs given by
    the columns of "frf", which correspond to the frequency range given by omega,
    following the GRFP method described by Richardson and Formenti [1]. It is assumed
    that "numer_order" is the order of the numerator polynomial, and that the common
    denominator polynomial shared by all the FRFs is given by "denom", formed by the
    coefficients "denom_coeff".

    Arguments:
        - frf (numpy complex array):
            - Frequency Response Function matrix. Each column contains the FRF
            for a particular DOF, with all of them corresponding the reference or
            input DOF.
        - omega (numpy array):
            - Angular velocity range (rad/s).
        - denom (numpy array):
            - Common denominator polynomial shared by all the FRFs.
        - denom_coeff (numpy array):
            - Coefficients that form the "denom" polynomial.
        - numer_order (int):
            - Order of the numerator polynomial.

    Returns:
        modal_params (array list):
            - Modal parameter  for the estimated FRF Modal parameter list:
                [freq_n, xi_n, modal_mag_n, modal_ang_n]

    [1] Richardson, M. H. & Formenti, D. L. "Global curve fitting of frequency response
    measurements using the Rational Fraction Polynomial method", 3rd IMAC Conference,
    Orlando, FL, 1985.
    """

    m = numer_order
    n_dof = frf.shape[1]  # number of frf measurements (degrees of freedom)
    w_norm = omega / np.max(omega)  # normalized angular frequency range
    w_j = 1j * w_norm  # complex normalized angular frequency range
    total_poles = len(
        denom_coeff
    ) - 1  # number of residues and poles expected in the solution
    c = np.zeros(
        (m + 1, n_dof))  # orthogonal numerator polynomial coefficients
    # standard numerator polynomial coefficients
    numer_coef = np.zeros((m + 1, n_dof), dtype=complex)
    numer = np.zeros((len(w_norm), n_dof),
                     dtype=complex)  # numerator polynomials
    alpha = np.zeros((len(w_norm), n_dof), dtype=complex)  # FRF estimations
    residues_norm = np.zeros((total_poles, n_dof),
                             dtype=complex)  # frecuency-normalized residues
    poles_norm = np.zeros((total_poles, n_dof),
                          dtype=complex)  # frequency-normalized poles

    Z, Gamma_phi = forsythe_polys_rfp(w_norm, np.abs(1 / denom)**2, m)
    X = np.diag(1 / denom) @ Z
    for dof in range(n_dof):
        c[:, dof] = 2 * np.real(X.conj().T @ frf[:, dof])
        numer_coef[:, dof] = np.flipud(Gamma_phi @ c[:, dof])
        numer[:, dof] = np.polyval(numer_coef[:, dof], w_j)
        alpha[:, dof] = numer[:, dof] / denom
        residues_norm[:, dof], poles_norm[:, dof], _ = signal.residue(
            numer_coef[:, dof], denom_coeff)

    xi_n_raw = -np.real(poles_norm * np.max(omega)) / np.abs(
        poles_norm * np.max(omega))
    # modes with unitary damping coefficient are discarded
    physical_modes_idx = (abs(xi_n_raw[:, 0]) != 1)
    residues = residues_norm[physical_modes_idx, :][::2] * np.max(omega)
    poles = poles_norm[physical_modes_idx, :][::2] * np.max(omega)

    freq_n = np.abs(poles[:, 0]) / 2 / np.pi
    xi_n = -np.real(poles[:, 0]) / np.abs(poles[:, 0])
    modal_const = 1j * 2 * residues * np.imag(poles)
    modal_mag_n = np.abs(modal_const)  # Modal constant magnitude
    modal_ang_n = np.angle(modal_const)  # Modal constant phase

    modal_params = [freq_n, xi_n, modal_mag_n, modal_ang_n]
    return modal_params, alpha
Esempio n. 31
0
plt.grid(True)
plt.ylabel('h(t)')
plt.title('Step response of system')

plt.subplot(2, 1, 2)
plt.plot(t, y2)
plt.grid(True)
plt.ylabel('sig.step')
#plt.title('')

plt.show()

H = ([1, 6, 12], [1, 10, 24, 0])

#partial fraction expansion of H
(r, p, k) = sig.residue(H[0], H[1])

for i in range(len(r)):
    print('\n', '\nr[', i, ']=', r[i], '\np[', i, ']=', p[i], '\n')

#Part 2
t = np.arange(0, 4.5 + stepsize, stepsize)

d = [1, 18, 218, 2036, 9085, 25250]
n = [25250]

(Tr, y2) = sig.step((n, d), T=t)

#plt.figure(figsize=fullsize_figure)

plt.subplots_adjust(top=2, bottom=0)
Esempio n. 32
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from scipy.signal import residue

print residue([2,5,3,6], [1,6,11,6])
Esempio n. 33
0
def partial_fraction_expansion(b, a):
    "Return the pole, residue, and polynomial of a partial fraction expansion"

    return signal.residue(b, a)
Esempio n. 34
0
# -*- coding: utf-8 -*-
"""
Created on Sat Dec 09 23:55:31 2017

@author: Rocky
"""

from scipy.signal import residue 
b = [2,0.8,0.5,0.3]
a = [1,0.8,0.2]

r,p,k=residue(b,a)
x = [1,0,0,0,0,0,0,0,0,0,0]
print ('Residues=', r)
print ('Poles=',p)
print ('Coefficients of the direct polynomial term=',k)
Esempio n. 35
0
# print apart(Zs, Zs, s)
#
# #print ilt(apart(Xs, s), s, t)
# #print ilt(apart(Ys, s), s, t)
# #print ilt(apart(Zs, s), s, t)
#
# print ilt(Xs, s, t)

x_num = [2, 1]
x_den = [1, 5, 6]
y_num = [5, 3, 2]
y_den = [1, 3, 9, 7]
z_num = [1]
z_den = [2, 5, 0]

x_residues, x_poles, _ = residue(x_num, x_den)
y_residues, y_poles, _ = residue(y_num, y_den)
z_residues, z_poles, _ = residue(z_num, z_den)

print "Residues X: ", x_residues
print "Poles X: ", x_poles
print "Residues Y: ", y_residues
print "Poles Y: ", y_poles
print "Residues Z: ", z_residues
print "Poles Z: ", z_poles

tLen = 5
t = np.arange(-1, tLen, tStep)
x = np.zeros(t.size)
y = np.zeros(t.size)
z = np.zeros(t.size)
Esempio n. 36
0
def RFP(rec, omega, N):

    x = np.shape(omega)
    if x == 1:
        omega = np.transpose(omega)

    x = np.shape(rec)
    if x == 1:
        rec = np.transpose(rec)
    # normalizacja danych
    nom_omega = np.max(omega)
    omega = omega / nom_omega

    m = 2 * N - 1  # licznik
    n = 2 * N  # mianownik

    #  stworzenie wielomanów ortogonalnych
    [phimatrix, coeff_a] = orthogonal(rec, omega, 1, m)
    [thetamatrix, coeff_b] = orthogonal(rec, omega, 2, n)

    [x, y] = np.shape(phimatrix)
    Phi = phimatrix[:, 0:x]

    [x, y] = np.shape(thetamatrix)
    Theta = thetamatrix[:, 0:x]

    T = np.diag(rec) @ thetamatrix[:, 0:y - 1]

    W = rec * thetamatrix[:, y - 1]

    X = -2.0 * np.real(np.conj(np.transpose(Phi)) @ T)
    G = 2.0 * np.real(np.conj(np.transpose(Phi)) @ W)
    [x, y] = np.shape(X)

    d = -1.0 * np.linalg.inv(np.eye(x, y) -
                             np.transpose(X) @ X) @ np.transpose(X) @ G

    C = G - X @ d
    D = np.append(d, 1.0)  #dodanie jedynki na koniec append?

    alfa = np.zeros(len(omega), dtype=complex)

    #  obliczenie aproksymowanej charakterystyki
    for i in range(len(omega)):
        numer = np.sum(np.transpose(C) * Phi[i, :])
        denom = np.sum(np.transpose(D) * Theta[i, :])
        alfa[i] = np.true_divide(numer, denom)

    A = coeff_a @ C
    A = np.transpose(A[::-1])  #  standaryzowane wspolczynniki licznika

    B = coeff_b @ D
    B = np.transpose((B[::-1]))  #  standaryzowane wspolczynniki mianownika

    [R, P, K] = residue(A, B)  # obliczenie reszt i biegunow

    #  odrzucenie biegunow lezacych w zakresie ujemnych czestosci
    x = int(len(R))
    ii = 0
    Resi = np.zeros((int(x), 1), dtype=complex)
    Pole = np.copy(Resi)
    for i in range(int(x)):
        if P[i].imag >= 0:
            Resi[ii] = R[i]
            Pole[ii] = P[i]
            ii += 1
    for i in range(int(x) - 1, -1, -1):
        if np.abs(Pole[i]) == 0:
            Resi = np.delete(Resi, i)
            Pole = np.delete(Pole, i)

    #  denormalizacja danych
    Resi = Resi * nom_omega
    Pole = Pole * nom_omega

    return Resi, Pole, alfa
Esempio n. 37
0
y = np.array([-1, 2, 2, -2, 2, 2])

solve = np.linalg.solve(X, y)
print(solve)
print(X @ solve)

solve = slau(X, y)
print(solve)
print(X @ solve)

fun = lambda x: (2.7 * x**2 + 3 * x + 3.7) / (6 * x**4 - 7 * x**2 + 2 * x + 12)
t = np.arange(start=-10, stop=10)
plt.plot(t, fun(t))
plt.xlabel('$X$')
plt.ylabel('$y$')
plt.title('$ \\frac{2.7x^2 + 3x + 3.7}{6x^4 - 7x^2 + 2x + 12}$')
plt.show()

ftt = np.fft.fft(fun(t))
plt.plot(t, np.real(ftt))
plt.plot(t, np.abs(ftt))
plt.plot(t, np.imag(ftt))
plt.legend(['real', 'abs', 'imag'])
plt.show()

up = np.poly1d([1, 0.652, 0.652, 1])
down = np.poly1d([1, -1.145, 0.727, -0.1205])
up_root = np.roots(up)
down_root = np.roots(down)
print(residue(down_root, up_root))