SLiCAP pole-zero analysis

../_images/colorCode.svg

Accurate pole-zero analysis is indispensible for investigating the stability of dynamic systems. SLiCAP supports both numeric and symbolic pole-zero analysis. Symbolic pole-zero analysis is supported for lower-order rational functions of the Laplace variable and for functions implemented in sympy. Numeric pole-zero analysis is implemented for Laplace rational functions of any order. SLiCAP uses numeric analysis if no other symbolic variables than the Laplace variable ini.laplace=s are found in the expression.

SLiCAP has three instructions related to pole-zero analysis:

  1. doPoles() returns the solutions of the Laplace variable of the denominator of a transfer function.

  2. doZeros() returns the solutions of the Laplace variable of the numerator of a transfer function.

  3. doPZ() returns the zero frequecy gain, the poles, and the zeros of a transfer function. Poles and zeros that coincide withing the display accurary ini.disp are canceled out.

    Important

    doPZ() does not return non-observable and non-controllable poles. Use doPoles() and doZeros() to obtain information about non-observable and non-controllable states.

    • Non-controllable state: the input signal(s) cannot change the state.

    • Non-observable state: the state cannot be observed at the output(s)

SLiCAP output displayed on this manual page, is generated with the script: laplace.py, imported by Manual.py.

1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4"""
5pz.py: SLiCAP scripts for the HTML help file
6"""
7import SLiCAP as sl

The following circuit is used for this manual page:

9pz_network = sl.makeCircuit("kicad/pzNetwork/pzNetwork.kicad_sch")
../_images/pzNetwork.svg

With a differential voltage detector between nodes (1) and (2), and the signal source set to V1, the transfer has four poles and three zeros. Two zeros coincide with two poles:

  • The pole introduced by C2 is not controllable and thus canceled by a zero.

  • The pole introduced by \(\tau\) is not observable and thus canceled by a zero.

Obtain all the poles of a transfer

Symbolic poles analysis

11pResult    = sl.doPoles(pz_network)
12print(pResult.poles)

This yields:

[-1/(C_b*R_b), -1/tau, (-C_a*R_a - C_a*R_d - sqrt(C_a**2*R_a**2 + 2*C_a**2*R_a*R_d + C_a**2*R_d**2 - 4*C_a*L))/(2*C_a*L), (-C_a*R_a - C_a*R_d + sqrt(C_a**2*R_a**2 + 2*C_a**2*R_a*R_d + C_a**2*R_d**2 - 4*C_a*L))/(2*C_a*L)]

Rendered with the formatter:

Table 14 Poles

#

\(f\) [Hz]

\(p_{1}\)

\(- \frac{0.5}{\pi C_{b} R_{b}}\)

\(p_{2}\)

\(- \frac{0.5}{\pi \tau}\)

\(p_{3}\)

\(\frac{0.25 \left(- C_{a} R_{a} - C_{a} R_{d} - \left(C_{a} \left(C_{a} R_{a}^{2} + 2 C_{a} R_{a} R_{d} + C_{a} R_{d}^{2} - 4 L\right)\right)^{0.5}\right)}{\pi C_{a} L}\)

\(p_{4}\)

\(\frac{0.25 \left(- C_{a} R_{a} - C_{a} R_{d} + \left(C_{a} \left(C_{a} R_{a}^{2} + 2 C_{a} R_{a} R_{d} + C_{a} R_{d}^{2} - 4 L\right)\right)^{0.5}\right)}{\pi C_{a} L}\)

Important

Poles and zeros returned by the instruction are always in [rad/s]. The units of poles and zeros displayed in tables HTML are governed by ini.hz=True (default).

Numeric poles analysis

14pResult_num = sl.doPoles(pz_network, pardefs="circuit")
15print(pResult_num.poles)

This yields:

[-30000.+10000.j, -30000.-10000.j, -100000.+0.j, -10000000.+0.j]

Rendered with the formatter:

Table 15 Poles

#

Re [Hz]

Im [Hz]

\(f\) [Hz]

Q

\(p_{1}\)

\(-4775.0\)

\(1592.0\)

\(5033.0\)

\(0.527\)

\(p_{2}\)

\(-4775.0\)

\(-1592.0\)

\(5033.0\)

\(0.527\)

\(p_{3}\)

\(-1.592 \cdot 10^{4}\)

\(0\)

\(1.592 \cdot 10^{4}\)

\(p_{4}\)

\(-1.592 \cdot 10^{6}\)

\(0\)

\(1.592 \cdot 10^{6}\)

Obtain all the zeros of a transfer

Symbolic zero analysis

17zResult     = sl.doZeros(pz_network)
18print(zResult.zeros)

This yields:

[-1/(C_b*R_b), -1/tau, -1/(C_a*R_d)]

Rendered with the formatter:

Table 16 Zeros

#

\(f\) [Hz]

\(z_{1}\)

\(- \frac{0.5}{\pi C_{b} R_{b}}\)

\(z_{2}\)

\(- \frac{0.5}{\pi \tau}\)

\(z_{3}\)

\(- \frac{0.5}{\pi C_{a} R_{d}}\)

Numeric zero analysis

20zResult_num = sl.doZeros(pz_network, pardefs="circuit")
21print(zResult_num.zeros)

This yields:

[-2.0000e+04, -1.0000e+05, -1.0000e+07]

Rendered with the formatter:

Table 17 Zeros

#

Re [Hz]

Im [Hz]

\(f\) [Hz]

Q

\(z_{1}\)

\(-3183.0\)

\(0\)

\(3183.0\)

\(z_{2}\)

\(-1.592 \cdot 10^{4}\)

\(0\)

\(1.592 \cdot 10^{4}\)

\(z_{3}\)

\(-1.592 \cdot 10^{6}\)

\(0\)

\(1.592 \cdot 10^{6}\)

Obtain the observable and controllable poles and zeros of a transfer

Symbolic pole-zero analysis

23pzResult   = sl.doPZ(pz_network)
24print(pzResult.DCvalue)
25print(pzResult.poles)
26print(pzResult.zeros)

This yields:

1
[(-C_a*R_a - C_a*R_d - sqrt(C_a**2*R_a**2 + 2*C_a**2*R_a*R_d + C_a**2*R_d**2 - 4*C_a*L))/(2*C_a*L), (-C_a*R_a - C_a*R_d + sqrt(C_a**2*R_a**2 + 2*C_a**2*R_a*R_d + C_a**2*R_d**2 - 4*C_a*L))/(2*C_a*L)]
[-1/(C_a*R_d)]

Rendered with the formatter:

DC value of gain: \(1\)

Table 18 Observable poles and zeros

#

\(f\) [Hz]

\(p_{1}\)

\(\frac{0.25 \left(- C_{a} R_{a} - C_{a} R_{d} - \left(C_{a} \left(C_{a} R_{a}^{2} + 2 C_{a} R_{a} R_{d} + C_{a} R_{d}^{2} - 4 L\right)\right)^{0.5}\right)}{\pi C_{a} L}\)

\(p_{2}\)

\(\frac{0.25 \left(- C_{a} R_{a} - C_{a} R_{d} + \left(C_{a} \left(C_{a} R_{a}^{2} + 2 C_{a} R_{a} R_{d} + C_{a} R_{d}^{2} - 4 L\right)\right)^{0.5}\right)}{\pi C_{a} L}\)

\(z_{1}\)

\(- \frac{0.5}{\pi C_{a} R_{d}}\)

Numeric pole-zero analysis

28pzResult_num   = sl.doPZ(pz_network, pardefs="circuit")
29sl.listPZ(pzResult_num)

The listPZ() function displays a table in the console output:

DC value of gain: 1.00e+00

Poles of gain:

 n  Real part [Hz]  Imag part [Hz]  Frequency [Hz]     Q [-]
--  --------------  --------------  --------------  --------
 0       -4.77e+03        1.59e+03        5.03e+03   5.27e-1
 1       -4.77e+03       -1.59e+03        5.03e+03   5.27e-1

Zeros of gain:

 n  Real part [Hz]  Imag part [Hz]  Frequency [Hz]     Q [-]
--  --------------  --------------  --------------  --------
 0       -5.07e+02        0.00e+00        5.07e+02

Rendered with the formatter:

DC value of gain: \(1\)

Table 19 Observable poles and zeros

#

Re [Hz]

Im [Hz]

\(f\) [Hz]

Q

\(p_{1}\)

\(-4775.0\)

\(1592.0\)

\(5033.0\)

\(0.527\)

\(p_{2}\)

\(-4775.0\)

\(-1592.0\)

\(5033.0\)

\(0.527\)

\(z_{1}\)

\(-3183.0\)

\(0\)

\(3183.0\)

Return attributes

Important

Calculation of the poles requires calculation of the denominator of a transfer. Hence, SLiCAP also executes the instruction doDenom() and returns the Laplace poly of the denominator (= determinant of the MNA matrix = ‘characteristic equation’) in the .denom attribute of the result. It also places the MNA matrix in the .M attribute of the returned instruction object.

Calculation of the zeros requires calculation of the numerator of a transfer. Hence, SLiCAP also executes the instruction doNumer() and returns the Laplace poly of the numerator in the .numer attribute of the result. It also places the MNA matrix in the .M in the returned instruction object.

Calculation of the poles and the zeros requires all of the above, and the following attributes are available in the returned object:

31M        = pzResult.M
32Iv       = pzResult.Iv
33Dv       = pzResult.Dv
34denom    = pzResult.denom
35numer    = pzResult.numer
36transfer = pzResult.laplace

Display equations on HTML pages and in LaTeX documents

The report module Create reports, discusses how HTML snippets and LaTeX snippets can be created for variables, expressions, equations and tables.

As a matter of fact, all equations, tables and figures on this page are created with this module:

38# Generate RST snippets for the Help file
39rst = sl.RSTformatter()
40
41rst.pz(pResult     , caption="Poles").save("table-P")
42rst.pz(pResult_num , caption="Poles").save("table-Pnum")
43rst.pz(zResult     , caption="Zeros").save("table-Z")
44rst.pz(zResult_num , caption="Zeros").save("table-Znum")
45rst.pz(pzResult    , caption="Observable poles and  zeros").save("table-PZ")
46rst.pz(pzResult_num, caption="Observable poles and  zeros").save("table-PZnum")

Plot pole-zero patterns and root-locus

SLiCAP plot functions are discussed in Create plots

../_images/colorCode.svg