I discovered this while working on #19.
When I use the zeta constructor with ZOH and N>=4, the output coefficients are wrong.
Uniform zeta forces all complex pole pairs to the same location, producing repeated eigenvalues in the CCF matrix. consteig's QR iteration cannot split the resulting degenerate 2x2 block, so matrix_exp returns a wrong result.
The FactoredTF path would not help here either. That path builds a Vandermonde matrix from the poles via matrix_exp_ccf. With repeated poles, two or more columns of the Vandermonde become identical and the matrix is singular, so lu_solve produces garbage. Both paths fail for the same underlying reason.
I confirmed the failure is specific to repeated eigenvalues, not the ZOH path itself. When I discretize a classical Butterworth N=5 (not specifying damping ratio, so poles are distinct) through the same non-factored ZOH path, I get error ~8e-15.
MatchedZ and Tustin are unaffected. I capped ZOH zeta tests at N<=3 for now.
I discovered this while working on #19.
When I use the zeta constructor with ZOH and N>=4, the output coefficients are wrong.
Uniform zeta forces all complex pole pairs to the same location, producing repeated eigenvalues in the CCF matrix. consteig's QR iteration cannot split the resulting degenerate 2x2 block, so matrix_exp returns a wrong result.
The FactoredTF path would not help here either. That path builds a Vandermonde matrix from the poles via matrix_exp_ccf. With repeated poles, two or more columns of the Vandermonde become identical and the matrix is singular, so lu_solve produces garbage. Both paths fail for the same underlying reason.
I confirmed the failure is specific to repeated eigenvalues, not the ZOH path itself. When I discretize a classical Butterworth N=5 (not specifying damping ratio, so poles are distinct) through the same non-factored ZOH path, I get error ~8e-15.
MatchedZ and Tustin are unaffected. I capped ZOH zeta tests at N<=3 for now.