www.gusucode.com > signal 工具箱matlab源码程序 > signal/@dfilt/@filterquantizer/latticearmadggen.m

    function DGDF = latticearmadggen(q,Hd,coeffnames,doMapCoeffsToPorts,states)
%LATTICEARMADGGEN Directed Graph generator for Discrete AR
%lattice filter

%   Author(s): Honglei Chen
%   Copyright 1988-2004 The MathWorks, Inc.

narginchk(5,5);

coefs = coefficients(reffilter(Hd));
num=coefs{1};
den=coefs{2};

% Get filter states and coefficient names
info.states = states;
info.coeffnames = coeffnames;
info.doMapCoeffsToPorts = doMapCoeffsToPorts;

% Represent the filter in terms of DG_Dfilt
DGDF = gen_DG_latticearma_stages(q,num,den,Hd,info);

% -------------------------------------------------------------------------
%
% gen_DG_dffir_stages: Generates the DG_DFILT representation
%   by constructing each "Stage" of the filter.
%
% -------------------------------------------------------------------------
function DGDF = gen_DG_latticearma_stages(q,num,den,H,info)

% Remove trailing zero-coefficients in polynomials:
num = num(1:max(find(num~=0)));
den = den(1:max(find(den~=0)));

%determine the number of layers required to construct the filter
max_order = max(length(num),length(den));
info.nstages = max_order; 

% Create the header, body and the footer.
if max_order > 2
    Stg(1) = header(num,den,H,info,q);
    Stg(2) = body(num,den,H,info,q);
    Stg(3) = footer(num,den,H,info,q);
elseif max_order > 1
    Stg(1) = header(num,den,H,info,q);
    Stg(2) = footer(num,den,H,info,q);
else
    Stg = latticearmaheader_order0(q,num,den,H,info);
end

% create demux
nK = length(num); nV = length(den);
if info.doMapCoeffsToPorts 
    if max_order<=1
        % This is the case when Lattice is an empty matrix e.g. the
        % header_order0. The only Lattice's non-conjugated coefficient is
        % implemented. Thus, we don't need a demux for K*.
        Stg(length(Stg)+1) = demux(q,H,nV,info.coeffnames{1});    % demux for K
        Stg(length(Stg)+1) = demux(q,H,nV,info.coeffnames{2});    % demux for V
    else
        Stg(length(Stg)+1) = demux(q,H,info.nstages,info.coeffnames{1});    % demux for K
        Stg(length(Stg)+1) = demux(q,H,info.nstages,info.coeffnames{2});    % demux for K*
        Stg(length(Stg)+1) = demux(q,H,info.nstages,info.coeffnames{3});    % demux for V
    end
end

% make a DG_DFILT out of it.
% dg_dfilt is the bridge between the dfilt representation
% and directed graph representation

DGDF = filtgraph.dg_dfilt(Stg,'latticearma','rl');

% --------------------------------------------------------------
%
% head: Generate the conceptual header stage for Discrete FIR architecture
%
%   Returns a filtgraph.stage,
% --------------------------------------------------------------
function Head = header(num,den,H,info,q)

% Construct the first layer, structure specific
NL=filtgraph.nodelist(8);

NL.setnode(filtgraph.node('sum'),1);
NL.setnode(filtgraph.node('gain'),2);
NL.setnode(filtgraph.node('gain'),3);
NL.setnode(filtgraph.node('sum'),4);
NL.setnode(filtgraph.node('delay'),5);
NL.setnode(filtgraph.node('gain'),6);
NL.setnode(filtgraph.node('sum'),7);


% specify the block label
set(NL.nodes(1).block,'label','BodyQSum');
set(NL.nodes(2).block,'label','K');
set(NL.nodes(3).block,'label','K*');
set(NL.nodes(4).block,'label','BodyPSum');
set(NL.nodes(5).block,'label','BodyDelay');
set(NL.nodes(6).block,'label','V');
set(NL.nodes(7).block,'label','BodyVSum');


% specify the relative position towards the grid
set(NL.nodes(1),'position',[0.3 0 0.3 0]);
set(NL.nodes(2),'position',[0.4 0.3 0.4 0.3]);
set(NL.nodes(3),'position',[0.4 0.7 0.4 0.7]);
set(NL.nodes(4),'position',[0.3 1 0.3 1]);
set(NL.nodes(5),'position',[0.7 1 0.7 1]);
set(NL.nodes(6),'position',[1 1.25 1 1.25]);
set(NL.nodes(7),'position',[1 1.5 1 1.5]);

% specify the orientation
set(NL.nodes(1).block,'orientation','right');
set(NL.nodes(2).block,'orientation','left');
set(NL.nodes(3).block,'orientation','left');
set(NL.nodes(4).block,'orientation','left');
set(NL.nodes(5).block,'orientation','left');
set(NL.nodes(6).block,'orientation','down');
set(NL.nodes(7).block,'orientation','right');

% Obtain the correct value for the gain block
pgain = NL.coeff2str(num(1),1);
qgain = NL.coeff2str(conj(num(1)),1);
ladgain = NL.coeff2str(den,1);

% Specify coefficieint names
plabel = {}; qlabel = {}; ladlabel = {};
if info.doMapCoeffsToPorts
    plabel{1} = sprintf('%s%d',info.coeffnames{1},1);
    qlabel{1} = sprintf('%s%d',info.coeffnames{2},1);
    ladlabel{1} = sprintf('%s%d',info.coeffnames{3},1);
end

% store the useful information into blocks
mainparams(1)=filtgraph.indexparam(1,'|+-');
mainparams(2)=filtgraph.indexparam(2,pgain,plabel);
mainparams(3)=filtgraph.indexparam(3,qgain,qlabel);
mainparams(4)=filtgraph.indexparam(4,'++|');
mainparams(5)=filtgraph.indexparam(5,['1,' mat2str(info.states(1,:))]);
mainparams(6)=filtgraph.indexparam(6,ladgain,ladlabel);
mainparams(7)=filtgraph.indexparam(7,'++|');

%add output
NL.setnode(filtgraph.node('output'),8);
set(NL.nodes(8).block,'label','Output');
set(NL.nodes(8),'position',[2 1.5 2 1.5]);
set(NL.nodes(8).block,'orientation','right');
mainparams(8)=filtgraph.indexparam(8,{});

[NL, NextIPorts, NextOPorts, mainparams] = latticearmaheadconnect(q,NL,H,mainparams);

% Generate the stage.
Head = filtgraph.stage(NL,[],[],NextIPorts,NextOPorts,mainparams);

% --------------------------------------------------------------
%
% body: Generate the conceptual repeating body stage for the
% Direct Form I architecture
%   Returns a filtgraph.stage,
% --------------------------------------------------------------
function Body = body(num,den,H,info,q)

% Generating the repeating middle layers

NL=filtgraph.nodelist(7);

NL.setnode(filtgraph.node('sum'),1);
NL.setnode(filtgraph.node('gain'),2);
NL.setnode(filtgraph.node('gain'),3);
NL.setnode(filtgraph.node('sum'),4);
NL.setnode(filtgraph.node('delay'),5);
NL.setnode(filtgraph.node('gain'),6);
NL.setnode(filtgraph.node('sum'),7);


% specify the block label

set(NL.nodes(1).block,'label','BodyQSum');
set(NL.nodes(2).block,'label','K');
set(NL.nodes(3).block,'label','K*');
set(NL.nodes(4).block,'label','BodyPSum');
set(NL.nodes(5).block,'label','BodyDelay');
set(NL.nodes(6).block,'label','V');
set(NL.nodes(7).block,'label','BodyVSum');


% specify the relative position towards the grid
set(NL.nodes(1),'position',[0.3 0 0.3 0]);
set(NL.nodes(2),'position',[0.4 0.3 0.4 0.3]);
set(NL.nodes(3),'position',[0.4 0.7 0.4 0.7]);
set(NL.nodes(4),'position',[0.3 1 0.3 1]);
set(NL.nodes(5),'position',[0.7 1 0.7 1]);
set(NL.nodes(6),'position',[1 1.25 1 1.25]);
set(NL.nodes(7),'position',[1 1.5 1 1.5]);

% specify the orientation
set(NL.nodes(1).block,'orientation','right');
set(NL.nodes(2).block,'orientation','left');
set(NL.nodes(3).block,'orientation','left');
set(NL.nodes(4).block,'orientation','left');
set(NL.nodes(5).block,'orientation','left');
set(NL.nodes(6).block,'orientation','down');
set(NL.nodes(7).block,'orientation','right');

% Main parameters of the blocks
pgain = {'0'}; qgain = {'0'}; ladgain={'0'};
for stage = 2:(info.nstages-1)
    pgain{stage-1} = NL.coeff2str(num,stage);
    qgain{stage-1} = NL.coeff2str(conj(num),stage);
    ladgain{stage-1} = NL.coeff2str(den,stage);
    
    psum_str{stage-1}='|+-';  %left sum
    qsum_str{stage-1}='++|';
    vsum_str{stage-1}='++|';
    
    delay_str{stage-1}=['1,' mat2str(info.states(stage,:))];

end

% Specify coefficieint names
plabel = {}; qlabel = {}; ladlabel = {};
if info.doMapCoeffsToPorts
    for stage = 2:(info.nstages-1)
        plabel{stage-1} = sprintf('%s%d',info.coeffnames{1},stage);
        qlabel{stage-1} = sprintf('%s%d',info.coeffnames{2},stage);
        ladlabel{stage-1} = sprintf('%s%d',info.coeffnames{3},stage);
    end
end

mainparams(1) = filtgraph.indexparam(1,psum_str);
mainparams(2) = filtgraph.indexparam(2,pgain,plabel);
mainparams(3) = filtgraph.indexparam(3,qgain,qlabel);
mainparams(4) = filtgraph.indexparam(4,qsum_str);
mainparams(5) = filtgraph.indexparam(5,delay_str);
mainparams(6) = filtgraph.indexparam(6,ladgain,ladlabel);
mainparams(7) = filtgraph.indexparam(7,vsum_str);

% Set extra parameters like fixed point attributes.  Also defines the extra
% blocks needed for fixed point model.  Connection among nodes will be
% generated in this function.  The interstage connection is also specified
% here.
[NL, PrevIPorts, PrevOPorts, NextIPorts, NextOPorts, mainparams]=latticearmabodyconnect(q,NL,H,mainparams);

% The number of repetitions
bstages = info.nstages - 2;


Body = filtgraph.stage(NL, PrevIPorts, PrevOPorts,...
    NextIPorts, NextOPorts, mainparams, [], bstages);

% --------------------------------------------------------------
%
% footer: Generate the conceptual footer stage for Direct Form I
% architecture
%
%   Returns a filtgraph.stage,
% --------------------------------------------------------------
function Foot = footer(num,den,H,info,q)

% Generate the last layer of the structure.

NL=filtgraph.nodelist(6);

NL.setnode(filtgraph.node('sum'),1);
NL.setnode(filtgraph.node('gain'),2);
NL.setnode(filtgraph.node('delay'),3);
NL.setnode(filtgraph.node('gain'),4);


% specify the block label
set(NL.nodes(1).block,'label','BodyQSum');
set(NL.nodes(2).block,'label','K');
set(NL.nodes(3).block,'label','BodyDelay');
set(NL.nodes(4).block,'label','V');


% specify the relative position towards the grid
set(NL.nodes(1),'position',[0.3 0 0.3 0]);
set(NL.nodes(2),'position',[0.4 0.3 0.4 0.3]);
set(NL.nodes(3),'position',[0.7 1 0.7 1]);
set(NL.nodes(4),'position',[1 1.25 1 1.25]);

% specify the orientation
set(NL.nodes(1).block,'orientation','right');
set(NL.nodes(2).block,'orientation','left');
set(NL.nodes(3).block,'orientation','left');
set(NL.nodes(4).block,'orientation','down');

% set up the parameter
pgain = {'0'}; qgain = {'0'}; ladgain={'0'};
pgain = NL.coeff2str(num,info.nstages); 
qgain = NL.coeff2str(conj(num),info.nstages);
ladgain = NL.coeff2str(den,info.nstages); 

% Specify coefficieint names
plabel = {}; qlabel = {}; ladlabel = {};
if info.doMapCoeffsToPorts
    plabel{1} = sprintf('%s%d',info.coeffnames{1},info.nstages);
    qlabel{1} = sprintf('%s%d',info.coeffnames{2},info.nstages);
    ladlabel{1} = sprintf('%s%d',info.coeffnames{3},info.nstages);
end

% Initial condition for Footer
footIC = info.states(end,:);
if size(info.states,1)<info.nstages
    % If the last Lattice's coefficient is 0, set the initial condition to
    % be 0. This corresponds to the zero-padding stage. The delay will be
    % eventually optimized unless the OptimizeZeros is turned off.
    footIC = 0;
end

mainparams(1)=filtgraph.indexparam(1,'|+-');
mainparams(2)=filtgraph.indexparam(2,pgain,plabel);
mainparams(3)=filtgraph.indexparam(3,['1,' mat2str(footIC)]);
mainparams(4)=filtgraph.indexparam(4,ladgain,ladlabel);

% add input and output
NL.setnode(filtgraph.node('input'),5);
set(NL.nodes(5).block,'label','Input');
set(NL.nodes(5),'position',[-0.5 0 -0.5 0]);
set(NL.nodes(5).block,'orientation','right');
mainparams(5)=filtgraph.indexparam(5,{});

% Add a connector node with a gain label to make sure that the number of
% goto blocks and from blocks match when MapCoeffsToPorts is on. The
% optimization will remove the associated goto block. The connector node
% will be removed by the garbage collector.
NL.setnode(filtgraph.node('connector'),6);
set(NL.nodes(6),'position',[-0.5 0 -0.5 0]);
mainparams(6)=filtgraph.indexparam(6,qgain,qlabel);

[NL, PrevIPorts, PrevOPorts, mainparams]=latticearmafootconnect(q,NL,H,mainparams);

Foot = filtgraph.stage(NL, PrevIPorts, PrevOPorts, [], [], mainparams);