image thumbnail

A Fully Automated Flowgraph Analysis Tool for MATLAB

by

 

22 Mar 2005 (Updated )

A handy signal flow graph analysis tool for exploring transfer function(s) of a given system.

out=find_params(TFS,HS)
function out=find_params(TFS,HS)
% function out=find_params(TFS,HS)
%
% This function solves (if possible) the values for symbolic parameters in HS.
% Basicly this function is about solving a system of equations.
%
% TFS is a transfer function or a cluster of transfer functions from a
% system (tf obj). HS is the same in a symbolic form.
%
% TFS is tf object(s): [TF(1) TF(2) ...]
% HS  is sym obj:      [H1(z) H2(z) ...]  (the variable can be other than z)
%
% For Delta sigma modulator designers:
% Does the same as in DS toolbox [a,g,b,c]=realizeNTF(NTF,FORM,STF), but the
% FORM is now not restricted to 'CIFB', 'CRFB','CIFF' and 'CRFF'.
precision=8;deno=1;denold=1;
stringi='out=solve(';
fprintf('\n')
for main_ind = 1:length(HS)
	H=HS(main_ind);
	TFOBJ=TFS(main_ind);
    if length(HS)>1
        [num,den]=tfdata(tf(minreal(TFOBJ)),'v');
    else
        [num,den]=tfdata(tf(TFOBJ),'v');
    end
    denold=den;
    if length(num)==1    %den==1
        if deno == 1;
            error('if you want a scalar tf, give the tf in num/den form')
        end
        num=num*deno;den=deno; %old tf assumed to be parsed
    end
    deno=den;
	ORDER=max([length(den) length(num)])-1;
	[n,d]=numden(simple(H));
	params_n = extract_symterms(n,ORDER); % Sort numerator  parameters in descending order
	params_d = extract_symterms(d,ORDER); % Sort denominator         ----"----
	for ind =1:length(den)
        if ~isempty(findsym(sym(char(params_n(ind)))))
            stringi=[stringi char(39) char(params_n(ind)) '=' num2str(num(ind),precision) char(39) ','];
		    fprintf('%s = %3.8g\n',char(params_n(ind)),num(ind));
        end
        if ~isempty(findsym(sym(char(params_d(ind))))) & denold == deno %latter is ds add-on for stf
            stringi=[stringi char(39) char(params_d(ind)) '=' num2str(den(ind),precision) char(39) ','];
            fprintf('%s = %3.8g\n',char(params_d(ind)),den(ind));
        end
	end
    stringit{ind}=stringi;
end
stringi(end)=')';stringi=[stringi ';'];
fprintf('\n')
warning off backtrace
eval(stringi)
warning on backtrace

try % to perform numeric evaluation
	fn=fieldnames(out);
	for indf=1:length(fn)
        eval(['blaa.' char(fn(indf)) '=' num2str(char(getfield(out,char(fn(indf)))),32) ';'])
    end
	if ~isempty(out)
        clear out,out=blaa;
	end
end

if isempty(out) & length(HS)>1
    fprintf('\n\nSince explicit solution was not found, lets try solving systems separately:\n')
    out={};
    for main_ind = 1:length(HS)
        out=[out {find_params(TFS(main_ind),HS(main_ind))}];
        out{main_ind}
    end
    if ~isempty(out),fprintf('\nSuccess!!!\n'),end
elseif isempty(out) & length(HS)==1
    fprintf('\n\nNope. Solution not found.\n')
else
    fprintf('\nSuccess!!!\n')
end









function out=extract_symterms(Eq_sym,ORDER,obj)

% function out=extract_symterms(Eq_sym,ORDER,obj)
%
% Sort parameters of symbolic polynomial Eq_sym by finding the
% multiplicands defined in char variable called obj.
% In some cases it is hard to decipher the ORDER of Eq_sym, 
% so I decided to let the user provide it. 
% The output is a cell array whose powers are in descending order,
% i.e highest order parameter is first.
%
% Example:      x=sym('z^3+z^2*(-3+c2*c3*g1)+z*(3-c2*c3*g1)');
%               out=extract_symterms(x,3,'z')
if nargin==2
    obj='z';
elseif nargin==3
    if length(obj)>1
        error('The variable should be a one-letter char')
    elseif isnumeric(obj)
        error('Third term is a character')
    end
end

x=char(expand(Eq_sym));
mask=sort([find(x=='-') find(x=='+')]);
ttt{1}=x(1:(mask(1)-1));

if nargin==1
    mxp=find(char(ttt)=='^');
    mttt=char(ttt);
    ORDER=eval(mttt(mxp+1));
    obj=mttt(mxp-1);
    fprintf('\nWarning: Order and variable are not given, guessing: \nvariable = %c\norder = %i\n',obj,ORDER)
end

for ind=1:(length(mask)-1)
    temp=x(mask(ind):(mask(ind+1)-1));
    ttt{ind+1}=temp;
end
ttt{ind+2}=x(mask(end):end);

for ORD=0:ORDER
	termi=[];
	for ind=1:length(ttt)
        if ORD==1
            if any(char(ttt(ind))==obj) & ~any(char(ttt(ind))=='^')
                termi=[termi '+' char(ttt(ind))];
            end
        elseif ORD==0
            if ~any(char(ttt(ind))==obj)
            %if (char(ttt(ind:(ind+length(obj)-1)))==obj)
                termi=[termi '+' char(ttt(ind))];
            end
        else
            if findstr(char(ttt(ind)),[obj '^' int2str(ORD)])
                termi=[termi '+' char(ttt(ind))];
            end
        end
	end
    mask=sort([findstr(termi,'++') findstr(termi,'--')]);
    for innnd=length(mask):-1:1
        termi(mask(innnd)+1)=[];
        termi(mask(innnd))='+';
    end
    mask=sort([findstr(termi,'-+') findstr(termi,'+-')]);
    for innnd=length(mask):-1:1
        termi(mask(innnd)+1)=[];
        termi(mask(innnd))='-';
    end
    if ORD>0 & ~isempty(termi)
        termi=char(simplify(sym(['(' termi ')/' obj '^' int2str(ORD)])));
    end
    if isempty(termi),termi='0';end
    out{ORD+1}=termi;
end
out = flipud(transpose(out));




Contact us