Beispiel #1
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)
Beispiel #2
0
def real_summation_partition(zpk, variant=0, tol=1e-16):
    r = random.Random(variant)
    zeros, poles, gain = zpk

    pole_groups = \
        poly.real_polynomial_factorization_roots(poles, tol=tol)
    if len(pole_groups) < 2:
        return rf, ((), (), 0.)  # degenerate case
    r.shuffle(pole_groups)
    i = r.choice(range(1, len(pole_groups)))
    q = np.concatenate(pole_groups[:i])
    u = np.concatenate(pole_groups[i:])
    if len(q) < len(u):
        q, u = u, q  # improper rational for interpolation

    def f(z):
        return -(reduce(auto.numpy.multiply, z - q, 1.) /
                 reduce(auto.numpy.multiply, z - u, 1.))

    z, s = signal.unique_roots(zeros, tol=tol, rtype='avg')
    n = np.sum(s) - 1
    k = math.floor(n / (1 + len(q) / len(u)))
    m = n - k
    p, t, v = hermite_rational_interpolant(f, z, s, m, k)
    p = poly.real_polynomial_roots_if_close(p, tol=tol)
    t = poly.real_polynomial_roots_if_close(t, tol=tol)
    kp, kt = np.abs(v), np.sign(v)
    kc = gain / poly.simplify(
        poly.add(kp * poly.from_roots(np.concatenate(
            (p, u))), kt * poly.from_roots(np.concatenate((t, q)))))[0]
    rfL = p, q, kc * kp
    rfR = t, u, kc * kt
    return rfL, rfR
Beispiel #3
0
def partial_fractions_expansion(z, p, tol=1e-16, rtype='avg'):
    if len(z) == 0 and len(p) == 0:
        return z, p, np.array([])

    if len(z) >= len(p):
        raise ValueError('Cannot expand improper rational function')

    if len(p) == 1:
        return np.array([1]), p, np.array([1])

    # Use modified Brugia method
    u, su = signal.unique_roots(z, tol=tol, rtype=rtype)
    v, sv = signal.unique_roots(p, tol=tol, rtype=rtype)
    N = lambda x: np.prod((x - u)**su)

    n = 0
    r = np.zeros(len(p), dtype=complex)
    vm = np.ma.array(v, mask=np.zeros_like(v))
    for j, (vj, sj) in enumerate(zip(v, sv)):
        vm.mask[j] = True
        Dj = lambda x: np.prod((x - vm)**sv)
        r[n] = N(vj) / Dj(vj)
        if sj > 1:
            h = lambda r: np.sum(su / (vj - u)**r) - np.sum(sv / (vj - vm)**r)
            b = np.c_[[h(i) for i in range(1, sj)]]
            A = np.zeros((sj - 1, sj - 1), dtype=complex)
            for i in range(1, sj):
                A[i - 1, i - 1] = i
                A[i:, i - 1] = b[:-i]
                A[i - 1:, i - 1] *= -1**(i - 1)
            c = scipy.linalg.solve_triangular(A, b, lower=True)
            r[n + 1:n + sj] = c * r[n]
        vm.mask[j] = False
        n += sj

    r = simple_if_possible(r, tol)
    p = np.concatenate([[vi] * si for vi, si in zip(v, sv)])
    s = np.concatenate([range(1, si + 1) for si in sv])
    return r, p, s
Beispiel #4
0
#vals = np.roots(np.convolve(ones(500),ones(500))) # 500 double complex roots

#vals = np.roots(np.convolve(ones(5),ones(7))) # 4 double complex roots

## tests with nans 
#vals = list(ones(5) * 1j); vals.append(np.nan); vals.append(np.nan)
#vals = []
#print(vals)

Navg = 1000
rtype = 'min'
print('============ dsp.unique_roots() ================================')
t1 = time.clock()
for i in range(Navg):
    roots, mult = dsp.unique_roots(vals, rtype = rtype, rdist='manhattan')
t2 = time.clock()
T_dsp = (t2 - t1)/Navg
print (mult)

print('============ signal.unique_roots() =============================')
t1 = time.clock()
for i in range(Navg):
    roots, mult = sig.unique_roots(vals, rtype = rtype)
t2 = time.clock()
T_sig = (t2 - t1)/Navg
print (mult)

print("T_dsp = ",T_dsp, " s")
print("T_sig = ",T_sig, " s")
print("T_dsp / T_sig = ", T_dsp / T_sig)
Beispiel #5
0
#vals = np.roots(np.convolve(ones(500),ones(500))) # 500 double complex roots

#vals = np.roots(np.convolve(ones(5),ones(7))) # 4 double complex roots

## tests with nans 
#vals = list(ones(5) * 1j); vals.append(np.nan); vals.append(np.nan)
#vals = []
#print(vals)

Navg = 1000
rtype = 'min'
print('============ dsp.unique_roots() ================================')
t1 = time.clock()
for i in range(Navg):
    roots, mult = dsp.unique_roots(vals, rtype = rtype, rdist='manhattan')
t2 = time.clock()
T_dsp = (t2 - t1)/Navg
print (mult)

print('============ signal.unique_roots() =============================')
t1 = time.clock()
for i in range(Navg):
    roots, mult = sig.unique_roots(vals, rtype = rtype)
t2 = time.clock()
T_sig = (t2 - t1)/Navg
print (mult)

print("T_dsp = ",T_dsp, " s")
print("T_sig = ",T_sig, " s")
print("T_dsp / T_sig = ", T_dsp / T_sig)