1## Copyright (C) 2009-2016 Lukas F. Reichlin 2## 3## This file is part of LTI Syncope. 4## 5## LTI Syncope is free software: you can redistribute it and/or modify 6## it under the terms of the GNU General Public License as published by 7## the Free Software Foundation, either version 3 of the License, or 8## (at your option) any later version. 9## 10## LTI Syncope is distributed in the hope that it will be useful, 11## but WITHOUT ANY WARRANTY; without even the implied warranty of 12## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13## GNU General Public License for more details. 14## 15## You should have received a copy of the GNU General Public License 16## along with LTI Syncope. If not, see <http://www.gnu.org/licenses/>. 17 18## -*- texinfo -*- 19## @deftypefn {Function File} {@var{s} =} zpk (@var{'s'}) 20## @deftypefnx {Function File} {@var{z} =} zpk (@var{'z'}, @var{tsam}) 21## @deftypefnx {Function File} {@var{sys} =} zpk (@var{sys}) 22## @deftypefnx {Function File} {@var{sys} =} zpk (@var{k}, @dots{}) 23## @deftypefnx {Function File} {@var{sys} =} zpk (@var{z}, @var{p}, @var{k}, @dots{}) 24## @deftypefnx {Function File} {@var{sys} =} zpk (@var{z}, @var{p}, @var{k}, @var{tsam}, @dots{}) 25## @deftypefnx {Function File} {@var{sys} =} zpk (@var{z}, @var{p}, @var{k}, @var{tsam}, @dots{}) 26## Create transfer function model from zero-pole-gain data. 27## This is just a stop-gap compatibility wrapper since zpk 28## models are not yet implemented. 29## 30## @strong{Inputs} 31## @table @var 32## @item sys 33## @acronym{LTI} model to be converted to transfer function. 34## @item z 35## Cell of vectors containing the zeros for each channel. 36## z@{i,j@} contains the zeros from input j to output i. 37## In the SISO case, a single vector is accepted as well. 38## @item p 39## Cell of vectors containing the poles for each channel. 40## p@{i,j@} contains the poles from input j to output i. 41## In the SISO case, a single vector is accepted as well. 42## @item k 43## Matrix containing the gains for each channel. 44## k(i,j) contains the gain from input j to output i. 45## @item tsam 46## Sampling time in seconds. If @var{tsam} is not specified, 47## a continuous-time model is assumed. 48## @item @dots{} 49## Optional pairs of properties and values. 50## Type @command{set (tf)} for more information. 51## @end table 52## 53## @strong{Outputs} 54## @table @var 55## @item sys 56## Transfer function model. 57## @end table 58## 59## @seealso{tf, ss, dss, frd} 60## @end deftypefn 61 62## Author: Lukas Reichlin <lukas.reichlin@gmail.com> 63## Created: September 2011 64## Version: 0.2 65 66function sys = zpk (varargin) 67 68 if (nargin <= 1) # zpk (), zpk (sys), zpk (k), zpk ('s') 69 sys = tf (varargin{:}); 70 return; 71 elseif (nargin == 2 ... 72 && ischar (varargin{1})) # zpk ('z', tsam) 73 sys = tf (varargin{:}); 74 return; 75 endif 76 77 z = {}; p = {}; k = []; # default values 78 tsam = 0; # default sampling time 79 80 [mat_idx, opt_idx] = __lti_input_idx__ (varargin); 81 82 switch (numel (mat_idx)) 83 case 1 84 k = varargin{mat_idx}; 85 case 3 86 [z, p, k] = varargin{mat_idx}; 87 case 4 88 [z, p, k, tsam] = varargin{mat_idx}; 89 if (isempty (tsam) && is_real_matrix (tsam)) 90 tsam = -1; 91 elseif (! issample (tsam, -10)) 92 error ("zpk: invalid sampling time"); 93 endif 94 case 0 95 ## nothing to do here, just prevent case 'otherwise' 96 otherwise 97 print_usage (); 98 endswitch 99 100 varargin = varargin(opt_idx); 101 102 if (isempty (z) && isempty (p) && is_real_matrix (k)) 103 sys = tf (k, varargin{:}); 104 return; 105 endif 106 107 if (! iscell (z)) 108 z = {z}; 109 endif 110 111 if (! iscell (p)) 112 p = {p}; 113 endif 114 115 if (! size_equal (z, p, k)) 116 error ("zpk: arguments 'z', 'p' and 'k' must have equal dimensions"); 117 endif 118 119 ## NOTE: accept [], scalars and vectors but not matrices as 'z' and 'p' 120 ## because poly (matrix) returns the characteristic polynomial 121 ## if the matrix is square! 122 123 if (! is_zp_vector (z{:}, 1)) # last argument 1 needed if z is empty cell 124 error ("zpk: first argument 'z' must be a vector or a cell of vectors"); 125 endif 126 127 if (! is_zp_vector (p{:}, 1)) 128 error ("zpk: second argument 'p' must be a vector or a cell of vectors") 129 endif 130 131 if (! is_real_matrix (k)) 132 error ("zpk: third argument 'k' must be a real-valued gain matrix"); 133 endif 134 135 num = cellfun (@(zer, gain) real (gain * poly (zer)), z, num2cell (k), "uniformoutput", false); 136 den = cellfun (@(pol) real (poly (pol)), p, "uniformoutput", false); 137 138 sys = tf (num, den, tsam, varargin{:}); 139 140endfunction 141