# zp2ctf

Convert zero-pole-gain filter parameters to cascaded transfer function form

*Since R2024a*

## Description

`[`

specifies additional options using name-value arguments.`b,a`

] = zp2ctf(___,`Name=Value`

)

## Examples

### Cascaded Transfer Function from Zeros and Poles

Compute the cascaded transfer function of a discrete-time system from its zeros and poles.

z = [-1 -0.5+0.5i -0.5-0.5i]; p = [0.77 0.9i -0.9i -0.3+0.4i -0.3-0.4i]; [b,a] = zp2ctf(z,p)

`b = `*3×3*
0 1.0000 0
0 1.0000 1.0000
1.0000 1.0000 0.5000

`a = `*3×3*
1.0000 -0.7700 0
1.0000 0.6000 0.2500
1.0000 0 0.8100

### Convert Zero-Pole-Gain Filter to Cascaded Transfer Function

Convert a stopband filter represented with zeros, poles, and gain to cascaded transfer-function form.

Get the zeros, poles, and gain of a 16th-order stopband Butterworth filter with stopband normalized frequencies of 0.35$\pi $rad/sample and 0.5$\pi $rad/sample.

`[z,p,k] = butter(16,[0.35 0.5],"stop");`

Compute the second-order cascaded transfer function coefficients. Plot the filter frequency response.

[ctfB,ctfA] = zp2ctf(z,p,k); filterAnalyzer(ctfB,ctfA)

### Customized Cascaded Transfer Function from Highpass Filter

Design a highpass filter and compute the zeros, poles, and gain. Convert a zero-pole-gain filter representation to cascaded transfer function. Customize the conversion with pole sorting and gain scaling options.

Design a 10th-order type-II Chebyshev highpass filter sampled at 2000 Hz, with a cutoff frequency of 600 Hz and a stopband attenuation of 50 dB. Observe the *z*-plane showing five pairs of poles with a distance from the origin that ranges from 0 to 1.

```
[z,p,k] = cheby2(10,50,600/(2000/2),"high");
zplane(z,p,k)
```

Convert the zero-pole-gain filter representation to cascaded transfer function form. Sort the filter sections in descending order using the distance between the poles and the origin. Specify the gain scaling of the filter sections using the infinity norm. List the pole-origin distances for all the filter sections.

[ctfBs,ctfAs] = zp2ctf(z,p,k,Direction="down",Scale="inf")

`ctfBs = `*5×3*
0.6705 0.3993 0.6705
0.6851 0.2758 0.6851
0.5190 -0.0281 0.5190
0.3424 -0.3002 0.3424
0.2235 -0.4075 0.2235

`ctfAs = `*5×3*
1.0000 0.8652 0.8531
1.0000 0.6592 0.5958
1.0000 0.4056 0.3591
1.0000 0.1474 0.1505
1.0000 -0.0262 0.0189

% Pole-Origin Distances for all Filter Sections. numSections = size(ctfBs,1); poleRadius = zeros(numSections,2); for iter = 1:numSections poleRadius(iter,:) = abs(roots(ctfAs(iter,:))'); end table((1:numSections)',poleRadius, ... VariableNames=["Section" "Pole-Origin Distances"])

`ans=`*5×2 table*
Section Pole-Origin Distances
_______ _____________________
1 0.92363 0.92363
2 0.77188 0.77188
3 0.59926 0.59926
4 0.38792 0.38792
5 0.13735 0.13735

The cascade sections are sorted in descending order by pole-origin distance.

### Cascaded Transfer Function of Lowpass Filter

Convert the zero-pole-gain representation of a Butterworth filter to cascaded transfer function form.

Design a 6th-order Butterworth lowpass filter with a normalized cutoff frequency of 0.2$\pi $rad/sample.

[z,p,k] = butter(6,0.2);

Obtain the numerator and denominator coefficients of the cascaded transfer function in the form of second-order and fourth-order cascaded transfer functions. Plot the frequency response of both cascaded transfer functions. Observe that both cascaded transfer functions yield the same frequency response.

```
% Second-order
[num2,den2,g2] = zp2ctf(z,p,k)
```

`num2 = `*3×3*
1 2 1
1 2 1
1 2 1

`den2 = `*3×3*
1.0000 -1.0321 0.2757
1.0000 -1.1430 0.4128
1.0000 -1.4044 0.7359

g2 = 3.4054e-04

```
% Fourth-order
[num4,den4,g4] = zp2ctf(z,p,k,SectionOrder=4)
```

`num4 = `*2×5*
1 2 1 0 0
1 4 6 4 1

`den4 = `*2×5*
1.0000 -1.0321 0.2757 0 0
1.0000 -2.5474 2.7539 -1.4209 0.3038

g4 = 3.4054e-04

```
% Frequency response
filterAnalyzer(num2,den2,num4,den4)
```

## Input Arguments

`z,p`

— Zeros and poles of system

vector

Zeros and poles of the system, specified as vectors.

The vectors `z`

and `p`

contain the
*n* zeros and *m* poles of the transfer function
*H*(*z*), respectively.

$$H(z)=k\frac{(z-{z}_{1})(z-{z}_{2})\cdots (z-{z}_{n})}{(z-{p}_{1})(z-{p}_{2})\cdots (z-{p}_{m})}.$$

**Example: **`zp2ctf([-1 -1],[0.5+0.5i 0.5-0.5i])`

specifies
`[-1 -1]`

as zeros and `[0.5+0.5i 0.5-0.5i]`

as
poles.

**Data Types: **`single`

| `double`

**Complex Number Support: **Yes

`k`

— Gain of system

1 (default) | real scalar

Gain of the system, specified as a real scalar.

The scalar *k* lists the gain of the transfer function
*H*(*z*).

$$H(z)=k\frac{(z-{z}_{1})(z-{z}_{2})\cdots (z-{z}_{n})}{(z-{p}_{1})(z-{p}_{2})\cdots (z-{p}_{m})}.$$

If you request the output argument `g`

, then the
`zp2ctf`

function assigns the value of `k`

to `g`

.

**Data Types: **`single`

| `double`

### Name-Value Arguments

Specify optional pairs of arguments as
`Name1=Value1,...,NameN=ValueN`

, where `Name`

is
the argument name and `Value`

is the corresponding value.
Name-value arguments must appear after other arguments, but the order of the
pairs does not matter.

**Example: **`zp2ctf(-1,[0.6+0.4i 0.6-0.4i],Direction="down")`

converts a
system with a zero in `-1`

, poles in `0.6+0.4i`

and
`0.6-0.4i`

, and a stacking order in descending distances between the
poles and the origin of the z-plane.

`SectionOrder`

— Order of section transfer functions

`2`

(default) | `4`

Order of the section transfer functions, specified as either `2`

or `4`

. Depending on the value that you specify for
`SectionOrder`

, the `zp2ctf`

function
returns either the second-order or the fourth-order cascaded transfer function form.

`2`

—The`zp2ctf`

function returns second-order cascaded transfer function form matrices`b`

and`a`

with three columns each.`4`

—The`zp2ctf`

function returns fourth-order cascaded transfer function form matrices`b`

and`a`

with five columns each.

**Data Types: **`single`

| `double`

| `int8`

| `int16`

| `int32`

| `int64`

| `uint8`

| `uint16`

| `uint32`

| `uint64`

`Direction`

— Stacking order of transfer function sections

`"up"`

(default) | `"down"`

Stacking order of the transfer function sections, specified as either
`"up"`

or `"down"`

. The
`zp2ctf`

function sorts the rows of `a`

as a function of the distance between the poles and the origin, depending on the value
you specify in `Direction`

:

`"up"`

— The first row of`a`

contains the poles closest to the origin.`"down"`

— The first row of`a`

contains the poles closest to the unit circle.

The `zp2ctf`

function sorts the rows of
`b`

so that the zeros in each section are paired with their
closest poles associated with the rows of `a`

.

**Data Types: **`char`

| `string`

`Scale`

— Gain scaling

`"none"`

(default) | `"inf"`

| `"l2"`

Gain scaling, specified as either `"none"`

,
`"inf"`

, or `"l2"`

. The
`zp2ctf`

scales the gain and the numerator coefficients of
all sections using the `filternorm`

function, depending on the
value you specify to `"Scale"`

:

`"none"`

— No scaling`"inf"`

— Infinity-norm scaling`"l2"`

— L2-norm scaling

**Note**

Infinity-norm and L2-norm scaling are appropriate only for direct-form II implementations, and they are supported only for stable systems.

Using infinity-norm scaling in conjunction with

`"up"`

directional ordering minimizes the probability of overflow when implementing the filter system. On the other hand, using L2-norm scaling in conjunction with`"down"`

directional ordering minimizes the peak round-off noise.

**Data Types: **`char`

| `string`

## Output Arguments

`b,a`

— Cascaded transfer function coefficients

*L*-by-3 matrix (default) | *L*-by-5 matrix

Cascaded transfer function coefficients, returned as either
*L*-by-3 or *L*-by-5 matrices, where
*L* is the number of sections. The number of columns depends on the
value you specify in `SectionOrder`

.

The matrices `b`

and `a`

list the numerator and
denominator coefficients of the cascaded transfer function, respectively. See Cascaded Transfer Functions for more
information.

`g`

— Overall system gain

real scalar

Overall system gain, returned as a real scalar.

If you request

`g`

, the`zp2ctf`

function normalizes the numerator coefficients with respect to the system gain`k`

and returns this gain in`g`

.If you do not request

`g`

, the`zp2ctf`

function uniformly distributes the system gain`k`

across all system sections using the`scaleFilterSections`

function.

## More About

### Cascaded Transfer Functions

Partitioning a filter system into sections connected in cascade form
offers several advantages, such as easy design, less susceptibility to coefficient
quantization errors, and improved stability [2]. A filter system *H*(*z*) can be expressed in *L* sectional transfer functions
*H*_{1}(*z*),
*H*_{2}(*z*), …,
*H*_{L}(*z*),
where

$$H(z)={\displaystyle \prod _{k=1}^{L}{H}_{k}(z)}\text{.}$$

The `zp2ctf`

computes the numerator and denominator coefficients
of the cascaded-transfer-function sections from the zeros, poles, and gain of the filter
system. For an *N*th-order filter system, there are (*L*)^{2} possible combinations [1]. The variable
*L* is the nearest integer greater than or equal to *N*/2 or *N*/4 for second-order or fourth-order sections, respectively.

Customize the sorting criteria for pairing of the zeros and poles in the cascaded
sections by specifying `Direction`

to start with the poles and zeros
closest to the origin of the z-plane (`"up"`

), or closest to the unit
circle (`"down"`

). Perform gain scaling across the cascaded sections by
specifying `Scale`

. Customize the order of the cascaded sections by setting
`SectionOrder`

to either `2`

or `4`

to
generate either second-order or fourth-order cascaded sections, respectively.

The output arguments `b`

and `a`

associate with
the matrices

$$b=\left[\begin{array}{ccc}{{b}^{\prime}}_{01}& {{b}^{\prime}}_{11}& {{b}^{\prime}}_{21}\\ {{b}^{\prime}}_{02}& {{b}^{\prime}}_{12}& {{b}^{\prime}}_{22}\\ \vdots & \vdots & \vdots \\ {{b}^{\prime}}_{0L}& {{b}^{\prime}}_{1L}& {{b}^{\prime}}_{2L}\end{array}\right]$$

and $$\text{a}=\left[\begin{array}{ccc}1& {a}_{11}& {a}_{21}\\ 1& {a}_{12}& {a}_{22}\\ \vdots & \vdots & \vdots \\ 1& {a}_{1L}& {a}_{2L}\end{array}\right]$$.

These matrices contain the second-order cascaded transfer function coefficients of
*H*(*z*)

$$H(z)={\displaystyle \prod _{k=1}^{L}\frac{{{b}^{\prime}}_{0k}+{{b}^{\prime}}_{1k}{z}^{-1}+{{b}^{\prime}}_{2k}{z}^{-2}}{1+{a}_{1k}{z}^{-1}+{a}_{2k}{z}^{-2}}}.$$

If you specify fourth-order sections, the `zp2ctf`

function
returns the *L*-by-5 matrices `b`

and
`a`

, where the last two columns correspond to the *z*^{–3} and *z*^{–4} terms for each cascaded section of *H*(*z*).

## References

[1] Lyons, Richard G.
*Understanding Digital Signal Processing*. Upper Saddle River, NJ:
Prentice Hall, 2004, pp. 274–278.

[2] Parks, Thomas W., and C. Sidney
Burrus. *Digital Filter Design*. Hoboken, NJ: John Wiley & Sons,
1987, pp. 233–239.

## Extended Capabilities

### C/C++ Code Generation

Generate C and C++ code using MATLAB® Coder™.

### GPU Code Generation

Generate CUDA® code for NVIDIA® GPUs using GPU Coder™.

### GPU Arrays

Accelerate code by running on a graphics processing unit (GPU) using Parallel Computing Toolbox™.

This function fully supports GPU arrays. For more information, see Run MATLAB Functions on a GPU (Parallel Computing Toolbox).

## Version History

**Introduced in R2024a**

## See Also

`filterAnalyzer`

| `scaleFilterSections`

| `sos2ctf`

| `zp2sos`

| `zp2ss`

| `zp2tf`

## MATLAB Command

You clicked a link that corresponds to this MATLAB command:

Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.

Select a Web Site

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

You can also select a web site from the following list:

## How to Get Best Site Performance

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

### Americas

- América Latina (Español)
- Canada (English)
- United States (English)

### Europe

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)