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

    function DGDF = latticemamindggen(q,Hd,coeffnames,doMapCoeffsToPorts,states)
%LATTICEMAMINDGGEN Directed Graph generator for Discrete MA Minimum Phase
%lattice filter

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

narginchk(5,5);

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

% 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_latticemamin_stages(q,num,Hd,info);

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

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

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

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

% create demux
if info.doMapCoeffsToPorts && ~isempty(info.coeffnames)
    % info.coeffnames is empty when it is header_order0 case, where the
    % coefficient of the Lattice is empty. Thus, no implementation for
    % demux.
    Stg(length(Stg)+1) = demux(q,H,max_order,info.coeffnames{1});    % demux for K
    if max_order > 1
        % for first order latticemamin, only K is used
        Stg(length(Stg)+1) = demux(q,H,max_order,info.coeffnames{2});    % demux for K*
    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,'latticemamin','lr');

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

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

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);


% 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');


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

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

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

% Specify coefficieint names
plabel = {}; qlabel = {};
if info.doMapCoeffsToPorts
    plabel{1} = sprintf('%s%d',info.coeffnames{1},1);
    qlabel{1} = sprintf('%s%d',info.coeffnames{2},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,:))]);

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

[NL, NextIPorts, NextOPorts, mainparams] = latticemamaxheadconnect(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,H,info,q)

% Generating the repeating middle layers

NL=filtgraph.nodelist(5);

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);


% 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');


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

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

% Main parameters of the blocks
% PGAIN = Lattice --> Q Block ; QGAIN = conj(Lattice) --> P Block
pgain = {'0'}; qgain = {'0'};
for stage = 2:(info.nstages-1)
    pgain{stage-1} = NL.coeff2str(num,stage);
    qgain{stage-1} = NL.coeff2str(conj(num),stage);

    psum_str{stage-1}='|++';  %left sum
    qsum_str{stage-1}='++|';
    
    delay_str{stage-1}=['1,' mat2str(info.states(stage,:))];

end

% Specify coefficieint names
plabel = {}; qlabel = {};
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);
    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);

% add a connector for interstage connection.  Cannot do sameport twice
% since for interbody stages, output is (1,1) (1,1) and (4,1) while once it
% connects to foot, it becomes (1,1) and (4,1), not consistent.
NL.setnode(filtgraph.node('connector'),6);
set(NL.nodes(6),'position',[0.1 0 0.1 0]);
mainparams(6) = filtgraph.indexparam(6,{});


% 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]=latticemaminbodyconnect(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,H,info,q)

% Generate the last layer of the structure.

NL=filtgraph.nodelist(4);

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


% 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');


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

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

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

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

mainparams(1)=filtgraph.indexparam(1,'|++');
mainparams(2)=filtgraph.indexparam(2,pgain,plabel);
mainparams(3)=filtgraph.indexparam(3,['1,' mat2str(info.states(info.nstages,:))]);

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

% 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'),5);
set(NL.nodes(5),'position',[1.2 0 1.2 0]);
mainparams(5)=filtgraph.indexparam(5,qgain,qlabel);


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

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