Пример #1
0
def PolyGCD(a: numpy.array, b: numpy.array):
    a = numpy.trim_zeros(a)
    b = numpy.trim_zeros(b)
    if (len(a) < len(b) or (len(a) == 0) or (len(b) == 0)):
        return None, None, None
    p0 = a[0]
    p1 = b[0]
    a0, a1 = a / p0, b / p1
    s0, s1 = 1 / p0, 0
    t0, t1 = 0, 1 / p1

    while (len(a1)):
        q, r = numpy.polydiv(a0, a1)

        if (len(numpy.trim_zeros(a0 - numpy.polymul(a1, q))) == 0):
            return a1, s1, t1

        a0, a1 = a1, a0 - numpy.polymul(a1, q)
        a1 = numpy.trim_zeros(a1)
        lu = a1[0]
        a1 = a1 / lu
        tmp = numpy.trim_zeros(numpy.polymul(s1, q))
        if (len(tmp) == 0):
            tmp = 0
        s0, s1 = s1, (s0 - tmp) / lu
        tmpt = numpy.trim_zeros(numpy.polymul(t1, q))
        if (len(tmpt) == 0):
            tmpt = 0
        t0, t1 = t1, (t0 - tmpt) / lu
    return a1, s1, t1
Пример #2
0
def grad_BP(clause, x, k, ctype, FC_table):
    grad = []
    nv = len(clause)
    coef = [FC_table[ci] for ci in range(1, len(clause) + 1)]
    if nv < 40:
        for i in clause:
            x_rest = [
                xi / abs(xi) * x[abs(xi) - 1] for xi in clause if xi != i
            ]
            esps = cardcons(x_rest)
            grad.append(np.dot(coef, esps) * (abs(i) / i))
        return grad
    esps = []  # Elementary symetric Polymomials
    x_prime = [
        -x[abs(clause[i]) - 1] * (clause[i] / abs(clause[i]))
        for i in range(len(clause))
    ]
    forward_message = []
    backward_message = []
    forward_message.append([1])
    backward_message.append([1])
    for i in range(1, nv):
        forward_message.append(
            np.polymul(forward_message[i - 1], poly1d([x_prime[i - 1]], True)))
        backward_message.append(
            np.polymul(backward_message[i - 1], poly1d([x_prime[nv - i]],
                                                       True)))
    for i in range(1, nv + 1):
        esps.append(
            np.polymul(forward_message[i - 1], backward_message[nv - i]))
    for i in range(nv):
        grad.append(np.dot(coef, esps[i].c) * (abs(clause[i]) / clause[i]))
    return grad
Пример #3
0
def mkSystem(fo_r, Q_r, fo_f, bw_f, ord_f=5, nsys = 4, tol_fo_f=0.0, tol_fo_r=0.0):

  if ( abs(tol_fo_f) > 0.05 ):
    raise RuntimeError("-.05 < tol_fo_f < +.05")
  if ( abs(tol_fo_r) > 0.05 ):
    raise RuntimeError("-.05 < tol_fo_r < +.05")

  if isinstance(fo_r,(tuple,list)):
    nsys = len(fo_r)
  else:
    fo_r = [fo_r for i in range(nsys)]
    Q_r  = [Q_r  for i in range(nsys)]

  lsys_list = []

  for i in range(nsys):
    fo_f_i = fo_f*(1.0 +  tol_fo_f*np.random.randn())
    fo_r_i = fo_r[i]*(1.0 +  tol_fo_r*np.random.randn())
    [bf,af] = sig.iirfilter(ord_f, 2*np.pi*np.array([fo_f_i-bw_f/2,fo_f_i+bw_f/2]), rp=0.5, ftype='cheby1', analog=True)
    if fo_r[i] > 0.0:
      [br,ar] = mkResonator(fo_r_i, Q_r[i])
      bsys = np.polymul(br,bf)
      asys = np.polymul(ar,af)
    else:
      bsys = bf
      asys = af
    try:
      lsys=LinSys( bsys,asys )
    except RuntimeError as e:
      norm = e.args[1]*1.001
      print("Normalized numerator dividing by {}!".format(norm))
      bsys = bsys/norm
      lsys = LinSys(bsys,asys)
    lsys_list.append(lsys)
  return lsys_list
Пример #4
0
def Closed_loop(Kz, Kp, Gz, Gp):
    """ 
    Return zero and pole polynomial for a closed loop function.
    
    Parameters
    ----------
    Kz & Gz : list
        Polynomial constants in the numerator.
    Kz & Gz : list
        Polynomial constants in the denominator.
    
    Returns
    -------
    Zeros_poly : list
        List of zero polynomial for closed loop function.
        
    Poles_poly : list
        List of pole polynomial for closed loop function.
        
   """

    # calculating the product of the two polynomials in the numerator
    # and denominator of transfer function GK
    Z_GK = numpy.polymul(Kz, Gz)
    P_GK = numpy.polymul(Kp, Gp)

    # calculating the polynomial of closed loop
    # sensitivity function s = 1/(1+GK)
    Zeros_poly = Z_GK
    Poles_poly = numpy.polyadd(Z_GK, P_GK)
    return Zeros_poly, Poles_poly
Пример #5
0
def closest1(point, bezier):
    close = None
    distance = np.infty
    for curve in bezier:
        x = curve.x_eq
        y = curve.y_eq
        x[-1] -= point.x
        y[-1] -= point.y
        dist = np.polyadd(np.polymul(x, x), np.polymul(y, y))
        d_f = np.polyder(dist)

        for r in np.roots(d_f):
            if np.isreal(r) and r >= 0 and r <= 1:
                p = Point(np.polyval(curve.x_eq, r), np.polyval(curve.y_eq, r))
                d = p.dist(point)
                if d <= distance:
                    close = curve
                    distance = d

    if close.color == (0, 0, 0):
        print("A curva mais próxima é a preta")
    elif close.color == (255, 0, 0):
        print("A curva mais próxima é a vermelha")
    elif close.color == (0, 255, 0):
        print("A curva mais próxima é a verde")
    elif close.color == (0, 0, 255):
        print("A curva mais próxima é a azul")
    else:
        print("A curva mais próxima é a roxo")
    return close
Пример #6
0
def _combine_reception_params(in_reception_parameters,
                              out_reception_parameters):
    """Combine reception parameters to join two signals into one, e.g., for
    optimising out a passthrough Node.
    """
    # Construct the new reception parameters
    # Combine the filters
    filter_in = in_reception_parameters.filter
    filter_out = out_reception_parameters.filter

    if (filter_in is None or filter_out is None):
        # If either filter is None then just use the filter from the other
        # connection
        new_filter = filter_in or filter_out
    elif (isinstance(filter_in, nengo.LinearFilter) and
            isinstance(filter_out, nengo.LinearFilter)):
        # Both filters are linear filters, so multiply the numerators and
        # denominators together to get a new linear filter.
        new_num = np.polymul(filter_in.num, filter_out.num)
        new_den = np.polymul(filter_in.den, filter_out.den)

        new_filter = nengo.LinearFilter(new_num, new_den)
    else:
        raise NotImplementedError

    # Take the size in from the second reception parameter, construct the new
    # reception parameters.
    return ReceptionParameters(new_filter, out_reception_parameters.width)
Пример #7
0
 def get_transfer_function(self):
     den = 1
     num = 1
     for i in self.filters:
         den = polymul(den, i.a)
         num = polymul(num, i.b)
     return Filter(num, den)
Пример #8
0
 def __rsub__(self,other):
     if type(other) in [int, float]:
         return ltimul(polyadd(-self.num,self.den*other),self.den)
     if type(other) in [TransFun, type(self)]:
         numer = polyadd(polymul(other.num,self.den),-polymul(self.den,other.num))
         denom = polymul(self.den,other.den)
         return ltimul(numer,denom)
Пример #9
0
def A_weighting(fs):
    """Design of an A-weighting filter.
    b, a = A_weighting(fs) designs a digital A-weighting filter for
    sampling frequency `fs`. Usage: y = scipy.signal.lfilter(b, a, x).
    Warning: `fs` should normally be higher than 20 kHz. For example,
    fs = 48000 yields a class 1-compliant filter.
    References:
       [1] IEC/CD 1672: Electroacoustics-Sound Level Meters, Nov. 1996.
    """
    # Definition of analog A-weighting filter according to IEC/CD 1672.
    f1 = 20.598997
    f2 = 107.65265
    f3 = 737.86223
    f4 = 12194.217
    A1000 = 1.9997

    NUMs = [(2*pi * f4)**2 * (10**(A1000/20)), 0, 0, 0, 0]
    DENs = polymul([1, 4*pi * f4, (2*pi * f4)**2],
                   [1, 4*pi * f1, (2*pi * f1)**2])
    DENs = polymul(polymul(DENs, [1, 2*pi * f3]),
                                 [1, 2*pi * f2])

    # Use the bilinear transformation to get the digital filter.
    # (Octave, MATLAB, and PyLab disagree about Fs vs 1/Fs)
    return bilinear(NUMs, DENs, fs)
Пример #10
0
    def concat(self, other):
        """Create new reception parameters by combining this set of reception
        parameters with another.
        """
        # Combine the filters
        if self.filter is None:
            new_filter = other.filter
        elif other.filter is None:
            new_filter = self.filter
        elif (isinstance(self.filter, LinearFilter)
              and isinstance(other.filter, LinearFilter)):
            # Combine linear filters by multiplying their numerators and
            # denominators.
            new_filter = LinearFilter(
                np.polymul(self.filter.num, other.filter.num),
                np.polymul(self.filter.den, other.filter.den))
        else:
            raise NotImplementedError(
                "Cannot combine filters of type {} and {}".format(
                    type(self.filter), type(other.filter)))

        # Combine the learning rules
        if self.learning_rule is not None and other.learning_rule is not None:
            raise NotImplementedError(
                "Cannot combine learning rules {} and {}".format(
                    self.learning_rule, other.learning_rule))

        new_learning_rule = self.learning_rule or other.learning_rule

        # Create the new reception parameters
        return ReceptionParameters(new_filter, other.width, new_learning_rule)
Пример #11
0
def E(F, P):
    '''
    Forms the Hurwitz polynomial E(lambda)
    '''
    #Generate F(jw)*F(-jw) and P(jw)*p(-jw) for n even
    #nX = X(-jw).  Changes sign of coefficients of odd order only.
    nF = np.copy(F)
    nP = np.copy(P)
    #Odd order indexing from penultimate element while stepping by 2 in reverse.
    nF[-2::-2] = -1 * nF[-2::-2]
    nP[-2::-2] = -1 * nP[-2::-2]

    FnF = np.polymul(F, nF)
    PnP = np.polymul(P, nP)

    #Form (E)(nE)=(F)(nF)+(P)(nP). Page 287. EQN(14), EQN(15)
    EnE = np.polyadd(FnF, PnP)

    E = np.array([1])
    for root in np.roots(EnE):
        if np.real(root) < 0:
            E = np.polymul(E, np.array([1, -1 * root]))

    E = np.real(E)

    return E, FnF, PnP
Пример #12
0
def ClosedLoop_TF(AOL_TF, Beta_TF, C_s):
    n1 = AOL_TF.num[0][0]
    d1 = AOL_TF.den[0][0]
    n2 = Beta_TF.num[0][0]
    d2 = Beta_TF.den[0][0]
    n1 = conv_arr2list(n1)
    d1 = conv_arr2list(d1)
    n2 = conv_arr2list(n2)
    d2 = conv_arr2list(d2)

    num = np.polymul(conv_list2arr(n1), conv_list2arr(d2))
    den1 = np.polymul(conv_list2arr(d1), conv_list2arr(d2))
    den2 = np.polymul(conv_list2arr(n1), conv_list2arr(n2))
    den1 = conv_arr2list(den1)
    den2 = conv_arr2list(den2)
    if len(den1) > len(den2):
        i = len(den2)
        while i < len(den1):
            den2 = append2first(den2, 0)
            i = i + 1
    else:
        i = len(den1)
        while i < len(den2):
            den1 = append2first(den1, 0)
            i = i + 1

    den = conv_list2arr(add_elm_by_elm(den2, den1))
    CL_TF = C_s * mt.tf(num, den)
    num_cl = CL_TF.num
    den_cl = CL_TF.den
    return CL_TF, num_cl[0][0], den_cl[0][0]
Пример #13
0
def _combine_reception_params(in_reception_parameters,
                              out_reception_parameters):
    """Combine reception parameters to join two signals into one, e.g., for
    optimising out a passthrough Node.
    """
    # Construct the new reception parameters
    # Combine the filters
    filter_in = in_reception_parameters.filter
    filter_out = out_reception_parameters.filter

    if (filter_in is None or filter_out is None):
        # If either filter is None then just use the filter from the other
        # connection
        new_filter = filter_in or filter_out
    elif (isinstance(filter_in, nengo.LinearFilter)
          and isinstance(filter_out, nengo.LinearFilter)):
        # Both filters are linear filters, so multiply the numerators and
        # denominators together to get a new linear filter.
        new_num = np.polymul(filter_in.num, filter_out.num)
        new_den = np.polymul(filter_in.den, filter_out.den)

        new_filter = nengo.LinearFilter(new_num, new_den)
    else:
        raise NotImplementedError

    # Take the size in from the second reception parameter, construct the new
    # reception parameters.
    return ReceptionParameters(new_filter, out_reception_parameters.width)
Пример #14
0
 def __mul__(self, other):
     if type(other) in [int, float]:
         return ltimul(self.num * other, self.den)
     elif type(other) in [TransFun, ltimul]:
         numer = numpy.polymul(self.num, other.num)
         denom = numpy.polymul(self.den, other.den)
         return ltimul(numer, denom)
Пример #15
0
 def __rtruediv__(self, other):
     if type(other) in [int, float]:
         return ltimul(other * self.den, self.num)
     if type(other) in [TransFun, ltimul]:
         numer = numpy.polymul(self.den, other.num)
         denom = numpy.polymul(self.num, other.den)
         return ltimul(numer, denom)
Пример #16
0
def Kc(n, p, theta_deg):
    #n is even EQN(37) p294
    m = n // 2

    c, delta_c, wc_p = c_v(n, theta_deg)

    #const_c calculation from page 304
    const_c = 1 / (delta_c * np.sqrt(1 / p**2 - 1))

    #EQN(46) expand for n even
    F = np.array([1, 0, 0])
    P = np.array([1 / const_c])

    #These are the inverse of the transmission zero frequencies
    co_tz = np.array([])

    for u in range(2, m + 1):
        #form numerator of K(lambda) or F(lambda)
        F = np.polymul(F, np.array([1, 0, c[2 * u - 1]**2]))

        #form denominator of K(lambda) or P(lambda)
        P = np.polymul(P, np.array([c[2 * u - 1]**2, 0, 1]))

        #collect the coefficient a[v] used in P(lambda)
        co_tz = np.append(co_tz, c[2 * u - 1])

    return F, P, co_tz, wc_p
Пример #17
0
def poly_pulverizer(a: np.ndarray, b: np.ndarray):
    """return (g, x, y) such that a*x + b*y = g = gcd(a, b)"""

    a = np.array(a)
    b = np.array(b)
    if a.size < b.size:
        a, b = b, a

    a = np.trim_zeros(a, trim="f") % 2
    b = np.trim_zeros(b, trim="f") % 2

    r = np.ndarray((1,))
    x1, x2, y1, y2 = 1, 0, 0, 1
    while np.trim_zeros(r).size != 0:
        q, r = np.polydiv(a, b)

        a = b
        b = r
        x2 = np.polysub(x1, np.polymul(q, x2))
        y2 = np.polysub(y1, np.polymul(q, y2))
        x1, y1 = x2, y2

        a = np.trim_zeros(a % 2, trim="f")
        b = np.trim_zeros(b % 2, trim="f")
    return b, x2, y2
Пример #18
0
    def __truediv__(self, other):
        """Divide two LTI objects."""

        if isinstance(other, (int, float, complex, np.number)):
            other = _convertToTransferFunction(other,
                                               inputs=self.inputs,
                                               outputs=self.inputs)
        else:
            other = _convertToTransferFunction(other)

        if (self.inputs > 1 or self.outputs > 1 or other.inputs > 1
                or other.outputs > 1):
            raise NotImplementedError(
                "TransferFunction.__truediv__ is currently \
                implemented only for SISO systems.")

        # Figure out the sampling time to use
        if (self.dt is None and other.dt is not None):
            dt = other.dt  # use dt from second argument
        elif (other.dt is None and self.dt is not None)\
                or (self.dt == other.dt):
            dt = self.dt  # use dt from first argument
        else:
            raise ValueError("Systems have different sampling times")

        num = polymul(self.num[0][0], other.den[0][0])
        den = polymul(self.den[0][0], other.num[0][0])

        return TransferFunction(num, den, dt)
Пример #19
0
 def __rtruediv__(self, other):
     if type(other) in [int, float]:
         return ExtendedTF(other * self.den, self.num, dt=self._dt)
     if type(other) in [TransFun, ExtendedTF]:
         numer = polymul(self.den, other.num)
         denom = polymul(self.num, other.den)
         return ExtendedTF(numer, denom, dt=self._dt)
Пример #20
0
    def feedback(self, other=1, sign=-1):
        """Feedback interconnection between two LTI objects."""
        other = _convertToTransferFunction(other)

        if (self.inputs > 1 or self.outputs > 1 or other.inputs > 1
                or other.outputs > 1):
            # TODO: MIMO feedback
            raise NotImplementedError("TransferFunction.feedback is currently \
only implemented for SISO functions.")

        # Figure out the sampling time to use
        if (self.dt is None and other.dt is not None):
            dt = other.dt  # use dt from second argument
        elif (other.dt is None and self.dt is not None) \
                or (self.dt == other.dt):
            dt = self.dt  # use dt from first argument
        else:
            raise ValueError("Systems have different sampling times")

        num1 = self.num[0][0]
        den1 = self.den[0][0]
        num2 = other.num[0][0]
        den2 = other.den[0][0]

        num = polymul(num1, den2)
        den = polyadd(polymul(den2, den1), -sign * polymul(num2, num1))

        return TransferFunction(num, den, dt)
Пример #21
0
 def __mul__(self, other):
     if type(other) in [int, float]:
         return ExtendedTF(self.num * other, self.den, dt=self._dt)
     elif type(other) in [TransFun, ExtendedTF]:
         numer = polymul(self.num, other.num)
         denom = polymul(self.den, other.den)
         return ExtendedTF(numer, denom, dt=self._dt)
Пример #22
0
 def __truediv__(self, other):
     if type(other) in [int, float]:
         return ltimul(self.num, self.den * other)
     if type(other) in [TransFun, ltimul]:
         numer = polymul(self.num, other.den)
         denom = polymul(self.den, other.num)
         return ltimul(numer, denom)
Пример #23
0
 def draw_cascade(self):
     if self.ui.chk_all_selected.isChecked():  #Graficame PLS
         if any(self.stages_list) == True:
             A = np.poly1d(1)
             B = np.poly1d(1)
             for i in range(0, len(self.stages_list)):
                 if self.stages_list[i]:
                     temp_list = []
                     temp_list.append(self.fix(self.sos[i]))
                     b, a = ss.sos2tf(temp_list)
                     b = np.poly1d(b)
                     a = np.poly1d(a)
                     B = np.polymul(B, b)
                     A = np.polymul(A, a)
             # self.sos=np.insert(self.sos[0],0,ss.tf2sos(B.c, A.c))
             # for t in range(0,len(self.stages_list)):
             #     self.stages_list[t] = False
             # self.stages_list[len(self.stages_list)-1] = True
             w = np.logspace(np.log10(1),
                             np.log10(self.furthestPZ() * 100 /
                                      (2 * np.pi)),
                             num=10000) * 2 * np.pi
             bode = ss.bode(ss.TransferFunction(B.c, A.c), w=w)
             self.axes_mag.plot(bode[0] / (2 * np.pi),
                                bode[1],
                                label='acumulada')
             self.axes_mag.set_xscale('log')
             self.axes_mag.set_xlabel('Frequency [Hz]')
             self.axes_mag.set_ylabel('Magnitude [dB]')
             self.axes_mag.minorticks_on()
             self.axes_mag.legend(loc='best')
             self.canvas_mag.draw()
     else:
         self.manage_plot()
Пример #24
0
    def concat(self, other):
        """Create new reception parameters by combining this set of reception
        parameters with another.
        """
        # Combine the filters
        if self.filter is None:
            new_filter = other.filter
        elif other.filter is None:
            new_filter = self.filter
        elif (isinstance(self.filter, LinearFilter) and
                isinstance(other.filter, LinearFilter)):
            # Combine linear filters by multiplying their numerators and
            # denominators.
            new_filter = LinearFilter(
                np.polymul(self.filter.num, other.filter.num),
                np.polymul(self.filter.den, other.filter.den)
            )
        else:
            raise NotImplementedError(
                "Cannot combine filters of type {} and {}".format(
                    type(self.filter), type(other.filter)))

        # Combine the learning rules
        if self.learning_rule is not None and other.learning_rule is not None:
            raise NotImplementedError(
                "Cannot combine learning rules {} and {}".format(
                    self.learning_rule, other.learning_rule))

        new_learning_rule = self.learning_rule or other.learning_rule

        # Create the new reception parameters
        return ReceptionParameters(new_filter, other.width, new_learning_rule)
Пример #25
0
def solve_for_nearest( px,py,rx,ry ):
  dpx = polyder(px)
  dpy = polyder(py)
  cp = polymul( dpx, px ) + polymul( dpy, py )
  cp = polyadd( cp, -rx*dpx )      
  cp = polyadd( cp, -ry*dpy )
  t = roots(cp)
  t = real(t[isreal(t)])
  t = t[ (t>=0) * (t<=1) ]

  ##tt = linspace(0,1,100)
  ##from pylab import plot
  ##plot( polyval(px,tt), polyval(py,tt), 'k', hold = 0 )
  ##plot( [rx],[ry], 'r.' )
  ##plot( polyval(px,t[isreal(t)*(real(t)>=0)*(real(t)<=1)]),
  ##      polyval(py,t[isreal(t)*(real(t)>=0)*(real(t)<=1)]), 'o' )
  ##pdb.set_trace()

  if len(t):
    if len(t) == 1:
      return t[0]
    else:
      ux = polyval( px, t )
      uy = polyval( py, t )
      d = hypot( ux - rx, uy - ry )
      return t[ d==d.min() ][0]
  else:
    t = array([0.0,1.0])
    ux = polyval( px, t )
    uy = polyval( py, t )
    d = hypot( ux - rx, uy - ry )
    if d[0] < d[1]:
      return 0.0
    else:
      return 1.0
Пример #26
0
def A_weighting(fs):
    """Design of an A-weighting filter.
    b, a = A_weighting(fs) designs a digital A-weighting filter for
    sampling frequency `fs`. Usage: y = scipy.signal.lfilter(b, a, x).
    Warning: `fs` should normally be higher than 20 kHz. For example,
    fs = 48000 yields a class 1-compliant filter.
    References:
       [1] IEC/CD 1672: Electroacoustics-Sound Level Meters, Nov. 1996.
    """
    # Definition of analog A-weighting filter according to IEC/CD 1672.
    f1 = 20.598997
    f2 = 107.65265
    f3 = 737.86223
    f4 = 12194.217
    A1000 = 1.9997

    NUMs = [(2*pi * f4)**2 * (10**(A1000/20)), 0, 0, 0, 0]
    DENs = polymul([1, 4*pi * f4, (2*pi * f4)**2],
                   [1, 4*pi * f1, (2*pi * f1)**2])
    DENs = polymul(polymul(DENs, [1, 2*pi * f3]),
                                 [1, 2*pi * f2])

    # Use the bilinear transformation to get the digital filter.
    # (Octave, MATLAB, and PyLab disagree about Fs vs 1/Fs)
    return bilinear(NUMs, DENs, fs)
Пример #27
0
    def __truediv__(self, other):
        """Divide two LTI objects."""

        if isinstance(other, (int, float, complex)):
            other = _convertToTransferFunction(
                other, inputs=self.inputs,
                outputs=self.inputs)
        else:
            other = _convertToTransferFunction(other)

        if (self.inputs > 1 or self.outputs > 1 or
                other.inputs > 1 or other.outputs > 1):
            raise NotImplementedError(
                "TransferFunction.__truediv__ is currently \
                implemented only for SISO systems.")

        # Figure out the sampling time to use
        if (self.dt is None and other.dt is not None):
            dt = other.dt       # use dt from second argument
        elif (other.dt is None and self.dt is not None)\
                or (self.dt == other.dt):
            dt = self.dt        # use dt from first argument
        else:
            raise ValueError("Systems have different sampling times")

        num = polymul(self.num[0][0], other.den[0][0])
        den = polymul(self.den[0][0], other.num[0][0])

        return TransferFunction(num, den, dt)
Пример #28
0
def Closed_loop(Kz, Kp, Gz, Gp):
    """
    Return zero and pole polynomial for a closed loop function.

    Parameters
    ----------
    Kz & Gz : list
        Polynomial constants in the numerator.
    Kz & Gz : list
        Polynomial constants in the denominator.

    Returns
    -------
    Zeros_poly : list
        List of zero polynomial for closed loop function.

    Poles_poly : list
        List of pole polynomial for closed loop function.

   """

    # calculating the product of the two polynomials in the numerator
    # and denominator of transfer function GK
    Z_GK = numpy.polymul(Kz, Gz)
    P_GK = numpy.polymul(Kp, Gp)

    # calculating the polynomial of closed loop
    # sensitivity function s = 1/(1+GK)
    Zeros_poly = Z_GK
    Poles_poly = numpy.polyadd(Z_GK, P_GK)
    return Zeros_poly, Poles_poly
    def L(self):
        # Returns the loop transfer function, L = PK given a plant and controller
        # transfer function (scipy.signal.TransferFunction objects)
        num = np.polymul(self.P.num, self.C.num)
        den = np.polymul(self.P.den, self.C.den)

        return signal.TransferFunction(num, den)
Пример #30
0
def Ka(n, p, theta_deg):
    #n is odd, EQN(37) p294
    m = (n - 1) // 2

    a, delta_a, wc_p = a_v(n, theta_deg)

    #const_c calculation from page 304
    const_c = 1 / (delta_a * np.sqrt(1 / p**2 - 1))

    #EQN(37) expand for n odd
    F = np.array([1, 0])
    P = np.array([1 / const_c])

    #These are the inverse of the transmission zero frequencies
    co_tz = np.array([])

    for u in range(1, m + 1):
        #form numerator of K(lambda) or F(lambda)
        F = np.polymul(F, [1, 0, a[2 * u]**2])

        #form denominator of K(lambda) or P(lambda)
        P = np.polymul(P, [a[2 * u]**2, 0, 1])

        #collect the coefficient a[v] used in P(lambda)
        co_tz = np.append(co_tz, a[2 * u])

    return F, P, co_tz, wc_p
Пример #31
0
    def __init__(self, pos_init, dir_init, alpha_init, pos_final, dir_final, alpha_final):
        delta_pos = pos_final - pos_init - alpha_init * dir_init
        delta_vel = alpha_final * dir_final - alpha_init * dir_init

        # path coefficients
        self.coeffs_pos = np.zeros(shape=(2, 4), dtype=float)
        for i in range(0, 2):
            c_temp = np.dot(np.array([[-2.0, 1.0], [3.0, -1.0]]), np.array([delta_pos[i], delta_vel[i]]))
            self.coeffs_pos[i, 0] = c_temp[0]
            self.coeffs_pos[i, 1] = c_temp[1]

            self.coeffs_pos[i, 2] = alpha_init * dir_init[i]
            self.coeffs_pos[i, 3] = pos_init[i]

        self.coeffs_vel = np.array([np.polyder(self.coeffs_pos[0,:]),
                                    np.polyder(self.coeffs_pos[1,:])])
        self.coeffs_acc = np.array([np.polyder(self.coeffs_vel[0,:]),
                                    np.polyder(self.coeffs_vel[1,:])])
        self.coeffs_jerk = np.array([np.polyder(self.coeffs_acc[0,:]),
                                    np.polyder(self.coeffs_acc[1,:])])

        # curvature coefficients
        self.coeffs_num = np.polysub(np.polymul(self.coeffs_vel[0, :], self.coeffs_acc[1, :]),
                                     np.polymul(self.coeffs_vel[1, :], self.coeffs_acc[0, :]))
        self.coeffs_denom = np.polyadd(np.polymul(self.coeffs_vel[0, :], self.coeffs_vel[0, :]),
                                       np.polymul(self.coeffs_vel[1, :], self.coeffs_vel[1, :]))

        # roots for minimizing curvature
        self.roots_init = False
Пример #32
0
def Kb(n, p, theta_deg):
    #EQN(39) for n even
    m = n // 2

    bP, bS, delta_b, wc_p = b_v(n, theta_deg)

    #c calculation from page 304
    const_c = 1 / (delta_b * np.sqrt(1 / p**2 - 1))

    #EQN(43) expand for n even
    F = np.array([1, 0, (bP[1]**2)])
    P = np.array([1 / const_c])

    #These are the inverse of the transmission zero frequencies
    co_tz = np.array([])

    for u in range(2, m + 1):
        #form numerator of K(lambda) or F(lambda)
        F = np.polymul(F, np.array([1, 0, bP[2 * u - 1]**2]))

        #form denominator of K(lambda) or P(lambda)
        P = np.polymul(P, np.array([bS[2 * u - 1]**2, 0, 1]))

        #collect the constants bS[2*u-1] used in P(lambda)
        co_tz = np.append(co_tz, bS[2 * u - 1])

    return F, P, co_tz, wc_p
Пример #33
0
 def decascade(self, ncascade=1):
     '''
     Reduces cascades of low order filters into smaller cascades of high order filters.
     
     ``ncascade`` is the number of cascaded filters to use, which should be
     a divisor of the original number.
     
     Note that higher order filters are often numerically unstable.
     '''
     n, m, p = self.filt_b.shape
     if p%ncascade!=0:
         raise ValueError('Number of cascades must be a divisor of original number of cascaded filters.')
     b = np.zeros((n, (m-1)*(p/ncascade)+1, ncascade))
     a = np.zeros((n, (m-1)*(p/ncascade)+1, ncascade))
     for i in range(n):
         for k in range(ncascade):
             bp = np.ones(1)
             ap = np.ones(1)
             for j in range(k*(p/ncascade), (k+1)*(p/ncascade)):
                 bp = np.polymul(bp, self.filt_b[i, ::-1, j])
                 ap = np.polymul(ap, self.filt_a[i, ::-1, j])
             bp = bp[::-1]
             ap = ap[::-1]
             a0 = ap[0]
             ap /= a0
             bp /= a0
             b[i, :len(bp), k] = bp
             a[i, :len(ap), k] = ap
     self.filt_b = np.array(b, order='F')
     self.filt_a = np.array(a, order='F')
     self.filt_state = np.zeros((b.shape[0], b.shape[1], b.shape[2]), order='F')
Пример #34
0
    def feedback(self, other=1, sign=-1):
        """Feedback interconnection between two LTI objects."""
        other = _convertToTransferFunction(other)

        if (self.inputs > 1 or self.outputs > 1 or
                other.inputs > 1 or other.outputs > 1):
            # TODO: MIMO feedback
            raise NotImplementedError("TransferFunction.feedback is currently \
only implemented for SISO functions.")

        # Figure out the sampling time to use
        if (self.dt is None and other.dt is not None):
            dt = other.dt       # use dt from second argument
        elif (other.dt is None and self.dt is not None) \
                or (self.dt == other.dt):
            dt = self.dt        # use dt from first argument
        else:
            raise ValueError("Systems have different sampling times")

        num1 = self.num[0][0]
        den1 = self.den[0][0]
        num2 = other.num[0][0]
        den2 = other.den[0][0]

        num = polymul(num1, den2)
        den = polyadd(polymul(den2, den1), -sign * polymul(num2, num1))

        return TransferFunction(num, den, dt)
Пример #35
0
def get_TF(zeros, poles, constant):
    num_fact = []
    den_fact = []
    i = 0

    while i < len(zeros):
        num_fact.insert(i, [1, -1 * zeros[i]])
        i = i + 1
    i = 0
    while i < len(poles):
        den_fact.insert(i, [1, -1 * poles[i]])
        i = i + 1
    i = 0
    num = [1]
    den = [1]
    while i < (len(zeros)):
        num = np.polymul(num, num_fact[i])
        i = i + 1
    i = 0
    while i < len(poles):
        den = np.polymul(den, den_fact[i])
        i = i + 1

    H_s = constant * mt.tf(num, den)
    # print(H_s)
    d, n = [], []
    for i in range(0, len(num)):
        n.append(num[i].real * constant)

    for i in range(0, len(den)):
        d.append(den[i].real)

    return H_s, n, d
Пример #36
0
def traiter_situation_1():
    sx = recuperer_valeur()
    sx = np.array(sx)
    gx = np.array([1.0, 1.0])
    xd = np.array([1.0, 0.0])
    rx = np.polydiv(np.polymul(sx, xd), gx)[1][0]
    print("CRC: R(x)= ", int(rx))
    print("T(x)= " + str(np.concatenate((sx, np.array([int(i) for i in np.polydiv(np.polymul(sx, xd), gx)[0]])))))
Пример #37
0
def _poly_iw_real_crossing(num_iw, den_iw, epsw):
    # Return w where imag(H(iw)) == 0
    test_w = np.polysub(np.polymul(num_iw.imag, den_iw.real),
                        np.polymul(num_iw.real, den_iw.imag))
    w = np.roots(test_w)
    w = np.real(w[np.isreal(w)])
    w = w[w >= epsw]
    return w
Пример #38
0
def compute_join_length( px, py, tlow = 0.0, thigh = 1.0 ):
  from scipy.integrate import quad
  xp  = polyder( px, 1 )
  yp  = polyder( py, 1 )
  xp2 = polymul( xp, xp )
  yp2 = polymul( yp, yp )
  p   = polyadd( xp2, yp2 )
  integrand = lambda t: sqrt( polyval( p, t ) )
  return quad(integrand, tlow, thigh) [0]
Пример #39
0
def compute_join_curvature( px, py ):
  from scipy.integrate import quad
  xp  = polyder( px, 1 )
  xpp = polyder( px, 2 )
  yp  = polyder( py, 1 )
  ypp = polyder( py, 2 )
  pn = polyadd( polymul( xp, ypp ), polymul( yp, xpp )) #numerator
  pd = polyadd( polymul( xp, xp ) , polymul( yp, yp ) ) #denominator
  integrand = lambda t:  fabs(polyval( pn, t )/( polyval( pd, t )**(1.5)) ) 
  return quad(integrand, 0, 1) [0]
Пример #40
0
def make_C_weighting(fs):

	den = p1
	den = np.polymul(den, p1)
	den = np.polymul(den, p4)
	den = np.polymul(den, p4)
	num = np.poly1d([(2.*np.pi*f4)**2, 0, 0])

	B, A = signal.bilinear(num, den, fs)
	return B, A
Пример #41
0
def mls_polynomial_coefficients(rho, degree):
    """Determine the coefficients for a MLS polynomial smoother

    Parameters
    ----------
    rho : {float}
        Spectral radius of the matrix in question
    degree : {int}
        Degree of polynomial coefficients to generate

    Returns
    -------
    Tuple of arrays (coeffs,roots) containing the
    coefficients for the (symmetric) polynomial smoother and
    the roots of polynomial prolongation smoother.

    The coefficients of the polynomial are in descending order

    References
    ----------
    .. [1] Parallel multigrid smoothing: polynomial versus Gauss--Seidel
       M. F. Adams, M. Brezina, J. J. Hu, and R. S. Tuminaro
       J. Comp. Phys., 188 (2003), pp. 593--610

    Examples
    --------
    >>> from pyamg.relaxation.chebyshev import mls_polynomial_coefficients
    >>> mls = mls_polynomial_coefficients(2.0, 2)
    >>> print mls[0] # coefficients
    [   6.4  -48.   144.  -220.   180.   -75.8   14.5]
    >>> print mls[1] # roots
    [ 1.4472136  0.5527864]
    """

    # std_roots = np.cos(np.pi * (np.arange(degree) + 0.5)/ degree)
    # print std_roots

    roots = rho/2.0 * (1.0 - np.cos(2*np.pi*(np.arange(degree,
                                       dtype='float64') + 1)/(2.0*degree+1.0)))
    # print roots
    roots = 1.0/roots

    # S_coeffs = list(-np.poly(roots)[1:][::-1])

    S = np.poly(roots)[::-1]  # monomial coefficients of S error propagator

    SSA_max = rho/((2.0*degree+1.0)**2)  # upper bound spectral radius of S^2A
    S_hat = np.polymul(S, S)  # monomial coefficients of \hat{S} propagator
    S_hat = np.hstack(((-1.0/SSA_max)*S_hat, [1]))

    # coeff for combined error propagator \hat{S}S
    coeffs = np.polymul(S_hat, S)
    coeffs = -coeffs[:-1]             # coeff for smoother

    return (coeffs, roots)
Пример #42
0
def residue(b,a,tol=1e-3,rtype='avg'):
    """Compute 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

    See also:  invres, poly, polyval, unique_roots
    """

    b,a = map(asarray,(b,a))
    k,b = polydiv(b,a)
    p = roots(a)
    r = p*0.0
    pout, mult = unique_roots(p,tol=tol,rtype=rtype)
    p = []
    for n in range(len(pout)):
        p.extend([pout[n]]*mult[n])
    p = asarray(p)
    # Compute the residue from the general formula
    indx = 0
    for n in range(len(pout)):
        bn = b.copy()
        pn = []
        for l in range(len(pout)):
            if l != n:
                pn.extend([pout[l]]*mult[l])
        an = atleast_1d(poly(pn))
        # bn(s) / an(s) is (s-po[n])**Nn * b(s) / a(s) where Nn is
        # multiplicity of pole at po[n]
        sig = mult[n]
        for m in range(sig,0,-1):
            if sig > m:
                # compute next derivative of bn(s) / an(s)
                term1 = polymul(polyder(bn,1),an)
                term2 = polymul(bn,polyder(an,1))
                bn = polysub(term1,term2)
                an = polymul(an,an)
            r[indx+m-1] = polyval(bn,pout[n]) / polyval(an,pout[n]) \
                          / factorial(sig-m)
        indx += sig
    return r, p, k
Пример #43
0
def _addSISO(num1, den1, num2, den2):
    """Return num/den = num1/den1 + num2/den2.

    Each numerator and denominator is a list of polynomial coefficients.

    """

    num = polyadd(polymul(num1, den2), polymul(num2, den1))
    den = polymul(den1, den2)

    return num, den
Пример #44
0
def Rule_7(w_start, w_end):
    # Rule 7 determining the phase of GGm at -180deg
    # this is solved visually from a plot

    w = np.logspace(w_start, w_end, 1000)

    Pz = np.polymul(G()[0], Gm()[0])
    Pp = np.polymul(G()[1], Gm()[1])
    [w, h] = scs.freqs(Pz, Pp, w)

    plt.semilogx(w, (180 / np.pi) * (phase(h) + w * Time_Delay()))
    plt.show()
Пример #45
0
def Closed_loop(Kz, Kp, Gz, Gp):
    """Kz & Gz is the polynomial constants in the numerator
    Kp & Gp is the polynomial constants in the denominator"""

    # calculating the product of the two polynomials in the numerator and denominator of transfer function GK
    Z_GK = numpy.polymul(Kz, Gz)
    P_GK = numpy.polymul(Kp, Gp)

    #calculating the polynomial of closed loop sensitivity function s = 1/(1+GK)
    Zeros_poly = Z_GK
    Poles_poly = numpy.polyadd(Z_GK, P_GK)
    return Zeros_poly, Poles_poly
def series(sys1, sys2):


    """Series connection of two systems.
    """
    if not isinstance(sys1, signal.lti):
        sys1 = signal.lti(*sys1)
    if not isinstance(sys2, signal.lti):
        sys2 = signal.lti(*sys2)
    num = np.polymul(sys1.num, sys2.num)
    den = np.polymul(sys1.den, sys2.den)
    sys = signal.lti(num, den)
    return sys
Пример #47
0
def Closed_loop (Kz,Kp,Gz,Gp):
    """ Kz and Gz are the polynomial constants in the numerator 
    Kp and Gp are the polynomial constants in the denominator""" 
    
    
    
    # calculating the product of the two polynomials in the numerator and denominator of transfer function GK
    Z_GK         =np.polymul(Kz,Gz)
    P_GK         =np.polymul(Kp,Gp)    
    # calculating the polynomial of closed loop function T=(GK/1+GK)
    Zeros_poly   =Z_GK
    Poles_poly   =np.polyadd(Z_GK,P_GK)   
    return      Zeros_poly,Poles_poly
Пример #48
0
 def __init__(self, c=4):
     c_ops = self._c_ops
     if not c in c_ops:
         raise ValueError("c should be one of " + str(c_ops))
     index = c / 2 - 1
     p_1 = (1,)
     for _i in xrange(self._coefs_1_orders[index]):
         p_1 = np.polymul(p_1, self._coefs_1)
     p_2 = self._coefs_2s[index]
     p = np.polymul(p_1, p_2)
     self.poly = np.poly1d(p)
     self._diff_order = -1
     self.set_diff_order(0)
Пример #49
0
def A_weighting(fs):
    """
    Design of an A-weighting filter.

    Designs a digital A-weighting filter for
    sampling frequency `fs`. Usage: y = lfilter(b, a, x).
    Warning: fs should normally be higher than 20 kHz. For example,
    fs = 48000 yields a class 1-compliant filter.

    fs : float
        Sampling frequency

    Since this uses the bilinear transform, frequency response around fs/2 will
    be inaccurate at lower sampling rates.  A-weighting is undefined above
    20 kHz, though.

    Example:

    from scipy.signal import freqz
    import matplotlib.pyplot as plt
    fs = 200000  # change to 48000 to see truncation
    b, a = A_weighting(fs)
    f = np.logspace(np.log10(10), np.log10(fs/2), 1000)
    w = 2*pi * f / fs
    w, h = freqz(b, a, w)
    plt.semilogx(w*fs/(2*pi), 20*np.log10(abs(h)))
    plt.grid(True, color='0.7', linestyle='-', which='both', axis='both')
    plt.axis([10, 100e3, -50, 20])

    References:
       [1] IEC/CD 1672: Electroacoustics-Sound Level Meters, Nov. 1996.
    """

    # Definition of analog A-weighting filter according to IEC/CD 1672.
    f1 = 20.598997
    f2 = 107.65265
    f3 = 737.86223
    f4 = 12194.217
    A1000 = 1.9997

    NUMs = [(2*pi * f4)**2 * (10**(A1000/20)), 0, 0, 0, 0]

    DENs = polymul([1, 4*pi * f4, (2*pi * f4)**2],
                   [1, 4*pi * f1, (2*pi * f1)**2])
    DENs = polymul(DENs, [1, 2*pi * f3])
    DENs = polymul(DENs, [1, 2*pi * f2])

    # Analog confirmed to match https://en.wikipedia.org/wiki/A-weighting#A_2

    # Use the bilinear transformation to get the digital filter.
    return bilinear(NUMs, DENs, fs)
Пример #50
0
def Poly_Zeros_T(Poly_z_K, Poly_p_K, Poly_z_G, Poly_p_G):
    """Given the polynomial expansion in the denominator and numerator of the controller function K and G
    then this function return s the poles and zeros of the closed loop transfer function in terms of reference signal

    the arrays for the input must range from the highest order of the polynomial to the lowest"""

    Poly_z = numpy.polymul(Poly_z_K, Poly_z_G)
    Poly_p = numpy.polyadd(numpy.polymul(Poly_p_K, Poly_z_G), numpy.polymul(Poly_p_K, Poly_p_G))

    # return the poles and zeros of T
    Zeros = numpy.roots(Poly_z)
    Poles = numpy.roots(Poly_p)

    return Poles, Zeros
Пример #51
0
def mean_curvature(w, side, dx, n=16):
    n = min(n, len(w.x) / 4)
    L = cumulative_path_length(w)
    tt = L / L.max()
    teval = tt[n] if side == 0 else tt[-n]
    px = np.polyfit(tt[n:-n], w.x[n:-n], 2)
    py = np.polyfit(tt[n:-n], w.y[n:-n], 2)
    xp = np.polyder(px, 1)
    xpp = np.polyder(px, 2)
    yp = np.polyder(py, 1)
    ypp = np.polyder(py, 2)
    pn = np.polyadd(np.polymul(xp, ypp), np.polymul(yp, xpp))  # numerator
    pd = np.polyadd(np.polymul(xp, xp), np.polymul(yp, yp))  # denominator
    kappa = lambda t: dx * np.polyval(pn, t) / (np.polyval(pd, t) ** (1.5))  # d Tangent angle/ds * ds/dt
    return quad(kappa, 0, 1, epsrel=1e-3)[0]
def feedback(plant, sensor=None):
    """Negative feedback connection of plant and sensor.
    If sensor is None, then it is assumed to be 1.
    """
    if not isinstance(plant, signal.lti):
        plant = signal.lti(*plant)
    if sensor is None:
        sensor = signal.lti([1], [1])
    elif not isinstance(sensor, signal.lti):
        sensor = signal.lti(*sensor)
    num = np.polymul(plant.num, sensor.den)
    den = np.polyadd(np.polymul(plant.den, sensor.den),
                     np.polymul(plant.num, sensor.num))
    sys = signal.lti(num, den)
    return sys
Пример #53
0
 def combine(self, obj):
     """Combine in series with another LinearFilter."""
     if not isinstance(obj, LinearFilter):
         raise ValidationError(
             "Can only combine with other LinearFilters", attr='obj')
     if self.analog != obj.analog:
         raise ValidationError(
             "Cannot combine analog and digital filters", attr='obj')
     num = np.polymul(self.num, obj.num)
     den = np.polymul(self.den, obj.den)
     return LinearFilter(num, den,
                         analog=self.analog,
                         default_size_in=self.default_size_in,
                         default_size_out=self.default_size_out,
                         default_dt=self.default_dt,
                         seed=self.seed)
Пример #54
0
 def solve(self, A):
     f = np.array([2.0,0.0,-1.0,1.0])
     f = np.poly1d(f)
     g = np.array(A)
     g = np.poly1d(g)
     f = np.polymul(f, g)
     return f
Пример #55
0
    def change_exponent(self, _pow):
        """ Change exponent

        Multiply top and bottom by an integer multiple of the
        self.denom_poly.

        Examples
        --------
        >>> import numpy
        >>> b = ECquasi([3,4,20], m=30, exponent=4)
        >>> x = numpy.linspace(0,1,101)
        >>> c = b.change_exponent(3)
        >>> c
        ECquasi(array([  1.11111111e-04,   1.48148148e-04,   1.07407407e-02,
                 1.33333333e-02,   3.66666667e-01,   4.00000000e-01,
                 5.00000000e+00,   4.00000000e+00,   2.00000000e+01]), m=30.000000, exponent=7.000000)
        >>> numpy.allclose(c(x), b(x))
        True
        """
        if np.isfinite(self.m):
            _denom_poly = self.denom_poly()
            if int(_pow) != _pow or _pow < 0:
                raise ValueError('expecting a non-negative integer')
            p = _denom_poly**int(_pow)
            exponent = self.exponent + _pow
            coeffs = np.polymul(self, p).coeffs
            return ECquasi(coeffs, exponent=exponent, m=self.m)
        else:
            return ECquasi(self.coeffs, exponent=self.exponent, m=self.m)
Пример #56
0
    def __rmul__(self, other):
        """Right multiply two LTI objects (serial connection)."""

        # Convert the second argument to a transfer function.
        if isinstance(other, (int, float, complex)):
            other = _convertToTransferFunction(other, inputs=self.inputs,
                                               outputs=self.inputs)
        else:
            other = _convertToTransferFunction(other)

        # Check that the input-output sizes are consistent.
        if other.inputs != self.outputs:
            raise ValueError("C = A * B: A has %i column(s) (input(s)), but B \
has %i row(s)\n(output(s))." % (other.inputs, self.outputs))

        inputs = self.inputs
        outputs = other.outputs

        # Figure out the sampling time to use
        if (self.dt is None and other.dt is not None):
            dt = other.dt       # use dt from second argument
        elif (other.dt is None and self.dt is not None) \
                or (self.dt == other.dt):
            dt = self.dt        # use dt from first argument
        else:
            raise ValueError("Systems have different sampling times")

        # Preallocate the numerator and denominator of the sum.
        num = [[[0] for j in range(inputs)] for i in range(outputs)]
        den = [[[1] for j in range(inputs)] for i in range(outputs)]

        # Temporary storage for the summands needed to find the
        # (i, j)th element
        # of the product.
        num_summand = [[] for k in range(other.inputs)]
        den_summand = [[] for k in range(other.inputs)]

        for i in range(outputs):  # Iterate through rows of product.
            for j in range(inputs):  # Iterate through columns of product.
                for k in range(other.inputs):  # Multiply & add.
                    num_summand[k] = polymul(other.num[i][k], self.num[k][j])
                    den_summand[k] = polymul(other.den[i][k], self.den[k][j])
                    num[i][j], den[i][j] = _addSISO(
                        num[i][j], den[i][j],
                        num_summand[k], den_summand[k])

        return TransferFunction(num, den, dt)
Пример #57
0
def State_Space_mats(Gp_n, Gp_d, kc, ti, td):

    if ti == 0:
        Gc_d = 1
        Gc_n = [kc * ti * td, (kc * ti), kc]

    else:
        Gc_n = [kc * ti * td, (kc * ti), kc]
        Gc_d = [ti, 0]

    OL_TF_n = np.polymul(Gp_n, Gc_n)
    OL_TF_d = np.polymul(Gc_d, Gp_d)
    CL_TF_n = OL_TF_n
    CL_TF_d = np.polyadd(OL_TF_d, OL_TF_n)
    OL_mats = signal.tf2ss(OL_TF_n, OL_TF_d)  # Open Loop Transfer Function is converted to State Space
    CL_mats = signal.tf2ss(CL_TF_n, CL_TF_d)  # Closed Loop Transfer Function is converted to State Space

    return OL_mats, CL_mats
Пример #58
0
    def __div__(self, other):
        """Divide two LTI objects."""
        
        if isinstance(other, (int, float, complex)):
            other = _convertToFRD(other, inputs=self.inputs, 
                outputs=self.inputs, omega=self.omega)
        else:
            other = _convertToFRD(other, omega=self.omega)


        if (self.inputs > 1 or self.outputs > 1 or 
            other.inputs > 1 or other.outputs > 1):
            raise NotImplementedError("FRD.__div__ is currently \
implemented only for SISO systems.")

        num = polymul(self.num[0][0], other.den[0][0])
        den = polymul(self.den[0][0], other.num[0][0])
        
        return FRD(num, den)
def error(plant, sensor=None, entrada=None):
    """Negative feedback connection of plant and sensor.
    If sensor is None, then it is assumed to be 1.
    """
    if not isinstance(plant, signal.lti):
        plant = signal.lti(*plant)

    if sensor is None:
        sensor = signal.lti([1], [1])
    elif not isinstance(sensor, signal.lti):
        sensor = signal.lti(*sensor)
        

    if entrada is None:
        entrada = signal.lti([1], [1])
    elif not isinstance(entrada, signal.lti):
        entrada = signal.lti(*entrada) 
 
        
        
 #   aux = np.polymul(plant.den, sensor.den)
    num = np.polymul(np.polymul(plant.den, sensor.den),entrada.num)
    den = np.polyadd(np.polymul(np.polymul(plant.den, sensor.den),entrada.den),
                     np.polymul(np.polymul(plant.num, sensor.num),entrada.den))
    sys = signal.lti(num, den)
    return sys