0

I have question about the data type of the result returned by Sympy Poly.all_coeffs(). I have started to use Sympy just recently. My Sympy transfer function is following:

enter image description here

Then I run this code:

n,d = fraction(Gs)
num = Poly(n,s)
den = Poly(d,s)
num_c = num.all_coeffs()
den_c = den.all_coeffs()

I get:

enter image description here

Then I run this code:

from scipy import signal
#nu = [5000000.0]
#de = [4.99, 509000.0]
nu = num_c
de = den_c
sys = signal.lti(nu, de)
w,mag,phase = signal.bode(sys)
plt.plot(w/(2*np.pi), mag)

and the result is:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-131-fb960684259c> in <module>
      4 nu = num_c
      5 de = den_c
----> 6 sys = signal.lti(nu, de)

But if I use those commented line 'nu' and 'de' straight python lists instead, the program works. So what is wrong here?

mpeli
  • 347
  • 3
  • 6

2 Answers2

2

Why did you just show a bit the error? Why not the full message, maybe even the full traceback!

In [60]: sys = signal.lti(num_c, den_c)                                                                   
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-60-21f71ecd8884> in <module>
----> 1 sys = signal.lti(num_c, den_c)

/usr/local/lib/python3.6/dist-packages/scipy/signal/ltisys.py in __init__(self, *system, **kwargs)
    590         self._den = None
    591 
--> 592         self.num, self.den = normalize(*system)
    593 
    594     def __repr__(self):

/usr/local/lib/python3.6/dist-packages/scipy/signal/filter_design.py in normalize(b, a)
   1609     leading_zeros = 0
   1610     for col in num.T:
-> 1611         if np.allclose(col, 0, atol=1e-14):
   1612             leading_zeros += 1
   1613         else:

<__array_function__ internals> in allclose(*args, **kwargs)

/usr/local/lib/python3.6/dist-packages/numpy/core/numeric.py in allclose(a, b, rtol, atol, equal_nan)
   2169 
   2170     """
-> 2171     res = all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan))
   2172     return bool(res)
   2173 

<__array_function__ internals> in isclose(*args, **kwargs)

/usr/local/lib/python3.6/dist-packages/numpy/core/numeric.py in isclose(a, b, rtol, atol, equal_nan)
   2267     y = array(y, dtype=dt, copy=False, subok=True)
   2268 
-> 2269     xfin = isfinite(x)
   2270     yfin = isfinite(y)
   2271     if all(xfin) and all(yfin):

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Now look at the elements of the num_c list (same for den_c):

In [55]: num_c[0]                                                                                         
Out[55]: 500000.000000000

In [56]: type(_)                                                                                          
Out[56]: sympy.core.numbers.Float

The scipy code is doing numpy testing on the inputs. So it's first turned the lists into arrays:

In [61]: np.array(num_c)                                                                                  
Out[61]: array([500000.000000000], dtype=object)

This array contains sympy object(s). It can't cast that to numpy float with 'safe'. But an explicit astype uses unsafe as the default:

In [63]: np.array(num_c).astype(float)                                                                    
Out[63]: array([500000.])

So lets convert both lists into valid numpy float arrays:

In [64]: sys = signal.lti(np.array(num_c).astype(float), np.array(den_c).astype(float))                   

In [65]: sys                                                                                              
Out[65]: 
TransferFunctionContinuous(
array([100200.4008016]),
array([1.00000000e+00, 1.02004008e+05]),
dt: None
)

Conversion in a list comprehension also works:

sys = signal.lti([float(i) for i in num_c],[float(i) for i in den_c]) 
hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • I thought to save some space by having only the beginning that says already that it is a type error. But next time I promise I'll put the whole thing :). Anyway, thanks a lot! – mpeli Jan 10 '20 at 23:31
  • You can also use `np.array(num_c, dtype=float)`, which is probably the preferred way to do this. – asmeurer Jan 10 '20 at 23:45
  • I started with `np.array(...)` to highlight the fact that, by default, the `scipy` is getting an array with sympy floats, not the numpy ones it needs. I suspect either way is good. – hpaulj Jan 11 '20 at 00:16
0

You likely need to conver sympy objects to floats / lists of floats.

ev-br
  • 24,968
  • 9
  • 65
  • 78
  • Yes, I think so too. Tried already to convert list element in for loop, but got error: TypeError: 'Poly' object is not iterable – mpeli Jan 10 '20 at 14:50