scipy / scipy

SciPy library main repository
https://scipy.org
BSD 3-Clause "New" or "Revised" License
12.7k stars 5.08k forks source link

BUG: zpk2ss uses controller canonical form; this is ill-conditioned for systems that are more than order 5-10 #5912

Open jason-s opened 8 years ago

jason-s commented 8 years ago

zpk2ss is implemented using the controller canonical form:

return tf2ss(*zpk2tf(z, p, k))

Controller canonical form is fine for transfer functions based on polynomial coefficients; it's a lossless way of dealing with the information encoded in polynomial coefficients. But floating-point polynomial coefficients are ill-conditioned ways of specifying the roots of a polynomial, and if someone carefully determines zeros and poles for systems of high order or even moderately high order (N > 5-10), the results are very poor.

Please don't use controller canonical form for zpkss! (And the scipy.signal.lti constructor uses zpk2ss so this causes problems for it as well.)

A cascade of 1st- and 2nd-order systems would be more appropriate. (of course, the hard part then becomes how to partition poles and zeros appropriately.)

I ran into this issue recently and got around it in my own way; writeup here: http://www.embeddedrelated.com/showarticle/927.php

endolith commented 8 years ago

Currently it's just tf2ss(*zpk2tf(z, p, k)), which loses data as it passes through tf form, so it needs a real implementation anyway.

On https://github.com/scipy/scipy/wiki/scipy.signal-to-do-list I suggested it have a form={'controllable', 'observable', 'cascade', 'jordan', ...} parameter

What is the SS equivalent of second-order sections?

jason-s commented 8 years ago

On https://github.com/scipy/scipy/wiki/scipy.signal-to-do-list I suggested it have a form={'controllable', 'observable', 'cascade', 'jordan', ...} parameter

Good idea! I second it. Alias 'series' to 'cascade' and 'modal' to 'jordan'. But unless there's some pathological exception I haven't thought of, the cascade form is the most numerically stable.

What is the SS equivalent of second-order sections?

Second order sections, I think. It's really the same idea, the poles and zeros can be partitioned into either single real first-order systems, or second-order systems with conjugate poles & zeros. As far as how they're implemented in SS, the cascade formulas are

A12 = [A1     0 ]
      [B2C1   A2]

B12 = [B1  ]
      [B2D1]

C12 = [D2C1    C2]

D12 = D2D1

in terms of systems (A1, B1, C1, D1) and (A2, B2, C2, D2). (source: http://press.princeton.edu/chapters/s9012.pdf )

jason-s commented 8 years ago

Currently it's just tf2ss(*zpk2tf(z, p, k))

Whoops, I copied ss2zpk instead. Fixed the description in this issue. Looks like ss2zpk needs a modification as well.