This commit is contained in:
cypressboat 2023-11-14 17:10:27 +08:00
commit d5a822831c
423 changed files with 5909 additions and 0 deletions

28
.gitattributes vendored Normal file
View File

@ -0,0 +1,28 @@
* text=auto
*.fig binary
*.mat binary
*.mdl binary diff merge=mlAutoMerge
*.mdlp binary
*.mex* binary
*.mlapp binary
*.mldatx binary
*.mlproj binary
*.mlx binary
*.p binary
*.sfx binary
*.sldd binary
*.slreqx binary merge=mlAutoMerge
*.slmx binary merge=mlAutoMerge
*.sltx binary
*.slxc binary
*.slx binary merge=mlAutoMerge
*.slxp binary
## Other common binary file types
*.docx binary
*.exe binary
*.jpg binary
*.pdf binary
*.png binary
*.xlsx binary

33
.gitignore vendored Normal file
View File

@ -0,0 +1,33 @@
# Autosave files
*.asv
*.m~
*.autosave
*.slx.r*
*.mdl.r*
# Derived content-obscured files
*.p
# Compiled MEX files
*.mex*
# Packaged app and toolbox files
*.mlappinstall
*.mltbx
# Deployable archives
*.ctf
# Generated helpsearch folders
helpsearch*/
# Code generation folders
slprj/
sccprj/
codegen/
# Cache files
*.slxc
# Cloud based storage dotfile
.MATLABDriveTag

BIN
Coop3LeaderFollower1D8.slx Normal file

Binary file not shown.

BIN
Coop3LeaderFollower2.slx Normal file

Binary file not shown.

BIN
Coop3LeaderFollower2D2.slx Normal file

Binary file not shown.

16
FOTF Toolbox/@foss/bode.m Normal file
View File

@ -0,0 +1,16 @@
function H=bode(G,varargin)
% bode - draw Bode diagram for an FOSS object
%
% bode(G,w)
% H=bode(G,w)
%
% G - the FOSS object
% w - the frequency vector
% H - the frequency response data in FRD format
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
if nargout==0, bode(fotf(G),varargin{:});
else, H=bode(fotf(G),varargin{:}); end
end

View File

@ -0,0 +1,21 @@
function G1=coss_aug(G,k)
% coss_aug - state augmentation of an FOSS object
%
% G1=coss_aug(G,k)
%
% G - the FOSS object
% k - integer so that original n states can be augmented into n*k states
% G1 - the augmented FOSS model
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
if G.alpha==0 || k==1, G1=G;
else, alpha=G.alpha/k; G=fotf(G); [n,m]=size(G);
for i=1:n, for j=1:m, g=G(i,j);
a=g.den.a; na=g.den.na; b=g.num.a; nb=g.num.na;
ii=1:k:k*length(a); a1(ii)=a;
ii=1:k:k*length(b); b1(ii)=b; G2(i,j)=tf(b1,a1);
end, end
G1=foss(ss(G2)); G1.alpha=alpha;
end, end

13
FOTF Toolbox/@foss/ctrb.m Normal file
View File

@ -0,0 +1,13 @@
function Tc=ctrb(G)
% ctrb - create a controllability test matrix for an FOSS
%
% Tc=ctrb(G)
%
% G - the FOSS object
% Tc - the controllability test matrix
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
Tc=ctrb(G.a,G.b);
end

14
FOTF Toolbox/@foss/disp.m Normal file
View File

@ -0,0 +1,14 @@
function disp(G)
% display - display an FOSS. This function will be called automatically
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
disp('E*(d^alpha*X)(t)=A*X(t)+B*U(t-T)'), T=G.ioDelay;
disp('Y(t)=C*X(t)+D*U(t-T)'); ss(G.a,G.b,G.c,G.d)
if ~isempty(G.E), disp('Descriptor matrix'), E=G.E, end
if sum(T(:)), disp(['Time Delay is = ' mat2str(T)]); end
disp(['alpha = ',num2str(G.alpha)]);
if ~isempty(G.x0), x0=G.x0;
disp(['Initil state vector x0 = [' num2str(x0(:).'),']'])
end, end

13
FOTF Toolbox/@foss/eig.m Normal file
View File

@ -0,0 +1,13 @@
function p=eig(G)
% eig - finding all the pseudo poles of an FOSS object
%
% p=eig(G)
%
% G - the FOSS object
% p - all the pseudo-poles of G
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
p=eig(G.a)
end

13
FOTF Toolbox/@foss/eq.m Normal file
View File

@ -0,0 +1,13 @@
function key=eq(G1,G2)
% eq - test whether two FOSS objects are equal or not
%
% key=G1==G2
%
% G1, G2 - the two FOSS objects
% key = 1 for equal, otherwise key = 0
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
key=fotf(G1)==fotf(G2);
end

View File

@ -0,0 +1,24 @@
function G=feedback(G1,G2)
% feedback - find the overall model of two FOSS objects in feedback connection
%
% G=feedback(G1,G2)
%
% G1, G2 - the FOSS objects in the forward and backward paths
% G - the overall model of the closed-loop system
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
G1=foss(G1); G2=foss(G2);
if length(G1.alpha)>1 || length(G2.alpha)>1, a=0.0001;
else, a=common_order(G1.alpha,G2.alpha); end
if a==0
G=foss([],[],[],G1.d*inv(eye(size(G1.d))+G2.d*G1.d),0);
elseif a<0.001
G1=fotf(G1); G2=fotf(G2); G=foss(feedback(G1,G2));
else
G1=coss_aug(G1,round(G1.alpha/a));
G2=coss_aug(G2,round(G2.alpha/a));
G=foss(feedback(ss_extract(G1),ss_extract(G2))); G.alpha=a;
end
end

25
FOTF Toolbox/@foss/foss.m Normal file
View File

@ -0,0 +1,25 @@
% foss - class constructor for an FOSS class
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
classdef foss
properties, a, b, c, d, alpha, ioDelay, E, x0, end
methods
function G=foss(a,b,c,d,alpha,L,E,x0)
if nargin<=7, x0=[]; end
if nargin<=6, E=[]; end, if nargin<=5, L=0; end
if nargin==1 && isa(a,'foss'), G=a;
elseif nargin==1 && isa(a,'fotf'), G=fotf2foss(a);
elseif nargin==1 && isa(a,'double'), G=foss([],[],[],a,0);
elseif (nargin==1||nargin==2) && (isa(a,'tf')||isa(a,'ss'))
alpha=1; if nargin==2, alpha=b; end
a=ss(a); L=a.ioDelay; [a,b,c,d,E]=dssdata(a);
G=foss(a,b,c,d,alpha,L,E);
elseif nargin>=5, msg=abcdchk(a,b,c,d);
if length(msg)>0, error(msg)
else, G.alpha=alpha; G.x0=x0;
G.a=a; G.b=b; G.c=c; G.d=d; G.E=E; G.ioDelay=L;
end
else, error('wrong input arguments'); end
end, end, end

View File

@ -0,0 +1,24 @@
function G1=foss2fotf(G)
% foss2fotf - convert an FOSS object to FOTF one
%
% G1=foss2fotf(G)
%
% G - an FOSS object
% G1 - an equivalent FOTF object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G); G1=fotf(zeros(n,m));
G0=ss_extract(G); G0=tf(G0); key=length(G.alpha)>1;
T=G.ioDelay; if isscalar(T), T=T*ones(n,m); end
if key~=0
n0=G.alpha; n1=n0(end:-1:1); n2=0;
for i=1:length(n1), n2(i+1)=n2(i)+n1(i); end
n2=n2(end:-1:1);
end
for i=1:n, for j=1:m, g=G0(i,j);
[num,den]=tfdata(g,'v');
if key==0, n2=((length(den)-1):-1:0)*G.alpha; end
h=fotf(den,n2,num,n2,T(i,j)); h=simplify(h); G1(i,j)=h;
end, end, end

View File

@ -0,0 +1,15 @@
function Y=impulse(G,varargin)
% impulse - impulse response evaluation of an FOSS object
%
% impulse(G,t)
%
% G - an FOSS object
% t - the time vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
if nargout==0, impulse(fotf(G),varargin{:});
else, Y=impulse(fotf(G),varargin{:});
end
end

12
FOTF Toolbox/@foss/inv.m Normal file
View File

@ -0,0 +1,12 @@
function G1=inv(G)
% inv - inverse of a multivariable FOSS system
%
% G1=inv(G)
%
% G, G1 - an FOSS object and its inverse system
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
H=inv(ss_extract(G)); G1=foss(H); G1.alpha=G.alpha;
end

View File

@ -0,0 +1,12 @@
function key=isfoss(G)
% isfoss - check whether input is an FOSS object
%
% key=isfoss(G)
%
% G - an FOSS object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
key=strcmp(class(G),'foss');
end

View File

@ -0,0 +1,20 @@
function [K,alpha,apol]=isstable(G)
% isstable - check whether an FOSS object is stable or not
%
% [K,alpha,apol]=isstable(G)
%
% G - an FOSS object
% K- identifier to indicate the stability of G, returns 0, and 1
% alpha - the common order
% apol - all the pseudo poles of the system
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
p=eig(G); alpha=G.alpha;
plot(real(p),imag(p),'x',0,0,'o')
apol=min(abs(angle(p))); K=apol>alpha*pi/2;
xm=xlim; if alpha<1, xm(1)=0; else, xm(2)=0; end
a1=tan(alpha*pi/2)*xm; a2=tan(alpha*pi)*xm;
line(xm,a1), line(xm,-a1), line(xm,a2), line(xm,-a2)
end

15
FOTF Toolbox/@foss/lsim.m Normal file
View File

@ -0,0 +1,15 @@
function Y=lsim(G,varargin)
% lsim - simulation of an FOSS object driven by given inputs
%
% lsim(G,u,t)
%
% G - an FOSS object
% u, t- input samples and time vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
if nargout==0, lsim(fotf(G),varargin{:});
else, Y=lsim(fotf(G),varargin{:});
end
end

View File

@ -0,0 +1,14 @@
function [Gm,Pm,Wcg,Wcp]=margin(G)
% margin - gain and phase margins of an FOSS object
%
% [Gm,Pm,Wcg,Wcp]=margin(G)
%
% G - an FOSS object
% Gm, Wcg - gain margin in dBs and the corresponding frequency
% Pm, Wcp - phase margin in degrees and the crossover frequency
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[Gm,Pm,Wcg,Wcp]=margin(fotf(G));
end

14
FOTF Toolbox/@foss/mfrd.m Normal file
View File

@ -0,0 +1,14 @@
function H=mfrd(G,varargin)
% mfrd - evaluation of frequency responses of an FOSS object
%
% H=mfrd(G,w)
%
% G - an FOSS object
% w - frequency vector
% H - frequency response of G in MFD format
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
H=mfrd(fotf(G),varargin{:});
end

View File

@ -0,0 +1,14 @@
function G=minreal(G1)
% minreal - minimum realisation of an FOSS object
%
% G=minreal(G1)
%
% G1 - an FOSS object
% G - minimum realisation of G1 as an FOSS object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
alpha=G1.alpha; G2=ss_extract(G1); G2=minreal(G2);
G=foss(G2); G.alpha=alpha;
end

View File

@ -0,0 +1,10 @@
function G=minus(G1,G2)
% minus - minus operation of two FOSS objects
%
% G=G1-G2
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
G=G1+(-G2);
end

View File

@ -0,0 +1,20 @@
function G1=mpower(G,n)
% mpower - power of an FOSS object
%
% G1=G^n
%
% G - an FOSS object
% n - power. If G is s or constant, n can be any real number,
% If G is an FOSS, n should be integers
% G1 - returns G^n, and an FOSS object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
if n==fix(n), [n1,m1]=size(G); if n<0, G=inv(G); end
if n1==m1
G1=foss(eye(n1)); for i=1:abs(n), G1=G1*G; end
else, error('matrix must be square'); end
else, error('mpower: power must be an integer.');
end
end

View File

@ -0,0 +1,22 @@
function G=mtimes(G1,G2)
% mpower - product of two FOSS objects, series connection
%
% G=G1*G2
%
% G1, G2 - FOSS objects
% G - returns the product of the two FOSS objects
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
G1=foss(G1); G2=foss(G2);
if length(G1.alpha)>1 || length(G2.alpha)>1, a=0.0001;
else, a=common_order(G1.alpha,G2.alpha); end
if a==0, G=foss([],[],[],G1.d*G2.d,0);
elseif a<0.001, G1=fotf(G1); G2=fotf(G2); G=foss(G1*G2);
else
G1=coss_aug(G1,round(G1.alpha/a));
G2=coss_aug(G2,round(G2.alpha/a));
G=foss(ss_extract(G1)*ss_extract(G2)); G.alpha=a;
end
end

View File

@ -0,0 +1,15 @@
function H=nichols(G,varargin)
% nichols - draw the Nichols chart of an FOSS object
%
% nichols(G,w)
%
% G - an FOSS object
% w - the frequency vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
if nargout==0, nichols(fotf(G),varargin{:});
else, H=nichols(fotf(G),varargin{:});
end
end

13
FOTF Toolbox/@foss/norm.m Normal file
View File

@ -0,0 +1,13 @@
function n=norm(G,varargin)
% norm -= norms of an FOSS object
%
% norm(G), norm(G,inf)
%
% G - an FOSS object
% The 2-norm and infinity-norm of G can be evaluated, respectively
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
n=norm(fotf(G),varargin{:});
end

View File

@ -0,0 +1,15 @@
function H=nyquist(G,varargin)
% nyquist - draw the Nyquist plot of an FOSS object
%
% nyquist(G,w)
%
% G - an FOSS object
% w - the frequency vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
if nargout==0, nyquist(fotf(G),varargin{:});
else, H=nyquist(fotf(G),varargin{:});
end
end

13
FOTF Toolbox/@foss/obsv.m Normal file
View File

@ -0,0 +1,13 @@
function To=obsv(G)
% obsv - create an observability test matrix for an FOSS
%
% To=obsv(G)
%
% G - the FOSS object
% To - the observability test matrix
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
To=obsv(G.a,G.c);
end

View File

@ -0,0 +1,13 @@
function n=order(G)
% order - extract the order of an FOSS object
%
% n=order(G)
%
% G - an FOSS object
% n - the order
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
n=length(G.a)*G.alpha;
end

22
FOTF Toolbox/@foss/plus.m Normal file
View File

@ -0,0 +1,22 @@
function G=plus(G1,G2)
% plus - evaluate the sum of two FOSS objects, parallel connection
%
% G=G1+G2
%
% G1, G2 - the two FOSS objects in parallel connection
% G - the sum of G1 and G2
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
G1=foss(G1); G2=foss(G2);
if length(G1.alpha)>1 || length(G2.alpha)>1, a=0.0001;
else, a=common_order(G1.alpha,G2.alpha); end
if a==0, G=foss([],[],[],G1.d+G2.d,0);
elseif a<0.001, G1=fotf(G1); G2=fotf(G2); G=foss(G1+G2);
else
G1=coss_aug(G1,round(G1.alpha/a));
G2=coss_aug(G2,round(G2.alpha/a));
G=foss(ss_extract(G1)+ss_extract(G2)); G.alpha=a;
end
end

View File

@ -0,0 +1,12 @@
function rlocus(G)
% rlocus - draw the root locus of a SISO FOSS object
%
% rlocus(G)
%
% G - a SISO FOSS object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
rlocus(fotf(G))
end

14
FOTF Toolbox/@foss/size.m Normal file
View File

@ -0,0 +1,14 @@
function [p,q,n]=size(G)
% size - extract the numbers of inputs, outputs and states of an FOSS object
%
% [p,q,n]=size(G)
%
% G - an FOSS object
% n, m - the numbers of the inputs and outputs
% n - the number of states
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
q=size(G.c,1); p=size(G.b,2); n=length(G.a);
end

View File

@ -0,0 +1,12 @@
function G1=ss_extract(G)
% ss_extract - extract the SS object from an FOSS object
%
% G1=ss_extract(G)
%
% G - an FOSS object
% G1 - the extracted integer-order state space model
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
G1=ss(G.a,G.b,G.c,G.d); G1.E=G.E;
end

15
FOTF Toolbox/@foss/step.m Normal file
View File

@ -0,0 +1,15 @@
function Y=step(G,varargin)
% step - simulation of an FOSS object driven by step inputs
%
% step(G,t)
%
% G - an FOSS object
% t- the time vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
if nargout==0, step(fotf(G),varargin{:});
else, Y=step(fotf(G),varargin{:});
end
end

View File

@ -0,0 +1,13 @@
function G=uminus(G1)
% uminus - unary minus of an FOSS object
%
% G1=-G
%
% G - an FOSS object
% G1- the unary minus of G, i.e., -G
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
G=G1; G.c=-G1.c; G.d=-G1.d;
end

View File

@ -0,0 +1,15 @@
function alpha=base_order(G)
% base_order - find the base order of an FOTF object
%
% alpha=base_order(G)
%
% G - an FOTF object
% alpha - the base order of the system
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G); a=[];
for i=1:n, for j=1:m, g=G(i,j); a=[a,g.num.na,g.den.na]; end, end
alpha=double(gcd(sym(a)));
end

17
FOTF Toolbox/@fotf/bode.m Normal file
View File

@ -0,0 +1,17 @@
function H=bode(G,w)
% bode - draw Bode diagram for an FOTF object
%
% bode(G,w)
% H=bode(G,w)
%
% G - the FOTF object
% w - the frequency vector
% H - the frequency response data in FRD format
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
arguments, G, w=logspace(-4,4); end
H1=freqresp(1j*w,G); H1=frd(H1,w);
if nargout==0, subplot(111), bode(H1); else, H=H1; end
end

18
FOTF Toolbox/@fotf/diag.m Normal file
View File

@ -0,0 +1,18 @@
function G=diag(G1)
% diag - diagonal matrix manipulation of an FOTF object
%
% G=diag(G1)
%
% G - the FOTF object
% G1 - if G is a vector, configurate a matrix G1, otherwise extract its
% diagonal elements to form G1
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G1); nm=max(n,m); nm1=min(n,m);
if m==1 || n==1
G=fotf(zeros(nm,nm)); for i=1:nm, G(i,i)=G1(i); end
else
G=fotf(zeros(nm1,1)); for i=1:nm1, G(i)=G1(i,i); end
end, end

25
FOTF Toolbox/@fotf/disp.m Normal file
View File

@ -0,0 +1,25 @@
function str=disp(G)
% display - display an FOTF. This function will be called automatically
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G); key=0; if nargout==1, key=1; end
for i=1:m, if m>1, disp([' From input ' int2str(i) ' to output...']), end
for j=1:n, if n>1, disp([' ' int2str(j) ':']), end
str=fotfdisp(G(j,i),key); if nargout==0, disp(' '); end
end, end, end
% display a SISO FOTF object
function str=fotfdisp(G,key)
strN=disp(G.num); str=strN;
strD=disp(G.den); nn=length(strN);
if nn==1 && strN=='0', if key==0, disp(strN), end
else, nd=length(strD); nm=max([nn,nd]);
if key==0, disp([char(' '*ones(1,floor((nm-nn)/2))) strN]), end
ss=[]; T=G.ioDelay; if T>0, ss=['exp(-' num2str(T) '*s)']; end
if T>0, str=['(' str ')*' ss '/(' strD ')'];
else, str=['(' str ')/(' strD ')']; end
str=strrep(strrep(str,'{',''),'}','');
if key==0, disp([char('-'*ones(1,nm)), ss]);
disp([char(' '*ones(1,floor((nm-nd)/2))) strD])
end, end, end

View File

@ -0,0 +1,10 @@
function a=double(G)
%double - convert FOTF to double, if possible
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 May, 2022
if G.num.na==0 && G.den.na==0
a=G.num.a./G.den.a;
else, error('G contains dynamic terms, cannot be converted into double')
end
end

13
FOTF Toolbox/@fotf/eig.m Normal file
View File

@ -0,0 +1,13 @@
function p=eig(G)
% eig - finding all the pseudo poles of an FOTF object
%
% p=eig(G)
%
% G - the FOTF object
% p - all the pseudo-poles of G
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
p=eig(foss(G));
end

19
FOTF Toolbox/@fotf/eq.m Normal file
View File

@ -0,0 +1,19 @@
function key=eq(G1,G2)
% eq - test whether two FOTF objects are equal or not
%
% key=G1==G2
%
% G1, G2 - the two FOTF objects
% key = 1 for equal, otherwise key = 0
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n1,m1]=size(G1); [n2,m2]=size(G2);
if n1~=n2 || m1~=m2, key=0;
else
G=G1-G2; [n,m]=size(G); key=0; kk=0;
for i=1:n, for j=1:m, kk=kk+(G(i,j).num==0);
end, end, end
key=(kk==n1*m1);
end

13
FOTF Toolbox/@fotf/exp.m Normal file
View File

@ -0,0 +1,13 @@
function G=exp(del)
% exp - express delay term exp(-tau*s)
%only works for SISO FOTF model
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 May, 2022
try
T=double(del/fotf('s'));
if T>0, error('Delay must be negative'), else, T=-T; end
G=fotf(1); G.ioDelay=T;
catch, error('Error in extracting delay constant');
end
end

View File

@ -0,0 +1,23 @@
function G=feedback(F,H)
% feedback - find the overall model of two FOTF objects in feedback connection
%
% G=feedback(G1,G2)
%
% G1, G2 - the FOTF objects in the forward and backward paths
% G - the overall model of the closed-loop system
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
F=fotf(F); H=fotf(H); [n1,m1]=size(F); [n2,m2]=size(H);
if n1*m1==1 && n2*m2==1
if F.ioDelay==H.ioDelay
G=fotf(F.den*H.den+F.num*H.num,F.num*H.den);
G=simplify(G); G.ioDelay=F.ioDelay;
else, error('delay in incompatible'), end
elseif n1==m1 && n1==n2 && n2==m2
if maxdelay(F)==0 && maxdelay(H)==0
G=inv(fotf(eye(size(F*H)))+F*H)*F; G=simplify(G);
else, error('cannot handle blocks with delays'); end
else, error('not equal sized square matrices'), end
end

View File

@ -0,0 +1,23 @@
function G1=foss_a(G)
% foss_a - convert an FOTF object into an extended FOSS object
%
% G1=foss_a(G)
%
% G - the FOTF object
% G1 - the equivalent extended FOSS object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G); n0=[];
for i=1:n, for j=1:m, g=G(i,j); n0=[n0, g.nn g.nd]; end, end
n0=unique(n0); n1=n0(end:-1:1);
for i=1:n, for j=1:m, g=G(i,j);
num=[]; den=[]; nn=g.nn; nd=g.nd; b=g.num; a=g.den;
for k=1:length(nn), t=find(nn(k)==n1); num(t)=b(k); end
for k=1:length(nd), t=find(nd(k)==n1); den(t)=a(k); end
Gt(i,j)=tf(num,den); T(i,j)=g.ioDelay;
end, end
Gf=ss(Gt); E=Gf.e; [a,b,c,d]=dssdata(Gf);
alpha=-diff(n1); G1=foss(a,b,c,d,alpha,T,E);
end

30
FOTF Toolbox/@fotf/fotf.m Normal file
View File

@ -0,0 +1,30 @@
% foss - class constructor for an FOTF class
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
%Note that, the low-level support of FOTF object is changed to
%ppoly object, pseudo-polynomials
classdef fotf
properties
num, den, ioDelay
end
methods
function G=fotf(a,na,b,nb,T)
if isa(a,'fotf'), G=a;
elseif strcmp(class(a),'sym'), G=sym2fotf(a);
elseif isa(a,'foss'), G=foss2fotf(a);
elseif nargin==1 && (isa(a,'tf') || isa(a,'ss') || isa(a,'double'))
a=tf(a); [n1,m1]=size(a); G=[]; D=a.ioDelay;
for i=1:n1, g=[]; for j=1:m1
[n,d]=tfdata(tf(a(i,j)),'v'); nn=length(n)-1:-1:0;
nd=length(d)-1:-1:0; g=[g fotf(d,nd,n,nn,D(i,j))];
end, G=[G; g]; end
elseif nargin==1 && a=='s', G=fotf(1,0,1,1,0);
elseif isa(a,'ppoly'), G.num=na; G.den=a; G.ioDelay=0;
else, ii=find(abs(a)<eps); a(ii)=[]; na(ii)=[];
ii=find(abs(b)<eps); b(ii)=[]; nb(ii)=[];
if isempty(b), b=0; nb=0; end
if nargin==4, T=0; end
num=ppoly(b,nb); den=ppoly(a,na); G.num=num; G.den=den; G.ioDelay=T;
end, end, end, end

View File

@ -0,0 +1,25 @@
function [G1,alpha]=fotf2cotf(G)
% fotf2cotf - convert an FOTF object into a commensurate-order one
%
% [G1,alpha]=fotf2cotf(G)
%
% G - an FOTF object
% G1 - an equivalent commensurate-order FOTF
% alpha - the base order
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G); alpha=base_order(G);
if alpha==0
for i=1:n, for j=1:m
g=G(i,j); a=g.den.a; b=g.num.a; D(i,j)=b(1)/a(1); T(i,j)=g.ioDelay;
end, end, G1=tf(D);
else
for i=1:n, for j=1:m, g=G(i,j); a=[]; b=[];
n0=round(g.den.na/alpha); a(n0+1)=g.den.a; a=a(end:-1:1);
m0=round(g.num.na/alpha); b(m0+1)=g.num.a; b=b(end:-1:1);
g1=tf(b,a); G1(i,j)=g1; T(i,j)=g.ioDelay;
end, end, end
G1.ioDelay=T;
end

View File

@ -0,0 +1,16 @@
function G1=fotf2foss(G)
% fotf2foss - convert an FOTF object to FOSS one
%
% G1=fotf2foss(G)
%
% G - an FOTF object
% G1 - an equivalent FOSS object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G);
[G2,alpha]=fotf2cotf(G); G2=minreal(G2); G2=ss(G2);
for i=1:n, for j=1:m, g=G(i,j); T(i,j)=g.ioDelay; end, end
G1=foss(G2.a,G2.b,G2.c,G2.d,alpha,T,G2.E);
end

View File

@ -0,0 +1,19 @@
function [a,na,b,nb,L]=fotfdata(G)
% fotfdata - extract data from an FOTF object
%
% [a,na,b,nb,L]=fotfdata(G)
%
% G - an FOTF object
% [a,na,b,nb] - the coefficients and orders of denominator and numerator
% L - the delay constant
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G);
if n*m==1, b=G.num.a; a=G.den.a; nb=G.num.na; na=G.den.na; L=G.ioDelay;
else
for i=1:n, for j=1:m
[a0,na0,b0,nb0,L0]=fotfdata(G(i,j));
a{i,j}=a0; b{i,j}=b0; na{i,j}=na0; nb{i,j}=nb0; L(i,j)=L0;
end, end, end, end

View File

@ -0,0 +1,23 @@
function H=freqresp(s,G1)
% freqresp - low-level function to evaluate the frequency response of
% an FOTF object
%
% H=freqresp(s,G)
%
% s - the frequency vector or a vector for s
% G - the FOTF object
% H - frequency response, i.e., G(s) vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G1);
for i=1:n, for j=1:m
[a,na,b,nb,L]=fotfdata(G1(i,j));
for k=1:length(s)
P=b*(s(k).^nb.'); Q=a*(s(k).^na.'); H1(k)=P/Q;
end
if L>0, H1=H1.*exp(-L*s); end, H(i,j,:)=H1;
end, end
if n*m==1, H=H(:).'; end
end

View File

@ -0,0 +1,36 @@
function Ga=high_order(G0,filter,wb,wh,N,key)
% high_order - approximate an FOTF object with high-order TFs
%
% Ga=high_order(G0,filter,wb,wh,N)
%
% G0 - an FOTF object
% filter - can be 'ousta_fod', 'new_fod' and 'matsuda_fod'
% wb, wh, N - the interested frequency interval and order of the filter
% Ga - an equivalent TF object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
arguments
G0, filter='ousta_fod', wb(1,1){mustBeNumeric}=1e-3
wh(1,1) {mustBeNumeric, mustBeGreaterThan(wh,wb)}=1e3
N(1,1) {mustBeInteger, mustBePositive}=5, key=0
end
[n,m]=size(G0); F=filter;
for i=1:n, for j=1:m
if G0(i,j)==fotf(0), Ga(i,j)=tf(0);
else, G=simplify(G0(i,j)); [a,na,b,nb]=fotfdata(G);
G1=pseudo_poly(b,nb,F,wb,wh,N,key)/pseudo_poly(a,na,F,wb,wh,N,key);
Ga(i,j)=minreal(G1);
end, end, end, end
%
function p=pseudo_poly(a,na,filter,wb,wh,N,key)
p=0; s=tf('s');
for i=1:length(a), na0=na(i); n1=floor(na0); gam=na0-n1;
if key==1
g1=eval([filter '(gam,N,wb,wh)']); p=p+a(i)*g1;
else
if gam~=0, g1=eval([filter '(gam,N,wb,wh)']);
else, g1=1; end
p=p+a(i)*s^n1*g1;
end, end, end

View File

@ -0,0 +1,15 @@
function y=impulse(G,t)
% impulse - impulse response evaluation of an FOTF object
%
% impulse(G,t)
%
% G - an FOTF object
% t - the time vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
G1=G*fotf('s');
if nargout==0, step(G1,t,1); title('Impulse Response')
else, y=step(G1,t,1); end
end

28
FOTF Toolbox/@fotf/inv.m Normal file
View File

@ -0,0 +1,28 @@
function G1=inv(G)
% inv - inverse of a multivariable FOTF system
%
% G1=inv(G)
%
% G, G1 - an FOTF object and its inverse system
% not recommended for MIMO FOTFs, use fotf2sym and work the
% model G under symbolic framework
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G);
if n*m==1
if G.ioDelay>0, error('Delay terms are not allowed');
else, G1=fotf(G.num,G.den); end
elseif n~=m
error('Error: non-square matrix, not invertible')
else, G1=fotfinv(G); end
end
function G1=fotfinv(G)
[n,~]=size(G); A1=G; E0=fotf(eye(n)); A3=E0;
for i=1:n, ij=1:n; ij=ij(ij~=i);
E=fotf(eye(n)); a0=inv(A1(i,i));
for k=ij, E(k,i)=-A1(k,i)*a0; end
E0=E*E0; A1=E*A1; A3(i,i)=a0;
end, G1=A3*E0;
end

View File

@ -0,0 +1,7 @@
function key=isfotf(p)
%isfotf check input is an FOTF object or not
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
key=isa(p,'fotf');
end

View File

@ -0,0 +1,34 @@
function [K,alpha0,apol,p]=isstable(G,a0)
% isstable - check whether an FOTF object is stable or not
%
% [K,alpha,apol]=isstable(G)
%
% G - an FOTF object
% K- identifier to indicate the stability of G, returns 0, and 1
% alpha - the common order
% apol - all the pseudo poles of the system
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n0,m0]=size(G); K=1; if nargin==1, a0=0.001; end
for i=1:n0, for j=1:m0
g=G(i,j); a=g.den.na; a1=fix(a/a0);
if length(a1)==1 && a1==0
else
[g1,alpha]=fotf2cotf(g); c=g1.den{1};
alpha0(i,j)=alpha; p0=roots(c); kk=[];
for k=1:length(p0)
a=g.den.a; na=g.den.na; pa=p0(k)^(1/alpha);
if norm(a*[pa.^na'])<1e-6, kk=[kk,k]; end
end
p=p0(kk); subplot(n0,m0,(i-1)*m0+j),
plot(real(p),imag(p),'x',0,0), xm=xlim;
if alpha<1, xm(1)=0; else, xm(2)=0; end
apol=min(abs(angle(p))); K=K*(apol>alpha*pi/2);
a1=tan(alpha*pi/2)*xm; a2=tan(alpha*pi)*xm;
line(xm,a1), line(xm,-a1), line(xm,a2), line(xm,-a2)
xlabel('Real Axis'), ylabel('Imaginary Axis')
end, end, end
title('Pole Map')
end

View File

@ -0,0 +1,14 @@
function key=iszero(g)
% iszero - check whether a SISO FOTF object is zero or not
%
% key=iszero(G)
%
% G - a SISO FOTF object
% key - identifier, if G is zero, then key = 1.
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
key=0; [~,~,b,nb]=fotfdata(g);
if isempty(b) || (length(nb)==1 && abs(b(1))<eps), key=1; end
end

View File

@ -0,0 +1,26 @@
function str=latex(G)
% latex - convert an FOTF object into its LaTeX string
%
% str=latex(G)
%
% G - an FOTF object
% str - LaTeX string
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G);
if n*m==1
str=['\frac{' latex(G.num) '}{' latex(G.den) '}']; T= G.ioDelay;
if T~=0, ss=[]; if T~=1, ss=num2str(T); end
str=[str '\mathrm{e}^{-' ss 's}'];
end
else
str='\begin{bmatrix}';
for i=1:n
for j=1:m
str=[str, '\displaystyle ' latex(G(i,j)) '&'];
end, str=[str(1:end-1) '\cr'];
end, str=[str(1:end-3),'\end{bmatrix}'];
end
end

26
FOTF Toolbox/@fotf/lsim.m Normal file
View File

@ -0,0 +1,26 @@
function y=lsim(G,u,t)
% lsim - simulation of an FOTFS object driven by given inputs
%
% lsim(G,u,t)
%
% G - an FOTF object
% u, t- input samples and time vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G); t0=t(1); t1=t(end); [nu,mu]=size(u);
if nu==m && mu==length(t), u=u.'; end
if nargout==0, lsim(tf(zeros(n,m)),'w',zeros(size(u)),t); end
for i=1:n, y1=0;
for j=1:m, g=G(i,j); uu=u(:,j);
y2=fode_sol9(g.den.a,g.den.na,g.num.a,g.num.na,uu,t,3);
ii=find(t>=g.ioDelay); lz=zeros(1,ii(1)-1);
y2=[lz, y2(1:end-length(lz))]; y(:,i)=y1+y2;
end, end
if nargout==0, khold=ishold; hold on
h=get(gcf,'child'); h0=h(end:-1:2);
for i=1:n, axes(h0(i));
plot(t,y(:,i),t,u,'--'), xlim([t0,t1])
end, if khold==0, hold off, end, end
end

View File

@ -0,0 +1,14 @@
function [Gm,Pm,Wcg,Wcp]=margin(G)
% margin - gain and phase margins of an FOTF object
%
% [Gm,Pm,Wcg,Wcp]=margin(G)
%
% G - an FOTF object
% Gm, Wcg - gain margin in dBs and the corresponding frequency
% Pm, Wcp - phase margin in degrees and the crossover frequency
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
H=bode(G,logspace(-4,4,1000)); [Gm,Pm,Wcg,Wcp]=margin(H);
end

View File

@ -0,0 +1,14 @@
function T=maxdelay(G)
% maxdelay - extract the maximum delay from an FOTF object
%
% T=maxdelay(G)
%
% G - an FOTF object
% T - the maximum delay of the system
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
T=0; [n,m]=size(G);
for i=1:n, for j=1:m, T=max(T,G(i,j).ioDelay); end, end
end

15
FOTF Toolbox/@fotf/mfrd.m Normal file
View File

@ -0,0 +1,15 @@
function H1=mfrd(G,w)
% mfrd - evaluation of frequency responses of an FOTF object
%
% H=mfrd(G,w)
%
% G - an FOTF object
% w - frequency vector
% H - frequency response of G in MFD format
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
H=bode(G,w); h=H.ResponseData; H1=[];
for i=1:length(w); H1=[H1; h(:,:,i)]; end
end

View File

@ -0,0 +1,10 @@
function G=minus(G1,G2)
% minus - minus operation of two FOTF objects
%
% G=G1-G2
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
G=G1+(-G2);
end

View File

@ -0,0 +1,10 @@
function G=mldivide(G1,G2)
% mldivide - left division of two FOTF objects
%
% G=G1\G2
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
G1=fotf(G1); G2=fotf(G2);
if maxdelay(G)==0 && maxdelay(G2)==0, G=inv(G1)*G2;
else, warning('block with positive delay'); end

View File

@ -0,0 +1,30 @@
function G1=mpower(G,n)
% mpower - power of an FOTF object
%
% G1=G^n
%
% G - an FOTF object
% n - power. If G is s or constant, n can be any real number,
% If G is an FOSS, n should be integers
% G1 - returns G^n, and an FOSS object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n1,m1]=size(G);
if n==fix(n)
if n1==m1
if n>=0, G1=fotf(eye(n1)); for i=1:n, G1=G1*G; end
else, G1=inv(G)^(-n); end
elseif n==1, G1=G;
else, error('G must be a square matrix');
end
elseif n1==1 && m1==1
if length(G.num)==1 && length(G.den)==1
[a,na,b,nb,L]=fotfdata(G);
G1=fotf(a^n,na*n,b^n,nb*n,L*n);
else, error('mpower: power must be an integer.');
end
else, error('mpower: power must be an integer.');
end
end

View File

@ -0,0 +1,12 @@
function G=mrdivide(G1,G2)
% mldivide - right division of two FOTF objects
%
% G=G1/G2
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
G1=fotf(G1); G2=fotf(G2);
if maxdelay(G1)==0 && maxdelay(G2)==0, G=G1*inv(G2);
else, error('block with positive delay'); end
end

View File

@ -0,0 +1,30 @@
function G=mtimes(G1,G2)
% mpower - product of two FOTF objects, series connection
%
% G=G1*G2
%
% G1, G2 - FOTF objects
% G - returns the product of the two FOTF objects
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
G1=fotf(G1); G2=fotf(G2);
if numel(G1)==1 && numel(G2)==1, G=sisofotftimes(G1,G2);
else, [n1,m1]=size(G1); [n2,m2]=size(G2);
if m1==n2, G=fotf(zeros(n1,m2));
for i=1:n1, for j=1:m2
for k=1:m1, G(i,j)=G(i,j)+sisofotftimes(G1(i,k),G2(k,j));
end, end, end
elseif n1*m1==1, G=fotf(zeros(n2,m2)); % if G1 is scalar
for i=1:n2, for j=1:m2, G(i,j)=G1*G2(i,j); end, end
elseif n2*m2==1, G=fotf(zeros(n1,m1)); % if G2 is scalar
for i=1:n1, for j=1:m1, G(i,j)=G2*G1(i,j); end, end
else
error('The two matrices are incompatible for multiplication')
end, end, end
% product of two SISO FOTF objects
function G=sisofotftimes(G1,G2)
G=fotf(G1.den*G2.den,G1.num*G2.num); G=simplify(G);
G.ioDelay=G1.ioDelay+G2.ioDelay;
end

View File

@ -0,0 +1,14 @@
function nichols(G,w)
% nichols - draw the Nichols chart of an FOTF object
%
% nichols(G,w)
%
% G - an FOTF object
% w - the frequency vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
arguments, G, w=logspace(-4,4); end
H=bode(G,w); nichols(H);
end

26
FOTF Toolbox/@fotf/norm.m Normal file
View File

@ -0,0 +1,26 @@
function n=norm(G,eps0)
% norm -= norms of an FOTF object
%
% norm(G), norm(G,inf)
%
% G - an FOTF object
% The 2-norm and infinity-norm of G can be evaluated, respectively
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G); if nargin==1, eps0=1e-6; end
for i=1:n, for j=1:m, A(i,j)=snorm(G(i,j),eps0); end, end
n=norm(A);
end
% norm of a SISO FOTF object
function n=snorm(G,eps0)
j=sqrt(-1);
if nargin==2 && ~isfinite(eps0) % H infinity norm, find the maximum value
f=@(w)-abs(freqresp(j*w,G));
w=fminsearch(f,0); n=abs(freqresp(j*w,G));
else % H2 norm, numerical integration
f=@(s)freqresp(s,G).*freqresp(-s,G);
n=integral(f,-inf,inf)/(2*pi*j);
end
end

View File

@ -0,0 +1,12 @@
function n=numel(G)
% numel - the number of FOTF objects in G
%
% n=numel(G)
%
% G - FOTF object
% n - returns the number of FOTF objects in G
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
[n,m]=size(G); n=n*m;
end

View File

@ -0,0 +1,14 @@
function nyquist(G,w)
% nyquist - draw the Nyquist plot of an FOTF object
%
% nyquist(G,w)
%
% G - an FOTF object
% w - the frequency vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
arguments, G, w=logspace(-4,4); end
H=bode(G,w); nyquist(H);
end

30
FOTF Toolbox/@fotf/plus.m Normal file
View File

@ -0,0 +1,30 @@
function G=plus(G1,G2)
% plus - evaluate the sum of two FOTF objects, parallel connection
%
% G=G1+G2
%
% G1, G2 - the two FOTF objects in parallel connection
% G - the sum of G1 and G2
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
G1=fotf(G1); G2=fotf(G2);
[n1,m1]=size(G1); [n2,m2]=size(G2);
if n1==n2 && m1==m2, G=G1;
for i=1:n1, for j=1:m1
G(i,j)=sisofotfplus(G1(i,j),G2(i,j));
end, end
elseif n1*m1==1, G1=G1*fotf(ones(n2,m2)); G=G1+G2;
elseif n2*m2==1, G2=G2*fotf(ones(n1,m1)); G=G1+G2;
else
error('Error: the sizes of the two FOTF matrices mismatch');
end
% sum of two SISO FOTF objects
function G=sisofotfplus(G1,G2)
if G1.ioDelay==G2.ioDelay
G=fotf(G1.den*G2.den,G1.num*G2.den+G2.num*G1.den);
G=simplify(G); G.ioDelay=G1.ioDelay;
else, error('Error: cannot handle different delays');
end, end
end

View File

@ -0,0 +1,14 @@
function [alpha,r,p,K]=residue(G)
% residue - partial fraction expansion of a SISO FOTF object
%
% [alpha,r,p,K]=residue(G)
%
% G - a SISO commensurate-order FOTF object
% alpha - base order
% r, p, K - the definitions are the same as the conventional residue function
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[H,alpha]=fotf2cotf(G); [r,p,K]=residue(H.num{1},H.den{1});
end

View File

@ -0,0 +1,19 @@
function rlocus(G)
% rlocus - draw the root locus of a SISO FOTF object
%
% rlocus(G)
%
% G - a SISO FOTF object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
if numel(G)==1
[G1,alpha]=fotf2cotf(G); rlocus(G1), xm=xlim;
if alpha<1, xm(1)=0; else, xm(2)=0; end
line(xm,tan(alpha*pi/2)*xm), line(xm,-tan(alpha*pi/2)*xm)
line(xm,tan(alpha*pi)*xm), line(xm,-tan(alpha*pi)*xm)
else
error('Root locus only applies to SISO systems');
end
end

View File

@ -0,0 +1,20 @@
function sigma(G,w)
% sigma - singular value plots of a MIMO FOTF object
%
% sigma(G,w)
%
% G - a MIMO FOTF object
% w - a frequency vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
if nargin==1, w=logspace(-4,4); end
H=bode(G,w); subplot(111); h1=[]; H1=H;
h=H.ResponseData; [n,m,k]=size(h);
for i=1:k, h1=[h1, svd(h(:,:,i))]; end
for i=1:min([n,m])
h2(1,1,:)=h1(i,:).'; H1.ResponseData=h2; bodemag(H1), hold on
end
hold off
end

View File

@ -0,0 +1,20 @@
function G=simplify(G,eps1)
% simplify - simplification of an FOTF object
%
% G=simplify(G1,eps1)
%
% G1 - a FOTF object
% eps1 - error tolerance
% G - simplified FOTF object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G); if nargin==1, eps1=eps; end
for i=1:n, for j=1:m
g=G(i,j); num=g.num.a; den=g.den.a; nn=g.num.na; nd=g.den.na;
i1=abs(num)>eps1; i2=abs(den)>eps1; num=num(i1); den=den(i2);
nn=nn(i1); nd=nd(i2); n0=min(nn); d0=min(nd);
na=min(n0,d0); if isempty(na), na=0; end
G(i,j)=fotf(den,nd-na,num,nn-na,g.ioDelay);
end, end, end

33
FOTF Toolbox/@fotf/step.m Normal file
View File

@ -0,0 +1,33 @@
function Y=step(G,t,key)
% step - simulation of an FOTF object driven by step inputs
%
% step(G,t)
%
% G - an FOTF object
% t- the time vector
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G); M=tf(zeros(n,m));
if nargin==1, t=(0:0.2:10)'; elseif length(t)==1, t=0:t/100:t; end
if nargout==0, t0=t(1); t1=t(end);
if nargin<=2, step(M,'w'); else, impulse(M,'w');
end, end
for i=1:n, for j=1:m
g=G(i,j); y1=g_step(g,t); y(i,j,:)=y1';
end, end
if nargout==0, khold=ishold; hold on
h=get(gcf,'child'); h0=h(end:-1:2);
for i=1:n, for j=1:m, axes(h0((i-1)*n+j));
yy=y(i,j,:); plot(t,yy(:)), xlim([t0,t1])
end, end
if khold==0, hold off, end
elseif n*m==1, Y=y1; else, Y=y; end
end
%subfunction to evaluate step response of SISO model
function y=g_step(g,t,key)
u=ones(size(t));
[a,na,b,nb,T]=fotfdata(g); y1=fode_sol(a,na,b,nb,u,t);
ii=find(t>=T); lz=zeros(1,ii(1)-1); y=[lz, y1(1:end-length(lz))];
end

View File

@ -0,0 +1,14 @@
function G=uminus(G)
% uminus - unary minus of an FOTFS object
%
% G1=-G
%
% G - an FOT object
% G1- the unary minus of G, i.e., -G
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
[n,m]=size(G);
for i=1:n, for j=1:m, G(i,j).num=-G(i,j).num; end, end
end

View File

@ -0,0 +1,18 @@
function p=collect(p)
% collect - collect like terms in ppoly objects
%
% p=collect(p)
%
% p - a ppoly object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
a=p.a; na=p.na;
[na,ii]=sort(na,'descend'); a=a(ii); ax=diff(na); key=1;
for i=1:length(ax)
if abs(ax(i))<=1e-10
a(key)=a(key)+a(key+1); a(key+1)=[]; na(key+1)=[];
else, key=key+1; end
end
ii=find(abs(a)~=0); a=a(ii); na=na(ii); p=ppoly(a,na);
end

View File

@ -0,0 +1,23 @@
function str=disp(p)
% collect - collect like terms in ppoly objects
%
% p=collect(p)
%
% p - a ppoly object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
np=p.na; p=p.a;
if isempty(np), p=0; np=0; end
P=''; [np,ii]=sort(np,'descend'); p=p(ii);
for i=1:length(p)
P=[P,'+',num2str(p(i)),'*s^{',num2str(np(i)),'}'];
end
P=P(2:end); P=strrep(P,'s^{0}',''); P=strrep(P,'+-','-');
P=strrep(P,'^{1}',''); P=strrep(P,'+1*s','+s');
P=strrep(P,'*+','+'); P=strrep(P,'*-','-');
P=strrep(P,'-1*s','-s'); nP=length(P);
if nP>=3 && isequal(P(1:3),'1*s'), P=P(3:end); end
if P(end)=='*', P(end)=''; end
if nargout==0, disp(P), else, str=P; end
end

12
FOTF Toolbox/@ppoly/eq.m Normal file
View File

@ -0,0 +1,12 @@
function key=eq(p1,p2)
% eq - test whether two PPOLY objects are equal or not
%
% key=p1==p2
%
% p1, p2 - the two PPOLY objects
% key = 1 for equal, otherwise key = 0
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
g=collect(p1-p2); key=isempty(g.a);
end

View File

@ -0,0 +1,13 @@
function H=freqw(p,w)
% freqw - get frequency response of ppoly object
%
% H=freqw(p,w)
%
% p - a ppoly object
% w - frequency vector
% H - frequency response data
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
for i=1:length(w), H(i)=p.a(:).'*(1i*w(i)).^p.na(:); end
end

19
FOTF Toolbox/@ppoly/get.m Normal file
View File

@ -0,0 +1,19 @@
function p1=get(varargin)
% get - get fields from ppoly object
%
% a=get(p,'a') or na=get(p,'na')
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
p=varargin{1};
if nargin==1
s=sprintf('%f ,',p.a); disp([' a: [' s(1:end-1) ']'])
s=sprintf('%f ,',p.na); disp([' na: [' s(1:end-1) ']'])
elseif nargin==2, key=varargin{2};
switch key
case 'a', p1=p.a; case 'na', p1=p.na;
otherwise, error('Wrong field name used'),
end
else, error('Wrong number of input argumants');
end
end

View File

@ -0,0 +1,11 @@
function key=isppoly(p)
% isppoly - check whether input is an ppoly object
%
% key=isppoly(p)
%
% key returns 1 or 0
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
key=strcmp(class(p),'ppoly');
end

View File

@ -0,0 +1,12 @@
function strA=latex(p)
% latex - convert ppoly object into LaTeX string
%
% str=latex(p)
%
% p - a ppoly object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
str=disp(p); str=strrep(str,'*s','s');
if nargout==0, disp(str), else, strA=str; end
end

View File

@ -0,0 +1,11 @@
function p=minus(p1,p2)
% minus - find the differences in two ppoly objects
%
% p=p1-p2
%
% p, p1, p2 - ppoly objects
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
p=p1+(-p2);
end

View File

@ -0,0 +1,15 @@
function p1=mpower(p,n)
% mpower - power of a ppoly object
%
% p1=p^n
%
% p - a ppoly object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
if length(p.a)==1, p1=ppoly(p.a^n,p.na*n);
elseif n==floor(n)
if n<0, p.na=-p.na; n=-n; end
p1=ppoly(1); for i=1:n, p1=p1*p; end
else, error('n must be an integer'), end
end

View File

@ -0,0 +1,11 @@
function p=mrdivide(p1,p2)
% mrdivide - right divide ppoly objects
%
% p=p1/p2
%
% p, p1, p2 - ppoly objects
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
p1=collect(ppoly(p1)); p2=collect(ppoly(p2)); p=fotf(p2,p1);
end

View File

@ -0,0 +1,12 @@
function p=mtimes(p1,p2)
% mtimes - product of two ppoly objects
%
% p=p1*p2
%
% p, p1, p2 - ppoly object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
p1=ppoly(p1); p2=ppoly(p2); a=kron(p1.a,p2.a);
na=kronsum(p1.na,p2.na); p=collect(ppoly(a,na));
end

View File

@ -0,0 +1,12 @@
function p=plus(p1,p2)
% plus - sum of twp ppoly objects
%
% p=p1+p2
%
% p, p1, p2 - ppoly objects
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
p1=ppoly(p1); p2=ppoly(p2);
a=[p1.a,p2.a]; na=[p1.na,p2.na]; p=collect(ppoly(a,na));
end

View File

@ -0,0 +1,15 @@
% ppoly - class definition of a ppoly object
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
classdef ppoly
properties, a, na, end
methods
function p=ppoly(a,na)
if nargin==1
if isa(a,'double'), p=ppoly(a,length(a)-1:-1:0);
elseif isa(a,'ppoly'), p=a;
elseif a=='s', p=ppoly(1,1); end
elseif length(a)==length(na), p.a=a; p.na=na;
else, error('Error: miss matching in a and na'); end
end, end, end

View File

@ -0,0 +1,11 @@
function p1=uminus(p)
% uminus - find -p
%
% p1=-p
%
% p, p1 - ppoly objects
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 18 May, 2022
p1=ppoly(-p.a,p.na);
end

197
FOTF Toolbox/Contents.m Normal file
View File

@ -0,0 +1,197 @@
%FOTF Toolbox - A MATLAB Toolbox for the modeling, analysis and design of fractional-order systems
%
% (c) Professor Dingy\"u Xue, Northeastern University, Shenyang, China
% Email: xuedingyu@mail.neu.edu.cn
% Date of last modification, 23 December, 2016
%
% This newly modified toolbox is written for the monograph,
%
% @BOOK{bkXueDFOCS,
% Author = {Xue Dingy\"u},
% Address = {Berlin},
% Publisher = {de Gruyter Press},
% Title = {Fractional-order Control Systems - Fundamentals and Numerical Implementations},
% Year = {2017}
% }
%
% Multivariable fractional-order systems are fully supported in the classes FOTF and FOSS
% and low-level numerical algorithms are replaced by $O(h^p)$ precision ones.
% For details in theory and programming, please refer to the monograph.
% (I) Special functions and fundamentals in numerical computation
% beta_c - beta function evaluation for complex arguments
% common_order - compute the common order
% fence_shadow - draw the shawdows on the walls
% fmincon_global - a global constrained optimisation problem solver
% funmsym - evaluate symbolic matrix functions
% gamma_c - Gamma function evaluation for complex arguments
% kronsum - compute Kronecker sum
% mittag_leffler - symbolic evaluation of Mittag-Leffler functions
% ml_func - numerical evaluation of Mittag-Leffler functions and derivatives
% more_sols - find possible all solutions of nonlinear matrix equations
% more_vpasols - symbolic version of more_sols, high precision solutions
% new_inv - simple matrix inverse function, not recommended in applications
%
%(II) Numerical evaluations of fractional-order derivatives and integrals
% caputo - computation of Caputo derivatives with interpolation, not recommended
% caputo9 - evaluation of Caputo derivatives with $O(h^p)$, recommended
% genfunc - computation of generating function coefficients symbolically
% get_vecw - computation of $O(h^p)$ weighting coefficients
% glfdiff0 - evaluation of GL derivatives, not recommended
% glfdiff - standard evaluation of GL derivatives, with $O(h)$
% glfdiff2 - evaluation of $O(h^p)$ GL derivatives, not recommended
% glfdiff9 - evaluation of $O(h^p)$ GL derivatives, recommended
% glfdiff_fft - evaluation of $O(h^p)$ GL derivatives with FFT, not recommended
% glfdiff_mat - matrix version of glfdiff, not recommended for large samples
% glfdiff_mem - GL derivative evaluation with short-memory effect
% rlfdiff evaluation of RL derivatives, not recommended, use glfdiff9 instead
%
%(III) Numerical evaluations of linear fractional-order differential equations
% caputo_ics - equivalent initial condition reconstruction, called by fode_caputo9
% fode_caputo0 - simple Caputo FODE solver with nonzero initial conditions
% fode_caputo9 - $O(h^p)$ solution of Caputo equations with nonzero ICs
% fode_sol - closed-form solution of FODE with zero initial conditions
% fode_solm - matrix version of fode_sol, not recommended for large samples
% fode_sol9 - $O(h^p)$ version of fode_sol
% ml_step3 - numerical solution of step response of 3-term models
%
%(IV) Numerical evaluations of nonlinear fractional-order differential equations
% INVLAP_new - closed-loop response evaluation with inverse Laplace transform
% nlfode_mat - matrix-based solutions of implicit nonlinear FODEs
% nlfode_vec - nonlinear fractional-order extended state space equation solver
% nlfode_vec1 - a different version of nlfode_vec, not recommended
% nlfec - $O(h^p)$ corrector solution of nonlinear multi-term FODEs
% nlfep - $O(h^p)$ predictor solution of nonlinear multi-term fractional-order ODEs
% pepc_nlfode - numerical solutions of single-term nonlinear FODE with PCPE algorithm
%
%(V) Filter design for fractional-order derivatives and systems
% carlson_fod - design of a Carlson filter
% charef_fod - design of a Charef filter
% charef_opt - design of an optimal Charef filter
% cont_frac0 - continued-fraction interface to irrational functions
% matsuda_fod - design of Matsuda-Fujii filter
% new_fod - design of a modified Oustaloup filter
% opt_app - optimal IO transfer approximation of high-order models
% ousta_fod - design of a standard Oustaloup filter
%
%(VI) FOTF object design and overload functions
% base_order - find the base order from an FOTF object
% bode - Bode diagram analysis
% diag - diagonal FOTF matrix creation and extraction
% display - overload function to display a MIMO FOTF object
% eig - find all the poles, including extraneous roots
% eq - checks whether two FOTF blocks equal or not
% feedback - overload the feedback function for two FOTF blocks
% foss_a - convert an FOTF to an extended FOSS object
% fotf - creation of an FOTF class
% fotf2cotf - convert an FOTF object into commensurate form
% fotf2foss - low-level conversion function of FOTF to FOSS object
% fotfdata - extract all the fields from an FOTF object
% freqresp - low-level frequency response function of an FOTF object
% high_order - high-order IO transfer function approximation of FOTF objects
% impulse - evaluation of impulse response of an FOTF object
% inv - inverse FOTF matrix
% isstable - check whether an FOTF object stable or not
% iszero - check whether an FOTF object is zero or not
% lsim - time response evaluation to arbitrary input signals
% margin - compute the gain and phase margins
% maxdelay - extract maximum delay from an FOTF object
% mfrd - frequency response evaluation
% minus - minus operation of two FOTF objects
% mldivide - left-division function
% mpower - power of an FOTF object
% mrdivide - right-division function
% mtimes - overload function of * operation of two blocks
% nichols - Nichols chart
% norm - H2 and Hinf evaluation
% nyquist - Nyquist plot
% plus - overload function of + operation of two blocks
% residue - partial fraction expansion
% rlocus - root locus analysis
% sigma - singular value plots
% simplify - simplification of an FOTF object
% step - step response
% uminus - unary minus of an FOTF object
%
%(VII) FOSS object design and overload functions
% bode - Bode diagram analysis
% coss_aug - FOSS augmentation
% ctrb - controllability test matrix creation
% display - overload function to display a MIMO FOSS object
% eig - compute the poles of a FOSS object
% eq - checks two FOSS blocks equal or not
% feedback - overload the feedback function for two FOSS blocks
% foss - FOSS class creation
% foss2fotf - low-level conversion from FOSS to FOTF object
% impulse - evaluation of impulse response of an FOSS object
% inv - inverse of an FOSS object
% isstable - check an FOSS object stable or not
% lsim - time response evaluation to arbitrary input signals
% margin - compute the gain and phase margins
% mfrd - frequency response evaluation
% minreal - minimum realisation of a FOSS object
% minus - minus operation of two FOTF objects
% mpower - power of an FOSS object
% mtimes - overload function of * operation of two blocks
% nichols - Nichols chart
% norm - H2 and Hinf evaluation
% nyquist - Nyquist plot
% obsv - construct observability test matrix
% order - find the orders of an FOSS object
% plus - overload function of + operation of two blocks
% rlocus - root locus analysis
% size - find the numbers of inputs, outputs and states
% ss_extract - extract integer-order state space object from FOSS
% step - step response
% uminus - unary minus of an FOSS object
%
%(VIII) Simulink models
% fotflib - Simulink blockset for FOTF Toolbox
% fotf2sl - multivariable FOTF to Simulink block convertor
% sfun_mls - S-function version of Mittag-Leffler function
% slblocks - default Simulink description file
% c9mvofuz - Simulink model for variable-order fuzzy PID control systems
% c9mvofuz2 - Simulink model for variable-order fuzzy PID systems with variable delays
% c10mpdm2 - Simulink model for multivariable PID control system
% c10mpopt - Simulink model for multivariable parameter optimisation control systems
% fPID_simu - Simulink model fractional-order PID controller for single-variable system
%
%(IX) Fractional-order and other controller design
% c9mfpid - fractional-order PID controller design with equation solution techniques
% c9mfpid_con - constraints in optimum FOPID design of FOPDT plants
% c9mfpid_con1 - constraints in optimum FOPID design of FOIPDT plants
% c9mfpid_con2 - constraints in optimum FOPID design of FO-FOPDT plants
% c9mfpid_opt - objective function in optimum FOPID design of FOPDT plants
% c9mfpid_opt1 - objective function in optimum FOPID design of FOIPDT plants
% c9mfpid_opt2 - objective function in optimum FOPID design of FO-FOPDT plants
% ffuz_param - S-function for parameter setting of fuzzy fractional-order PIDs
% fopid - construct a \fPID{} controller from parameters
% fpidfun - an example of objective function for optimum fractional-order PIDs
% fpidfuns - objective function for fractional-order PID controller design
% fpidtune - design of optimum fractional-order PID controllers
% gershgorin - draw Nyquist plots with Gershgorin bands
% get_fpidf - build string expression of the open-loop model
% mfd2frd - convert MFD data into FRD data
% optimfopid - GUI for optimum fractional-order PID design
% optimpid - GUI for optimum integer-order PID design
% pseuduag - pseudodiagonalisation of multivariable systems
%
%(X) Dedicated functions and models for the examples
% c2exnls - constraint function of an example
% c8mstep - Simulink model of a multivariable fractional-order system
% c8mfpid1 - Simulink model of a fractional-order PID control system
% c8mchaos - vectorised Simulink model for fractional-order Chua system
% c8mchaosd - data input file for c8mchaos
% c8mchua - MATLAB description of fractional-order Chua equations
% c8mchuasim - Simulink model for fractional-order Chua circuit
% c8mblk2,3,5 - three Simulink models of a linear fractional-order equation
% c8mcaputo - complicated Simulink model for nonlinear FODE
% c8mexp2 - simpler Simulink model for nonlinear Caputo equations
% c8mexp2m - MATLAB description of nonlinear Caputo equation
% c8mnlf1, c8mnlf2 - two different Simulink models of a nonlinear FODE
% c8mexp1x - MATLAB function for describing nonlinear Caputo equations
% c8nleq - MATLAB description of a nonlinear single-term Caputo equation
% c8mlinc1 - Simulink model of a linear fractional-order Caputo equation
% c9ef1-c9ef3 - criteria for optimum fractional-order PID controllers
% c9mplant - Simulink model used for optimpid design

49
FOTF Toolbox/INVLAP_new.m Normal file
View File

@ -0,0 +1,49 @@
function [t,y]=INVLAP_new(G,t0,tn,N,H,tx,ux)
% INVLAP_new - updated version of INVLAP for closed-loop system with any inputs
%
% [t,y]=INVLAP_new(G,t0,tn,N)
% [t,y]=INVLAP_new(G,t0,tn,N,H)
% [t,y]=INVLAP_new(G,t0,tn,N,H,u)
% [t,y]=INVLAP_new(G,t0,tn,N,H,tx,ux)
%
% G - the string representation of the open-loop model
% t0, tn, N - the time interval and number of points in the interval
% H - the string representation of the feedback model
% u - the function handle of the input signal
% tx, ux - the samples of time and input signal
% y, t - the output and time vectors
% Copyright (c) Dingyu Xue, Northeastern University, China
% Last modified 28 March, 2017
% Last modified 18 May, 2022
arguments
G, t0(1,1), tn(1,1) {mustBeGreaterThan(tn,t0)}
N(1,1){mustBePositiveInteger}=100;
H(1,1)=0; tx='1'; ux(1,:) {mustBeNumeric}=0;
end
G=add_dots(G); if ischar(H), H=add_dots(H); end
if ischar(tx), tx=add_dots(tx); end
a=6; ns=20; nd=19; t=linspace(t0,tn,N);
if t0==0, t=[1e-6 t(2:N)]; end
n=1:ns+1+nd; alfa=a+(n-1)*pi*1j; bet=-exp(a)*(-1).^n;
n=1:nd; bet(1)=bet(1)/2;
bdif=fliplr(cumsum(gamma(nd+1)./gamma(nd+2-n)./gamma(n)))./2^nd;
bet(ns+2:ns+1+nd)=bet(ns+2:ns+1+nd).*bdif;
if isnumeric(H), H=num2str(H); end
for i=1:N
tt=t(i); s=alfa/tt; bt=bet/tt; sG=eval(G); sH=eval(H);
if ischar(tx), sU=eval(tx);
else
if isnumeric(tx)
f=@(x)interp1(tx,ux,x,'spline').*exp(-s.*x);
else, f=@(x)tx(x).*exp(-s.*x); end
sU=integral(f,t0,tn,'ArrayValued',true);
end
btF=bt.*sG./(1+sG.*sH).*sU; y(i)=sum(real(btF));
end, t=t(:); y=y(:);
end
% remove and add back dots uniformly
function F=add_dots(F)
F=strrep(strrep(strrep(F,'.*','*'),'./','/'),'.^','^');
F=strrep(strrep(strrep(F,'*','.*'),'/','./'),'^','.^');
end

34
FOTF Toolbox/Readme.txt Normal file
View File

@ -0,0 +1,34 @@
About FOTF Toolbox
(c) Professor Dingy\"u Xue, Northeastern University, Shenyang, China
Email: xuedingyu@mail.neu.edu.cn
Date of last modification, 09 May, 2022
This newly modified toolbox is written for the monograph, for details, please cite
@BOOK{bkXueDFOCS,
Author = {Xue Dingy\"u},
Address = {Berlin},
Publisher = {de Gruyter Press},
Title = {Fractional-order Control Systems - Fundamentals and Numerical Implementations},
Year = {2017}
}
For the new version, please cite
@BOOK{bkXueNew,
Author = {Xue Dingy\"u, Bai Lu},
Address = {Beijing},
Publisher = {Tsinghua University Press},
Title = {Fractional Calculus - Numerical Algorithms and Implementations},
Year = {2022}
}
For the full list of the toolbox, please check Contents.m
Please Note that
If you are using MATLAB 2022a or newer, please disable the simulink2019 subfolders in your MATLAB path,
while if you are using old versions, disable the subfolder Simulink in your MATLAB path.
---------------------------------
FOTF Toolbox, Release 2.0, 9 May, 2022

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,4 @@
function y=bp3_fcn(u)
y=u^(1.5-sqrt(2))*exp(u)*...
ml_func([1,3-sqrt(2)],-u)./ml_func([1,1.5],-u);
end

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More