Open jason-s opened 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?
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 )
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.
zpk2ss is implemented using the controller canonical form:
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 useszpk2ss
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