Sympy .coeff_all () возвращенный список не читается scipy - PullRequest
0 голосов
/ 10 января 2020

У меня есть вопрос о типе данных результата, возвращаемого Sympy Poly.all_coeffs (). Я начал использовать Sympy совсем недавно. Моя функция передачи Sympy следующая:

enter image description here

Затем я запускаю этот код:

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

Я получаю:

enter image description here

Затем я запускаю этот код:

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)

и получается:

---------------------------------------------------------------------------
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)

Но если я использую вместо этих закомментированных строк 'nu' и 'de' прямо python списки программа работает. Так что тут не так?

Ответы [ 2 ]

2 голосов
/ 10 января 2020

Почему вы только что показали ошибку? Почему бы не полное сообщение, возможно, даже полное обратное отслеживание!

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''

Теперь посмотрите на элементы списка num_c (то же самое для den_c):

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

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

scipy код выполняет numpy тестирование на входах. Итак, сначала он превратил списки в массивы:

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

Этот массив содержит sympy объектов. Он не может привести это к numpy с плавающей надписью «безопасно». Но явное astype использует unsafe по умолчанию:

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

Итак, давайте преобразуем оба списка в действительные numpy массивы с плавающей точкой:

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
)

Преобразование в понимании списка также работает:

sys = signal.lti([float(i) for i in num_c],[float(i) for i in den_c]) 
0 голосов
/ 10 января 2020

Скорее всего, вам нужно конвертировать объекты sympy в float / списки с плавающей точкой.

...