www.gusucode.com > rf 工具箱matlab源码程序 > rf/s2rlgc.m

    function output = s2rlgc(s_params,linelength,freq,z0,port_reorder)
%S2RLGC Converts S-parameters of a transmission line to RLGC-parameters
%   OUTPUT = S2RLGC(S_PARAMS, LINELENGTH, FREQ, Z0, PORT_REORDER) converts
%   the scattering parameters S_PARAMS of a transmission line into
%   RLGC-matrices
%   
%   S_PARAMS is a complex 2N-by-2N-by-M array, where M is the number of 
%   frequency points at which the S-parameters are specified and N is 
%   the number of transmission lines.
%   LINELENGTH is the length of the transmission line 
%   FREQ is a real Mx1 frequency vector
%   Z0 is the reference impedance, the default is 50 ohms.
%   PORT_REORDER IS A 2Nx1 vector indicating the input and output ports
%   [IP... OP ...]
%   
%   The outputs are per unit length transmission line parameters 
%   OUTPUT.R is a real N-by-N-by-M Resistance matrix (ohm/m) 
%   OUTPUT.L is a real N-by-N-by-M Inductance matrix (H/m) 
%   OUTPUT.C is a real N-by-N-by-M Capacitance matrix (F/m) 
%   OUTPUT.G is a real N-by-N-by-M Conductance matrix (S/m) 
%   OUTPUT.Zc is a complex N-by-N-by-M Characteristic line impedance(ohm) 
%   OUTPUT.alpha is a real N-by-N-by-M attenuation constant (Nepers/m) 
%   OUTPUT.beta is a real N-by-N-by-M phase constant (radians/m) 
%
%   See also ABCD2S, S2Y, S2Z, S2H, Y2ABCD, Z2ABCD, H2ABCD, RLGC2S
%   Copyright 2003-2015 The MathWorks, Inc.

narginchk(3,5)

num_lines = size(s_params,1)/2;   % Number of transmission lines
freqpts = size(freq,1);         % Number of frequency points

if nargin < 4
    z0 = 50;
else
    if ~isscalar(z0)
        error(message('rf:s2rlgc:InvalidInputZ0NonScalar'))
    end
    if (isnan(z0) || isinf(z0))
        error(message('rf:s2rlgc:InvalidInputZ0NanInf'))
    end
end
        
if nargin < 5
    port_reorder = [];
end

if ~isempty(port_reorder)
    if(size(port_reorder,2) ~= 2*num_lines)
        error(message('rf:s2rlgc:InvalidInputPortReorder'))
    end
    s_params = snp2smp(s_params,z0,port_reorder);
end


% Check the input S-parameters
m = CheckNetworkData(s_params,2*num_lines,'S_PARAMS');

% Check the S-parameters for passivity
if ~ispassive(s_params,'Impedance',z0)
    error(message('rf:s2rlgc:InvalidInputpassiveS'))
end

if (m ~= freqpts)
    error(message('rf:s2rlgc:InvalidInputFreqLength'))
end

if ~isscalar(linelength)
    error(message('rf:s2rlgc:InvalidInputscalarlen'))
end

if (linelength <= 0 || isnan(linelength) || isinf(linelength) || ...
        ~isnumeric(linelength) || isempty(linelength))
    error(message('rf:s2rlgc:InvalidInputLength'))
end

if(any(freq<0) || any(isinf(freq)) || any(isnan(freq)) || isempty(freq))
    error(message('rf:s2rlgc:InvalidInputFreq'));
end

% Allocate the memory for RLGC matrix
R = zeros(num_lines,num_lines,freqpts);     % Resistance matrix
L = zeros(num_lines,num_lines,freqpts);     % Inductance matrix
C = zeros(num_lines,num_lines,freqpts);     % Capacitance matrix
G = zeros(num_lines,num_lines,freqpts);     % Conductance matrix
Zc = zeros(num_lines,num_lines,freqpts);    % Characteristic impedance
gamma = zeros(num_lines,num_lines,freqpts); % Propagation term

if freq(1) == 0
    freq(1) = 1e-6;
end

if num_lines == 1 
    for m = 1:freqpts
        S11 = s_params(1,1,m);
        S21 = s_params(2,1,m);
        
        K = sqrt(((S11^2 - S21^2 + 1)^2 - (2*S11)^2)/(2*S21)^2);
        exp_gamma_l1 = inv(((1- S11^2 + S21^2)/(2*S21)) + K);
        
        Z2_num = (1 + S11)^2 - S21^2;
        Z2_den = (1 - S11)^2 - S21^2;
        Z_square = z0^2*Z2_num/Z2_den;
        
        gamma(:,:,m) = -log(exp_gamma_l1)/linelength;
        Zc(:,:,m) = sqrt(Z_square);
    end
    alpha = abs(real(gamma));
    beta = abs(imag(gamma));
    gamma = complex(alpha,beta);

elseif num_lines > 1   
    % Calculare the propagation constant and attenuation constant
    I = eye(num_lines,num_lines);
    for m = 1:freqpts
        % Calculate the D term of the Transmission line matrix
        S11 = s_params(1:num_lines, 1:num_lines,m);
        S12 = s_params(1:num_lines, num_lines+1:end,m);
        S21 = s_params(num_lines+1:end, 1:num_lines,m);
        S22 = s_params(num_lines+1:end, num_lines+1:end,m);
        Td =  ((I - S11)*(I + S22)+ S12*S21)/(2*S21);
        
        % Calculate the eigen values and eigen-vectors of the Td matrix
        [V,D] = eig(Td);
        
        for n= 1:num_lines
            D(n,n) = acosh(D(n,n))/linelength;
        end
        gamma(:,:,m) = V*D/V;
    end
    
    alpha = real(gamma);
    beta = imag(gamma);
    
    for m = 1:num_lines
        for n = 1:num_lines
            beta(m,n,:) = abs(beta(m,n,:));
            alpha(m,n,:) = abs(alpha(m,n,:));
        end
    end
    gamma = complex(alpha,beta);
    
    Z_params = s2z(s_params,z0);
    for m = 1:freqpts
        sinh_gamma = funm(gamma(:,:,m)*linelength,@sinh);
        if abs(sinh_gamma) < eps
            Zc(:,:,m) = eps;
        else
            Zc(:,:,m) = Z_params(num_lines+1:end,1:num_lines,m)*sinh_gamma;
        end
    end    
end

% Calculate the RLCG matrices
num_terms = num_lines*num_lines;
for m= 1:freqpts        
    R_temp = real(Zc(:,:,m)*gamma(:,:,m));
    L_temp = imag(Zc(:,:,m)*gamma(:,:,m))./(2*pi*freq(m));
    G_temp = real(gamma(:,:,m)/Zc(:,:,m));
    C_temp = imag(gamma(:,:,m)/Zc(:,:,m))./(2*pi*freq(m));
    
    R(:,:,m) = 0.5*(R_temp + R_temp.');
    L(:,:,m) = 0.5*(L_temp + L_temp.');
    G(:,:,m) = 0.5*(G_temp + G_temp.');
    C(:,:,m) = 0.5*(C_temp + C_temp.');
    
    % Check if calcuated vaues are correct
    % The diagonal terms of L and C are positive, non-zero.
    % The diagonal terms of R and G are non-negative (can be zero).
    % Off-diagonal terms of the L matrix are non-negative.
    % Off-diagonal terms of C and G matrices are non-positive. 
    if(((any(diag(L(:,:,m))<= 0) ||  any(diag(C(:,:,m))<= 0)) &&  freq(m) ~= 0.0) ...
            || (any(diag(R(:,:,m))< 0) ||  any(diag(G(:,:,m))< 0)) ...
            || (any(any(L(:,:,m) <0)) && num_lines>1) ...
            || ((sum(sum(C(:,:,m) <=0)) == num_terms*(num_terms-1)) && num_lines>1) ...
            || ((sum(sum(G(:,:,m) <=0)) == num_terms*(num_terms-1)) && num_lines>1))
        error(message('rf:s2rlgc:InvalidRLGC'))
    end
end

output = struct('R',R,'L',L,'G',G,'C',C,'alpha',alpha,'beta',beta,'Zc',Zc);