Skip to content

Commit

Permalink
fix #968 zp2tf function
Browse files Browse the repository at this point in the history
  • Loading branch information
Nelson-numerical-software committed Sep 26, 2023
1 parent 68d2b68 commit 5236265
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- [#967](http://github.com/Nelson-numerical-software/nelson/issues/967) control system module template.
- `abcdchk` Verifies the dimensional compatibility of matrices A, B, C, and D.
- [#944](http://github.com/Nelson-numerical-software/nelson/issues/944) `mag2db`, `db2mag`, `pow2db`, `db2pow` functions.
- [#968](http://github.com/Nelson-numerical-software/nelson/issues/968) `zp2tf`: Zero-pole to transfer function conversion.

### Changed

Expand Down
63 changes: 63 additions & 0 deletions modules/signal_processing/functions/zp2tf.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
%=============================================================================
% Copyright (c) 2016-present Allan CORNET (Nelson)
%=============================================================================
% This file is part of the Nelson.
%=============================================================================
% LICENCE_BLOCK_BEGIN
% SPDX-License-Identifier: LGPL-3.0-or-later
% LICENCE_BLOCK_END
%=============================================================================
function varargout = zp2tf(varargin)
narginchk(3, 3);
nargoutchk(0, 2);
z = varargin{1};
p = varargin{2};
k = varargin{3};

den = computesDenominator(p);
varargout{1} = computesNumerator(z, k, den);

if nargout > 1
varargout{2} = den;
end
end
%=============================================================================
function den = computesDenominator(p)
den = real(poly(p(:)));
end
%=============================================================================
function num = computesNumerator(z, k, den)
num = [];
denc = size(den, 2);
k = k(:);
kr = size(k, 1);
if isempty(z)
if (denc - 1 > 0)
num = [zeros(kr, denc - 1), k];
else
num = k;
end
else
zc = size(z, 2);
if kr ~= zc
if ((size(z, 1) - 1) ~= 0)
error('Input argument #1 and #3 should have the same column size.');
else
error('First argument must be a column vector.');
end
else
num = [];
for nidx = 1:zc
zidx = z(:, nidx);
pidx = real(poly(zidx) * k(nidx));
zr = zeros(1, denc - length(pidx));
if isempty(num)
num = [zr, pidx];
else
num(nidx, :) = [zr, pidx];
end
end
end
end
end
%=============================================================================
79 changes: 79 additions & 0 deletions modules/signal_processing/help/en_US/xml/zp2tf.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xmldoc>
<copyright>SAME AS NELSON SOFTWARE</copyright>

<language>en_US</language>
<keyword>zp2tf</keyword>
<short_description
>Zero-pole to transfer function conversion.</short_description>

<syntax>
<syntax_item>[NUM, DEN] = zp2tf(Z, P, K)</syntax_item>
</syntax>

<param_input>
<param_input_item>
<param_name>Z</param_name>
<param_description
>Locations of zeros, organized in columns for each system output.</param_description>
</param_input_item>
<param_input_item>
<param_name>P</param_name>
<param_description
>Locations of poles, recorded as a column vector.</param_description>
</param_input_item>
<param_input_item>
<param_name>K</param_name>
<param_description>Gains.</param_description>
</param_input_item>

</param_input>

<param_output>
<param_output_item>
<param_name>NUM</param_name>
<param_description
>Coefficients in the numerator, organized by rows corresponding to each system output.</param_description>
</param_output_item>
<param_output_item>
<param_name>DEN</param_name>
<param_description
>Coefficients in the denominator, arranged as a row vector.</param_description>
</param_output_item>
</param_output>

<description>
<p><b
>[NUM, DEN] = zp2tf(Z, P, K)</b> returns polynomial transfer function representation from zeros and poles.</p>
</description>

<examples>
<example_item>
<example_item_type>nelson</example_item_type>
<example_item_description />
<example_item_data
><![CDATA[p = [0.5;0.45+0.5i;0.45-0.5i];
z = [-1;i;-i];
k = 1;
[n, d] = zp2tf(z, p, k)]]>
</example_item_data>
</example_item>
</examples>

<see_also>
<see_also_item>
<link linkend="${signal_processing}tf2zpk">tf2zpk</link>
</see_also_item>
</see_also>

<history>
<history_item>
<history_version>1.0.0</history_version>
<history_description>initial version</history_description>
</history_item>
</history>

<authors>
<author_item>Allan CORNET</author_item>
</authors>
</xmldoc>
35 changes: 35 additions & 0 deletions modules/signal_processing/tests/test_zp2tf.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
%=============================================================================
% Copyright (c) 2016-present Allan CORNET (Nelson)
%=============================================================================
% This file is part of the Nelson.
%=============================================================================
% LICENCE_BLOCK_BEGIN
% SPDX-License-Identifier: LGPL-3.0-or-later
% LICENCE_BLOCK_END
%=============================================================================
assert_isequal(nargin('zp2tf'), -1);
assert_isequal(nargout('zp2tf'), -1);
%=============================================================================
assert_checkerror('zp2tf([-100 -2.01], [-5 -.9 -20.1], 1)', _('First argument must be a column vector.'))
%=============================================================================
[N, D] = zp2tf([-1; -2.01], [-5 -9.9 -20.1], 1);
N_REF = [0 1.0000 3.0100 2.0100];
D_REF = [1.0000 35.0000 348.9900 994.9500];
assert_isapprox(N, N_REF, 1e-3);
assert_isapprox(D, D_REF, 1e-3);
%=============================================================================
[N, D] = zp2tf([], [], 1);
N_REF = 1;
D_REF = 1;
assert_isequal(N, N_REF);
assert_isequal(D, D_REF);
%=============================================================================
z = [49.498, 0; -49.498, 16.362];
p = [0; -57.753; 53.851; 2.0831];
k = [18.182; 45.455];
[N, D] = zp2tf(z, p, k);
N_REF = 1.0e+04 * [0, 0, 0.0018, 0, -4.4547; 0, 0, 0.0045, -0.0744, 0];
D_REF = 1.0e+03 * [0.0010, 0.0018, -3.1182, 6.4786, 0];
assert_isapprox(N, N_REF, 1e-3);
assert_isapprox(D, D_REF, 1e-3);
%=============================================================================

0 comments on commit 5236265

Please sign in to comment.