commit d5a822831c15ec7142968b03c7b2c73fee2b7d1f Author: cypressboat <toby20001206@126.com> Date: Tue Nov 14 17:10:27 2023 +0800 init diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7871ff3 --- /dev/null +++ b/.gitattributes @@ -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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..92061b1 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/Coop3LeaderFollower1D8.slx b/Coop3LeaderFollower1D8.slx new file mode 100644 index 0000000..fa56bc6 Binary files /dev/null and b/Coop3LeaderFollower1D8.slx differ diff --git a/Coop3LeaderFollower2.slx b/Coop3LeaderFollower2.slx new file mode 100644 index 0000000..8f68617 Binary files /dev/null and b/Coop3LeaderFollower2.slx differ diff --git a/Coop3LeaderFollower2D2.slx b/Coop3LeaderFollower2D2.slx new file mode 100644 index 0000000..bb9ac92 Binary files /dev/null and b/Coop3LeaderFollower2D2.slx differ diff --git a/FOTF Toolbox/@foss/bode.m b/FOTF Toolbox/@foss/bode.m new file mode 100644 index 0000000..c147b2f --- /dev/null +++ b/FOTF Toolbox/@foss/bode.m @@ -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 diff --git a/FOTF Toolbox/@foss/coss_aug.m b/FOTF Toolbox/@foss/coss_aug.m new file mode 100644 index 0000000..0b6897c --- /dev/null +++ b/FOTF Toolbox/@foss/coss_aug.m @@ -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 diff --git a/FOTF Toolbox/@foss/ctrb.m b/FOTF Toolbox/@foss/ctrb.m new file mode 100644 index 0000000..3689b80 --- /dev/null +++ b/FOTF Toolbox/@foss/ctrb.m @@ -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 diff --git a/FOTF Toolbox/@foss/disp.m b/FOTF Toolbox/@foss/disp.m new file mode 100644 index 0000000..64ca41a --- /dev/null +++ b/FOTF Toolbox/@foss/disp.m @@ -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 diff --git a/FOTF Toolbox/@foss/eig.m b/FOTF Toolbox/@foss/eig.m new file mode 100644 index 0000000..aefdaee --- /dev/null +++ b/FOTF Toolbox/@foss/eig.m @@ -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 diff --git a/FOTF Toolbox/@foss/eq.m b/FOTF Toolbox/@foss/eq.m new file mode 100644 index 0000000..5f47782 --- /dev/null +++ b/FOTF Toolbox/@foss/eq.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/@foss/feedback.m b/FOTF Toolbox/@foss/feedback.m new file mode 100644 index 0000000..04df663 --- /dev/null +++ b/FOTF Toolbox/@foss/feedback.m @@ -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 diff --git a/FOTF Toolbox/@foss/foss.m b/FOTF Toolbox/@foss/foss.m new file mode 100644 index 0000000..682f950 --- /dev/null +++ b/FOTF Toolbox/@foss/foss.m @@ -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 diff --git a/FOTF Toolbox/@foss/foss2fotf.m b/FOTF Toolbox/@foss/foss2fotf.m new file mode 100644 index 0000000..6583a7a --- /dev/null +++ b/FOTF Toolbox/@foss/foss2fotf.m @@ -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 diff --git a/FOTF Toolbox/@foss/impulse.m b/FOTF Toolbox/@foss/impulse.m new file mode 100644 index 0000000..6d62cd7 --- /dev/null +++ b/FOTF Toolbox/@foss/impulse.m @@ -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 diff --git a/FOTF Toolbox/@foss/inv.m b/FOTF Toolbox/@foss/inv.m new file mode 100644 index 0000000..10379b6 --- /dev/null +++ b/FOTF Toolbox/@foss/inv.m @@ -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 diff --git a/FOTF Toolbox/@foss/isfoss.m b/FOTF Toolbox/@foss/isfoss.m new file mode 100644 index 0000000..7db2ecd --- /dev/null +++ b/FOTF Toolbox/@foss/isfoss.m @@ -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 diff --git a/FOTF Toolbox/@foss/isstable.m b/FOTF Toolbox/@foss/isstable.m new file mode 100644 index 0000000..bad6ac4 --- /dev/null +++ b/FOTF Toolbox/@foss/isstable.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/@foss/lsim.m b/FOTF Toolbox/@foss/lsim.m new file mode 100644 index 0000000..67e48cd --- /dev/null +++ b/FOTF Toolbox/@foss/lsim.m @@ -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 diff --git a/FOTF Toolbox/@foss/margin.m b/FOTF Toolbox/@foss/margin.m new file mode 100644 index 0000000..f3c528d --- /dev/null +++ b/FOTF Toolbox/@foss/margin.m @@ -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 diff --git a/FOTF Toolbox/@foss/mfrd.m b/FOTF Toolbox/@foss/mfrd.m new file mode 100644 index 0000000..f48edb5 --- /dev/null +++ b/FOTF Toolbox/@foss/mfrd.m @@ -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 diff --git a/FOTF Toolbox/@foss/minreal.m b/FOTF Toolbox/@foss/minreal.m new file mode 100644 index 0000000..3399a32 --- /dev/null +++ b/FOTF Toolbox/@foss/minreal.m @@ -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 diff --git a/FOTF Toolbox/@foss/minus.m b/FOTF Toolbox/@foss/minus.m new file mode 100644 index 0000000..23211ba --- /dev/null +++ b/FOTF Toolbox/@foss/minus.m @@ -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 diff --git a/FOTF Toolbox/@foss/mpower.m b/FOTF Toolbox/@foss/mpower.m new file mode 100644 index 0000000..00d3d21 --- /dev/null +++ b/FOTF Toolbox/@foss/mpower.m @@ -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 diff --git a/FOTF Toolbox/@foss/mtimes.m b/FOTF Toolbox/@foss/mtimes.m new file mode 100644 index 0000000..216eeb9 --- /dev/null +++ b/FOTF Toolbox/@foss/mtimes.m @@ -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 diff --git a/FOTF Toolbox/@foss/nichols.m b/FOTF Toolbox/@foss/nichols.m new file mode 100644 index 0000000..6eb70c3 --- /dev/null +++ b/FOTF Toolbox/@foss/nichols.m @@ -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 diff --git a/FOTF Toolbox/@foss/norm.m b/FOTF Toolbox/@foss/norm.m new file mode 100644 index 0000000..69c150d --- /dev/null +++ b/FOTF Toolbox/@foss/norm.m @@ -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 diff --git a/FOTF Toolbox/@foss/nyquist.m b/FOTF Toolbox/@foss/nyquist.m new file mode 100644 index 0000000..403b9cf --- /dev/null +++ b/FOTF Toolbox/@foss/nyquist.m @@ -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 diff --git a/FOTF Toolbox/@foss/obsv.m b/FOTF Toolbox/@foss/obsv.m new file mode 100644 index 0000000..2b18348 --- /dev/null +++ b/FOTF Toolbox/@foss/obsv.m @@ -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 diff --git a/FOTF Toolbox/@foss/order.m b/FOTF Toolbox/@foss/order.m new file mode 100644 index 0000000..3f1cc20 --- /dev/null +++ b/FOTF Toolbox/@foss/order.m @@ -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 diff --git a/FOTF Toolbox/@foss/plus.m b/FOTF Toolbox/@foss/plus.m new file mode 100644 index 0000000..615fe11 --- /dev/null +++ b/FOTF Toolbox/@foss/plus.m @@ -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 diff --git a/FOTF Toolbox/@foss/rlocus.m b/FOTF Toolbox/@foss/rlocus.m new file mode 100644 index 0000000..54d1738 --- /dev/null +++ b/FOTF Toolbox/@foss/rlocus.m @@ -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 diff --git a/FOTF Toolbox/@foss/size.m b/FOTF Toolbox/@foss/size.m new file mode 100644 index 0000000..854771d --- /dev/null +++ b/FOTF Toolbox/@foss/size.m @@ -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 diff --git a/FOTF Toolbox/@foss/ss_extract.m b/FOTF Toolbox/@foss/ss_extract.m new file mode 100644 index 0000000..67a18cb --- /dev/null +++ b/FOTF Toolbox/@foss/ss_extract.m @@ -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 diff --git a/FOTF Toolbox/@foss/step.m b/FOTF Toolbox/@foss/step.m new file mode 100644 index 0000000..f4af8ea --- /dev/null +++ b/FOTF Toolbox/@foss/step.m @@ -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 diff --git a/FOTF Toolbox/@foss/uminus.m b/FOTF Toolbox/@foss/uminus.m new file mode 100644 index 0000000..2275e5d --- /dev/null +++ b/FOTF Toolbox/@foss/uminus.m @@ -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 diff --git a/FOTF Toolbox/@fotf/base_order.m b/FOTF Toolbox/@fotf/base_order.m new file mode 100644 index 0000000..33ea786 --- /dev/null +++ b/FOTF Toolbox/@fotf/base_order.m @@ -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 diff --git a/FOTF Toolbox/@fotf/bode.m b/FOTF Toolbox/@fotf/bode.m new file mode 100644 index 0000000..7715dc1 --- /dev/null +++ b/FOTF Toolbox/@fotf/bode.m @@ -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 diff --git a/FOTF Toolbox/@fotf/diag.m b/FOTF Toolbox/@fotf/diag.m new file mode 100644 index 0000000..cc5c9f7 --- /dev/null +++ b/FOTF Toolbox/@fotf/diag.m @@ -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 diff --git a/FOTF Toolbox/@fotf/disp.m b/FOTF Toolbox/@fotf/disp.m new file mode 100644 index 0000000..503b9c8 --- /dev/null +++ b/FOTF Toolbox/@fotf/disp.m @@ -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 diff --git a/FOTF Toolbox/@fotf/double.m b/FOTF Toolbox/@fotf/double.m new file mode 100644 index 0000000..ec139f6 --- /dev/null +++ b/FOTF Toolbox/@fotf/double.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/@fotf/eig.m b/FOTF Toolbox/@fotf/eig.m new file mode 100644 index 0000000..482bc46 --- /dev/null +++ b/FOTF Toolbox/@fotf/eig.m @@ -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 diff --git a/FOTF Toolbox/@fotf/eq.m b/FOTF Toolbox/@fotf/eq.m new file mode 100644 index 0000000..dfb35c1 --- /dev/null +++ b/FOTF Toolbox/@fotf/eq.m @@ -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 diff --git a/FOTF Toolbox/@fotf/exp.m b/FOTF Toolbox/@fotf/exp.m new file mode 100644 index 0000000..1c7f9e8 --- /dev/null +++ b/FOTF Toolbox/@fotf/exp.m @@ -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 diff --git a/FOTF Toolbox/@fotf/feedback.m b/FOTF Toolbox/@fotf/feedback.m new file mode 100644 index 0000000..0195c76 --- /dev/null +++ b/FOTF Toolbox/@fotf/feedback.m @@ -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 diff --git a/FOTF Toolbox/@fotf/foss_a.m b/FOTF Toolbox/@fotf/foss_a.m new file mode 100644 index 0000000..43a256b --- /dev/null +++ b/FOTF Toolbox/@fotf/foss_a.m @@ -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 diff --git a/FOTF Toolbox/@fotf/fotf.m b/FOTF Toolbox/@fotf/fotf.m new file mode 100644 index 0000000..198ff71 --- /dev/null +++ b/FOTF Toolbox/@fotf/fotf.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/@fotf/fotf2cotf.m b/FOTF Toolbox/@fotf/fotf2cotf.m new file mode 100644 index 0000000..0acb290 --- /dev/null +++ b/FOTF Toolbox/@fotf/fotf2cotf.m @@ -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 diff --git a/FOTF Toolbox/@fotf/fotf2foss.m b/FOTF Toolbox/@fotf/fotf2foss.m new file mode 100644 index 0000000..e1352b7 --- /dev/null +++ b/FOTF Toolbox/@fotf/fotf2foss.m @@ -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 diff --git a/FOTF Toolbox/@fotf/fotfdata.m b/FOTF Toolbox/@fotf/fotfdata.m new file mode 100644 index 0000000..bf7884e --- /dev/null +++ b/FOTF Toolbox/@fotf/fotfdata.m @@ -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 diff --git a/FOTF Toolbox/@fotf/freqresp.m b/FOTF Toolbox/@fotf/freqresp.m new file mode 100644 index 0000000..90dd475 --- /dev/null +++ b/FOTF Toolbox/@fotf/freqresp.m @@ -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 diff --git a/FOTF Toolbox/@fotf/high_order.m b/FOTF Toolbox/@fotf/high_order.m new file mode 100644 index 0000000..1187aff --- /dev/null +++ b/FOTF Toolbox/@fotf/high_order.m @@ -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 diff --git a/FOTF Toolbox/@fotf/impulse.m b/FOTF Toolbox/@fotf/impulse.m new file mode 100644 index 0000000..d33abd4 --- /dev/null +++ b/FOTF Toolbox/@fotf/impulse.m @@ -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 diff --git a/FOTF Toolbox/@fotf/inv.m b/FOTF Toolbox/@fotf/inv.m new file mode 100644 index 0000000..c6fb1ff --- /dev/null +++ b/FOTF Toolbox/@fotf/inv.m @@ -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 diff --git a/FOTF Toolbox/@fotf/isfotf.m b/FOTF Toolbox/@fotf/isfotf.m new file mode 100644 index 0000000..5d92d4f --- /dev/null +++ b/FOTF Toolbox/@fotf/isfotf.m @@ -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 diff --git a/FOTF Toolbox/@fotf/isstable.m b/FOTF Toolbox/@fotf/isstable.m new file mode 100644 index 0000000..8488beb --- /dev/null +++ b/FOTF Toolbox/@fotf/isstable.m @@ -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 diff --git a/FOTF Toolbox/@fotf/iszero.m b/FOTF Toolbox/@fotf/iszero.m new file mode 100644 index 0000000..096748a --- /dev/null +++ b/FOTF Toolbox/@fotf/iszero.m @@ -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 diff --git a/FOTF Toolbox/@fotf/latex.m b/FOTF Toolbox/@fotf/latex.m new file mode 100644 index 0000000..5029a10 --- /dev/null +++ b/FOTF Toolbox/@fotf/latex.m @@ -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 diff --git a/FOTF Toolbox/@fotf/lsim.m b/FOTF Toolbox/@fotf/lsim.m new file mode 100644 index 0000000..498273c --- /dev/null +++ b/FOTF Toolbox/@fotf/lsim.m @@ -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 diff --git a/FOTF Toolbox/@fotf/margin.m b/FOTF Toolbox/@fotf/margin.m new file mode 100644 index 0000000..4e51986 --- /dev/null +++ b/FOTF Toolbox/@fotf/margin.m @@ -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 diff --git a/FOTF Toolbox/@fotf/maxdelay.m b/FOTF Toolbox/@fotf/maxdelay.m new file mode 100644 index 0000000..9ddc87f --- /dev/null +++ b/FOTF Toolbox/@fotf/maxdelay.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/@fotf/mfrd.m b/FOTF Toolbox/@fotf/mfrd.m new file mode 100644 index 0000000..1714f18 --- /dev/null +++ b/FOTF Toolbox/@fotf/mfrd.m @@ -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 diff --git a/FOTF Toolbox/@fotf/minus.m b/FOTF Toolbox/@fotf/minus.m new file mode 100644 index 0000000..03d83d4 --- /dev/null +++ b/FOTF Toolbox/@fotf/minus.m @@ -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 diff --git a/FOTF Toolbox/@fotf/mldivide.m b/FOTF Toolbox/@fotf/mldivide.m new file mode 100644 index 0000000..7310734 --- /dev/null +++ b/FOTF Toolbox/@fotf/mldivide.m @@ -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 diff --git a/FOTF Toolbox/@fotf/mpower.m b/FOTF Toolbox/@fotf/mpower.m new file mode 100644 index 0000000..e2f6502 --- /dev/null +++ b/FOTF Toolbox/@fotf/mpower.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/@fotf/mrdivide.m b/FOTF Toolbox/@fotf/mrdivide.m new file mode 100644 index 0000000..669b244 --- /dev/null +++ b/FOTF Toolbox/@fotf/mrdivide.m @@ -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 diff --git a/FOTF Toolbox/@fotf/mtimes.m b/FOTF Toolbox/@fotf/mtimes.m new file mode 100644 index 0000000..5b6624b --- /dev/null +++ b/FOTF Toolbox/@fotf/mtimes.m @@ -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 diff --git a/FOTF Toolbox/@fotf/nichols.m b/FOTF Toolbox/@fotf/nichols.m new file mode 100644 index 0000000..bc9fff7 --- /dev/null +++ b/FOTF Toolbox/@fotf/nichols.m @@ -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 diff --git a/FOTF Toolbox/@fotf/norm.m b/FOTF Toolbox/@fotf/norm.m new file mode 100644 index 0000000..32ffc68 --- /dev/null +++ b/FOTF Toolbox/@fotf/norm.m @@ -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 diff --git a/FOTF Toolbox/@fotf/numel.m b/FOTF Toolbox/@fotf/numel.m new file mode 100644 index 0000000..9279ec1 --- /dev/null +++ b/FOTF Toolbox/@fotf/numel.m @@ -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 diff --git a/FOTF Toolbox/@fotf/nyquist.m b/FOTF Toolbox/@fotf/nyquist.m new file mode 100644 index 0000000..c283f25 --- /dev/null +++ b/FOTF Toolbox/@fotf/nyquist.m @@ -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 diff --git a/FOTF Toolbox/@fotf/plus.m b/FOTF Toolbox/@fotf/plus.m new file mode 100644 index 0000000..75aa39e --- /dev/null +++ b/FOTF Toolbox/@fotf/plus.m @@ -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 diff --git a/FOTF Toolbox/@fotf/residue.m b/FOTF Toolbox/@fotf/residue.m new file mode 100644 index 0000000..754f330 --- /dev/null +++ b/FOTF Toolbox/@fotf/residue.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/@fotf/rlocus.m b/FOTF Toolbox/@fotf/rlocus.m new file mode 100644 index 0000000..b36b70f --- /dev/null +++ b/FOTF Toolbox/@fotf/rlocus.m @@ -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 diff --git a/FOTF Toolbox/@fotf/sigma.m b/FOTF Toolbox/@fotf/sigma.m new file mode 100644 index 0000000..6d1c3f3 --- /dev/null +++ b/FOTF Toolbox/@fotf/sigma.m @@ -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 diff --git a/FOTF Toolbox/@fotf/simplify.m b/FOTF Toolbox/@fotf/simplify.m new file mode 100644 index 0000000..7bdf6ea --- /dev/null +++ b/FOTF Toolbox/@fotf/simplify.m @@ -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 diff --git a/FOTF Toolbox/@fotf/step.m b/FOTF Toolbox/@fotf/step.m new file mode 100644 index 0000000..10a7ba0 --- /dev/null +++ b/FOTF Toolbox/@fotf/step.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/@fotf/uminus.m b/FOTF Toolbox/@fotf/uminus.m new file mode 100644 index 0000000..af29f53 --- /dev/null +++ b/FOTF Toolbox/@fotf/uminus.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/collect.m b/FOTF Toolbox/@ppoly/collect.m new file mode 100644 index 0000000..2522ca6 --- /dev/null +++ b/FOTF Toolbox/@ppoly/collect.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/disp.m b/FOTF Toolbox/@ppoly/disp.m new file mode 100644 index 0000000..fa00b16 --- /dev/null +++ b/FOTF Toolbox/@ppoly/disp.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/eq.m b/FOTF Toolbox/@ppoly/eq.m new file mode 100644 index 0000000..8e33339 --- /dev/null +++ b/FOTF Toolbox/@ppoly/eq.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/freqw.m b/FOTF Toolbox/@ppoly/freqw.m new file mode 100644 index 0000000..4ae803f --- /dev/null +++ b/FOTF Toolbox/@ppoly/freqw.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/get.m b/FOTF Toolbox/@ppoly/get.m new file mode 100644 index 0000000..2cbde4a --- /dev/null +++ b/FOTF Toolbox/@ppoly/get.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/@ppoly/isppoly.m b/FOTF Toolbox/@ppoly/isppoly.m new file mode 100644 index 0000000..0420d71 --- /dev/null +++ b/FOTF Toolbox/@ppoly/isppoly.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/@ppoly/latex.m b/FOTF Toolbox/@ppoly/latex.m new file mode 100644 index 0000000..0c64932 --- /dev/null +++ b/FOTF Toolbox/@ppoly/latex.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/minus.m b/FOTF Toolbox/@ppoly/minus.m new file mode 100644 index 0000000..7050b31 --- /dev/null +++ b/FOTF Toolbox/@ppoly/minus.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/mpower.m b/FOTF Toolbox/@ppoly/mpower.m new file mode 100644 index 0000000..83b07ae --- /dev/null +++ b/FOTF Toolbox/@ppoly/mpower.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/mrdivide.m b/FOTF Toolbox/@ppoly/mrdivide.m new file mode 100644 index 0000000..06af807 --- /dev/null +++ b/FOTF Toolbox/@ppoly/mrdivide.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/mtimes.m b/FOTF Toolbox/@ppoly/mtimes.m new file mode 100644 index 0000000..045c2ad --- /dev/null +++ b/FOTF Toolbox/@ppoly/mtimes.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/plus.m b/FOTF Toolbox/@ppoly/plus.m new file mode 100644 index 0000000..5b758af --- /dev/null +++ b/FOTF Toolbox/@ppoly/plus.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/ppoly.m b/FOTF Toolbox/@ppoly/ppoly.m new file mode 100644 index 0000000..60619f3 --- /dev/null +++ b/FOTF Toolbox/@ppoly/ppoly.m @@ -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 diff --git a/FOTF Toolbox/@ppoly/uminus.m b/FOTF Toolbox/@ppoly/uminus.m new file mode 100644 index 0000000..9045cad --- /dev/null +++ b/FOTF Toolbox/@ppoly/uminus.m @@ -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 diff --git a/FOTF Toolbox/Contents.m b/FOTF Toolbox/Contents.m new file mode 100644 index 0000000..848adf4 --- /dev/null +++ b/FOTF Toolbox/Contents.m @@ -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 + diff --git a/FOTF Toolbox/INVLAP_new.m b/FOTF Toolbox/INVLAP_new.m new file mode 100644 index 0000000..1e79648 --- /dev/null +++ b/FOTF Toolbox/INVLAP_new.m @@ -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 \ No newline at end of file diff --git a/FOTF Toolbox/Readme.txt b/FOTF Toolbox/Readme.txt new file mode 100644 index 0000000..00c2a5c --- /dev/null +++ b/FOTF Toolbox/Readme.txt @@ -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 + diff --git a/FOTF Toolbox/Simulink/bench/bp1_model.slx b/FOTF Toolbox/Simulink/bench/bp1_model.slx new file mode 100644 index 0000000..6fe883a Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp1_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp1_model2.slx b/FOTF Toolbox/Simulink/bench/bp1_model2.slx new file mode 100644 index 0000000..39a9253 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp1_model2.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp2_model.slx b/FOTF Toolbox/Simulink/bench/bp2_model.slx new file mode 100644 index 0000000..4c4a4bf Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp2_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp3_fcn.m b/FOTF Toolbox/Simulink/bench/bp3_fcn.m new file mode 100644 index 0000000..0d37ff3 --- /dev/null +++ b/FOTF Toolbox/Simulink/bench/bp3_fcn.m @@ -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 diff --git a/FOTF Toolbox/Simulink/bench/bp3_model.slx b/FOTF Toolbox/Simulink/bench/bp3_model.slx new file mode 100644 index 0000000..4f583f5 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp3_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp4_fcn.m b/FOTF Toolbox/Simulink/bench/bp4_fcn.m new file mode 100644 index 0000000..f37c049 --- /dev/null +++ b/FOTF Toolbox/Simulink/bench/bp4_fcn.m @@ -0,0 +1,4 @@ +function y=bp4_fcn(t) + y=1/8*t*(ml_func([1,1.8],-t/2)*ml_func([1,1.2],-t/2)+... + ml_func([1,1.7],-t/2)*ml_func([1,1.3],-t/2)); +end diff --git a/FOTF Toolbox/Simulink/bench/bp4_model.slx b/FOTF Toolbox/Simulink/bench/bp4_model.slx new file mode 100644 index 0000000..b37f819 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp4_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp4a_model.slx b/FOTF Toolbox/Simulink/bench/bp4a_model.slx new file mode 100644 index 0000000..0ac3af7 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp4a_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp5_fcn.m b/FOTF Toolbox/Simulink/bench/bp5_fcn.m new file mode 100644 index 0000000..74e8bab --- /dev/null +++ b/FOTF Toolbox/Simulink/bench/bp5_fcn.m @@ -0,0 +1,5 @@ +function y=bp5_fcn(u) + y=[(((u(2)-0.5)*(u(3)-0.3))^(1/5)+sqrt(u(4)))/sqrt(pi); + (u(1)-1)*gamma(2.2); (u(2)-0.5)*gamma(2.3)/gamma(2.2)]; + y=real(y); %{\kaishu\,因未知原因混入微小的虚数,所以需要提取实部} +end \ No newline at end of file diff --git a/FOTF Toolbox/Simulink/bench/bp5_model.slx b/FOTF Toolbox/Simulink/bench/bp5_model.slx new file mode 100644 index 0000000..a97724e Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp5_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp5_model2.slx b/FOTF Toolbox/Simulink/bench/bp5_model2.slx new file mode 100644 index 0000000..200e299 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp5_model2.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp5_model_v.slx b/FOTF Toolbox/Simulink/bench/bp5_model_v.slx new file mode 100644 index 0000000..3d976c4 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp5_model_v.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp5a_fcn2.m b/FOTF Toolbox/Simulink/bench/bp5a_fcn2.m new file mode 100644 index 0000000..81a9ec3 --- /dev/null +++ b/FOTF Toolbox/Simulink/bench/bp5a_fcn2.m @@ -0,0 +1,6 @@ +function y=c8mfss3a(u) + y=[2/sqrt(pi)*(((u(2)-0.3)*(u(3)-0.5*u(1)))^(1/5)+sqrt(u(5))); + gamma(1.4)/gamma(1.3)*((u(1)-1)/2)^0.3; + u(4); gamma(3.1)/gamma(1.6)*sqrt((u(2)-0.3)^3)]; + y=real(y); %{\kaishu\,因未知原因混入微小的虚数,所以需要提取实部} +end diff --git a/FOTF Toolbox/Simulink/bench/bp5a_model.slx b/FOTF Toolbox/Simulink/bench/bp5a_model.slx new file mode 100644 index 0000000..bfab57a Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp5a_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp5a_model2.slx b/FOTF Toolbox/Simulink/bench/bp5a_model2.slx new file mode 100644 index 0000000..d80da3d Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp5a_model2.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp5b_fcn.m b/FOTF Toolbox/Simulink/bench/bp5b_fcn.m new file mode 100644 index 0000000..27715ae --- /dev/null +++ b/FOTF Toolbox/Simulink/bench/bp5b_fcn.m @@ -0,0 +1,6 @@ +function y=bp5b_fcn(u) + y=[4/sqrt(pi)*((u(2)-0.3)*(u(3)-0.5*u(1)))^(1/5); + gamma(1.4)/gamma(1.3)*((u(1)-1)/2)^0.3; + gamma(3.1)/gamma(1.6)*sqrt((u(2)-0.3)^3)]; + y=real(y); %{\kaishu\,因未知原因混入微小的虚数,所以需要提取实部} +end diff --git a/FOTF Toolbox/Simulink/bench/bp5b_model.slx b/FOTF Toolbox/Simulink/bench/bp5b_model.slx new file mode 100644 index 0000000..4e47465 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp5b_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp6_fcn.m b/FOTF Toolbox/Simulink/bench/bp6_fcn.m new file mode 100644 index 0000000..dcf4a44 --- /dev/null +++ b/FOTF Toolbox/Simulink/bench/bp6_fcn.m @@ -0,0 +1,3 @@ +function y = bp6_fcn(u) +y=u^(1.5-sqrt(2))*exp(u)*... + ml_func([1,3-sqrt(2)],-u)./ml_func([1,1.5],-u); diff --git a/FOTF Toolbox/Simulink/bench/bp6_model.slx b/FOTF Toolbox/Simulink/bench/bp6_model.slx new file mode 100644 index 0000000..6171406 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp6_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp6_model1.slx b/FOTF Toolbox/Simulink/bench/bp6_model1.slx new file mode 100644 index 0000000..d7bcd9a Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp6_model1.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp6_model2.slx b/FOTF Toolbox/Simulink/bench/bp6_model2.slx new file mode 100644 index 0000000..3e28a12 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp6_model2.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp6a_model.slx b/FOTF Toolbox/Simulink/bench/bp6a_model.slx new file mode 100644 index 0000000..d3aace7 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp6a_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp7_model.slx b/FOTF Toolbox/Simulink/bench/bp7_model.slx new file mode 100644 index 0000000..2869a7f Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp7_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp7_opts.m b/FOTF Toolbox/Simulink/bench/bp7_opts.m new file mode 100644 index 0000000..caed381 --- /dev/null +++ b/FOTF Toolbox/Simulink/bench/bp7_opts.m @@ -0,0 +1,5 @@ +function y=bp7_opts(x) + W=get_param(gcs,'ModelWorkspace'); assignin(W,'a',x(1)) + try, txy=sim('bp7_model'); y0=txy.yout; y=abs(y0(end)-exp(-1)); + catch, y=10; end +end diff --git a/FOTF Toolbox/Simulink/bench/bp7a_model.slx b/FOTF Toolbox/Simulink/bench/bp7a_model.slx new file mode 100644 index 0000000..fc2de83 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp7a_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp8_fcn.m b/FOTF Toolbox/Simulink/bench/bp8_fcn.m new file mode 100644 index 0000000..cef9868 --- /dev/null +++ b/FOTF Toolbox/Simulink/bench/bp8_fcn.m @@ -0,0 +1,3 @@ +function y = bp7_fcn(u) +y=u^(1.5-sqrt(2))*exp(u)*... + ml_func([1,3-sqrt(2)],-u)./ml_func([1,1.5],-u); diff --git a/FOTF Toolbox/Simulink/bench/bp8_model.slx b/FOTF Toolbox/Simulink/bench/bp8_model.slx new file mode 100644 index 0000000..464bfef Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp8_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp8a_fcn.m b/FOTF Toolbox/Simulink/bench/bp8a_fcn.m new file mode 100644 index 0000000..052c88b --- /dev/null +++ b/FOTF Toolbox/Simulink/bench/bp8a_fcn.m @@ -0,0 +1,4 @@ +function y=bp8a_fcn(t) + y=t^(1.5-sqrt(2))*exp(t-0.3)*... + ml_func([1,3-sqrt(2)],-t)./ml_func([1,1.5],-t); +end diff --git a/FOTF Toolbox/Simulink/bench/bp8a_model.slx b/FOTF Toolbox/Simulink/bench/bp8a_model.slx new file mode 100644 index 0000000..bfa89d8 Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp8a_model.slx differ diff --git a/FOTF Toolbox/Simulink/bench/bp_models.slx b/FOTF Toolbox/Simulink/bench/bp_models.slx new file mode 100644 index 0000000..f4f2b2e Binary files /dev/null and b/FOTF Toolbox/Simulink/bench/bp_models.slx differ diff --git a/FOTF Toolbox/Simulink/c10mpdm2.slx b/FOTF Toolbox/Simulink/c10mpdm2.slx new file mode 100644 index 0000000..2166c24 Binary files /dev/null and b/FOTF Toolbox/Simulink/c10mpdm2.slx differ diff --git a/FOTF Toolbox/Simulink/c10mpopt.slx b/FOTF Toolbox/Simulink/c10mpopt.slx new file mode 100644 index 0000000..d5cf2d0 Binary files /dev/null and b/FOTF Toolbox/Simulink/c10mpopt.slx differ diff --git a/FOTF Toolbox/Simulink/c4msim1.slx b/FOTF Toolbox/Simulink/c4msim1.slx new file mode 100644 index 0000000..9e38636 Binary files /dev/null and b/FOTF Toolbox/Simulink/c4msim1.slx differ diff --git a/FOTF Toolbox/Simulink/c5mimp.slx b/FOTF Toolbox/Simulink/c5mimp.slx new file mode 100644 index 0000000..c31a349 Binary files /dev/null and b/FOTF Toolbox/Simulink/c5mimp.slx differ diff --git a/FOTF Toolbox/Simulink/c5mqft.slx b/FOTF Toolbox/Simulink/c5mqft.slx new file mode 100644 index 0000000..24d3154 Binary files /dev/null and b/FOTF Toolbox/Simulink/c5mqft.slx differ diff --git a/FOTF Toolbox/Simulink/c5msim1.slx b/FOTF Toolbox/Simulink/c5msim1.slx new file mode 100644 index 0000000..9c0871e Binary files /dev/null and b/FOTF Toolbox/Simulink/c5msim1.slx differ diff --git a/FOTF Toolbox/Simulink/c8mblk1a.slx b/FOTF Toolbox/Simulink/c8mblk1a.slx new file mode 100644 index 0000000..2e44b56 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mblk1a.slx differ diff --git a/FOTF Toolbox/Simulink/c8mblk1b.slx b/FOTF Toolbox/Simulink/c8mblk1b.slx new file mode 100644 index 0000000..96f904e Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mblk1b.slx differ diff --git a/FOTF Toolbox/Simulink/c8mblk2.slx b/FOTF Toolbox/Simulink/c8mblk2.slx new file mode 100644 index 0000000..82cc7eb Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mblk2.slx differ diff --git a/FOTF Toolbox/Simulink/c8mblk3.slx b/FOTF Toolbox/Simulink/c8mblk3.slx new file mode 100644 index 0000000..9fafb79 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mblk3.slx differ diff --git a/FOTF Toolbox/Simulink/c8mblk5.slx b/FOTF Toolbox/Simulink/c8mblk5.slx new file mode 100644 index 0000000..afdf2f5 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mblk5.slx differ diff --git a/FOTF Toolbox/Simulink/c8mcaputos.slx b/FOTF Toolbox/Simulink/c8mcaputos.slx new file mode 100644 index 0000000..18ef282 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mcaputos.slx differ diff --git a/FOTF Toolbox/Simulink/c8mchaos.slx b/FOTF Toolbox/Simulink/c8mchaos.slx new file mode 100644 index 0000000..7c6a146 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mchaos.slx differ diff --git a/FOTF Toolbox/Simulink/c8mchaos2.slx b/FOTF Toolbox/Simulink/c8mchaos2.slx new file mode 100644 index 0000000..42b53d6 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mchaos2.slx differ diff --git a/FOTF Toolbox/Simulink/c8mchaos_v.slx b/FOTF Toolbox/Simulink/c8mchaos_v.slx new file mode 100644 index 0000000..a9dc5fe Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mchaos_v.slx differ diff --git a/FOTF Toolbox/Simulink/c8mchuasim.slx b/FOTF Toolbox/Simulink/c8mchuasim.slx new file mode 100644 index 0000000..58ddce6 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mchuasim.slx differ diff --git a/FOTF Toolbox/Simulink/c8mexp2s.slx b/FOTF Toolbox/Simulink/c8mexp2s.slx new file mode 100644 index 0000000..0ba57c0 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mexp2s.slx differ diff --git a/FOTF Toolbox/Simulink/c8mfpid.slx b/FOTF Toolbox/Simulink/c8mfpid.slx new file mode 100644 index 0000000..d76a06a Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mfpid.slx differ diff --git a/FOTF Toolbox/Simulink/c8mfpid1.slx b/FOTF Toolbox/Simulink/c8mfpid1.slx new file mode 100644 index 0000000..a150d06 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mfpid1.slx differ diff --git a/FOTF Toolbox/Simulink/c8mimps.slx b/FOTF Toolbox/Simulink/c8mimps.slx new file mode 100644 index 0000000..251de51 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mimps.slx differ diff --git a/FOTF Toolbox/Simulink/c8mmimo.slx b/FOTF Toolbox/Simulink/c8mmimo.slx new file mode 100644 index 0000000..3e2ee75 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mmimo.slx differ diff --git a/FOTF Toolbox/Simulink/c8mnlf1.slx b/FOTF Toolbox/Simulink/c8mnlf1.slx new file mode 100644 index 0000000..869f85c Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mnlf1.slx differ diff --git a/FOTF Toolbox/Simulink/c8mnlf2.slx b/FOTF Toolbox/Simulink/c8mnlf2.slx new file mode 100644 index 0000000..f612e1f Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mnlf2.slx differ diff --git a/FOTF Toolbox/Simulink/c8mnlf3.slx b/FOTF Toolbox/Simulink/c8mnlf3.slx new file mode 100644 index 0000000..c1bda87 Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mnlf3.slx differ diff --git a/FOTF Toolbox/Simulink/c8mod_3.slx b/FOTF Toolbox/Simulink/c8mod_3.slx new file mode 100644 index 0000000..97c33dd Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mod_3.slx differ diff --git a/FOTF Toolbox/Simulink/c8mstep.slx b/FOTF Toolbox/Simulink/c8mstep.slx new file mode 100644 index 0000000..c84964d Binary files /dev/null and b/FOTF Toolbox/Simulink/c8mstep.slx differ diff --git a/FOTF Toolbox/Simulink/c9mdde1a.slx b/FOTF Toolbox/Simulink/c9mdde1a.slx new file mode 100644 index 0000000..4066b3e Binary files /dev/null and b/FOTF Toolbox/Simulink/c9mdde1a.slx differ diff --git a/FOTF Toolbox/Simulink/c9mdde1b.slx b/FOTF Toolbox/Simulink/c9mdde1b.slx new file mode 100644 index 0000000..3b0962b Binary files /dev/null and b/FOTF Toolbox/Simulink/c9mdde1b.slx differ diff --git a/FOTF Toolbox/Simulink/c9mdde3.slx b/FOTF Toolbox/Simulink/c9mdde3.slx new file mode 100644 index 0000000..08825c6 Binary files /dev/null and b/FOTF Toolbox/Simulink/c9mdde3.slx differ diff --git a/FOTF Toolbox/Simulink/c9mfpid2.slx b/FOTF Toolbox/Simulink/c9mfpid2.slx new file mode 100644 index 0000000..753bc4c Binary files /dev/null and b/FOTF Toolbox/Simulink/c9mfpid2.slx differ diff --git a/FOTF Toolbox/Simulink/c9mfpids.slx b/FOTF Toolbox/Simulink/c9mfpids.slx new file mode 100644 index 0000000..5ce0a6c Binary files /dev/null and b/FOTF Toolbox/Simulink/c9mfpids.slx differ diff --git a/FOTF Toolbox/Simulink/c9mimp3.slx b/FOTF Toolbox/Simulink/c9mimp3.slx new file mode 100644 index 0000000..aa77e97 Binary files /dev/null and b/FOTF Toolbox/Simulink/c9mimp3.slx differ diff --git a/FOTF Toolbox/Simulink/c9mplant.slx b/FOTF Toolbox/Simulink/c9mplant.slx new file mode 100644 index 0000000..47d3896 Binary files /dev/null and b/FOTF Toolbox/Simulink/c9mplant.slx differ diff --git a/FOTF Toolbox/Simulink/c9mvofuz.slx b/FOTF Toolbox/Simulink/c9mvofuz.slx new file mode 100644 index 0000000..6939905 Binary files /dev/null and b/FOTF Toolbox/Simulink/c9mvofuz.slx differ diff --git a/FOTF Toolbox/Simulink/c9mvofuz2.slx b/FOTF Toolbox/Simulink/c9mvofuz2.slx new file mode 100644 index 0000000..20d2f00 Binary files /dev/null and b/FOTF Toolbox/Simulink/c9mvofuz2.slx differ diff --git a/FOTF Toolbox/Simulink/fotflib.slx b/FOTF Toolbox/Simulink/fotflib.slx new file mode 100644 index 0000000..9fb6fcc Binary files /dev/null and b/FOTF Toolbox/Simulink/fotflib.slx differ diff --git a/FOTF Toolbox/Simulink/pidctrl_model.slx b/FOTF Toolbox/Simulink/pidctrl_model.slx new file mode 100644 index 0000000..8fa7df5 Binary files /dev/null and b/FOTF Toolbox/Simulink/pidctrl_model.slx differ diff --git a/FOTF Toolbox/aux_func.m b/FOTF Toolbox/aux_func.m new file mode 100644 index 0000000..a7df4b2 --- /dev/null +++ b/FOTF Toolbox/aux_func.m @@ -0,0 +1,18 @@ +function [T,dT,w,d2]=aux_func(t,y0,alpha,p) +% aux_func - auxilliary function, not recommended to call directly + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Created 28 March, 2017 +% Last Modified 18 May, 2022 + an=ceil(alpha); y0=y0(:); q=length(y0); d2=length(alpha); + m=length(t); g=double(genfunc(p)); + for i=1:d2, w(:,i)=get_vecw(alpha(i),m,g)'; end + b=y0./gamma(1:q)'; T=0; dT=zeros(m,d2); + for i=1:q, T=T+b(i)*t.^(i-1); end + for i=1:d2 + if an(i)==0, dT(:,i)=T; + elseif an(i)<q + for j=(an(i)+1):q + dT(:,i)=dT(:,i)+(t.^(j-1-alpha(i)))*... + b(j)*gamma(j)/gamma(j-alpha(i)); +end, end, end, end diff --git a/FOTF Toolbox/beta_c.m b/FOTF Toolbox/beta_c.m new file mode 100644 index 0000000..7a89da6 --- /dev/null +++ b/FOTF Toolbox/beta_c.m @@ -0,0 +1,16 @@ +function y=beta_c(z,m) +% gamma_c - beta function with complex arguments +% +% y=beta_c(z,m) +% +% z,m - the independent variable containing complex quantities +% y - the values of the Gamma function + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Created 28 March, 2017 +% Last Modified 18 May, 2022 + if isreal(z), y=beta(z,m); + else, f=@(t)t.^(z-1).*(1-t).^(m-1); + y=integral(f,0,1,'ArrayValued',true); + end +end diff --git a/FOTF Toolbox/c2exnls.m b/FOTF Toolbox/c2exnls.m new file mode 100644 index 0000000..5ffc939 --- /dev/null +++ b/FOTF Toolbox/c2exnls.m @@ -0,0 +1,12 @@ +function [c,ceq]=c2exnls(x) +% c2exnls - MATLAB function to describe an objective function in +% an example of the book, in Chapter 2 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Created 28 March, 2017 +% Last Modified 18 May, 2022 + c=[]; + ceq=[x(3)+9.625*x(1)*x(4)+16*x(2)*x(4)+16*x(4)^2+... + 12-4*x(1)-x(2)-78*x(4); + 16*x(1)*x(4)+44-19*x(1)-8*x(2)-x(3)-24*x(4)]; +end diff --git a/FOTF Toolbox/c7mbench5.m b/FOTF Toolbox/c7mbench5.m new file mode 100644 index 0000000..443960f --- /dev/null +++ b/FOTF Toolbox/c7mbench5.m @@ -0,0 +1,12 @@ +function y=c7mbench5(t,x,k) +% C7MBENCH the function describing Benchmark Problem 5 +% Copyright (c) Dingyu Xue, Northeastern University, China + +% Last Modified 18 May, 2022 + switch k + case 1 + y=(((x(2)-0.5)*(x(3)-0.3))^(1/5)+sqrt(t))/sqrt(pi); + case 2, y=(x(1)-1)*gamma(2.2); + case 3, y=(x(2)-0.5)*gamma(2.3)/gamma(2.2); + end +end diff --git a/FOTF Toolbox/c7mbench5a.m b/FOTF Toolbox/c7mbench5a.m new file mode 100644 index 0000000..4c22442 --- /dev/null +++ b/FOTF Toolbox/c7mbench5a.m @@ -0,0 +1,9 @@ +function y=c7mbench5a(t,x) +% C7MBENCHa the function describing Benchmark Problem 5a +% Copyright (c) Dingyu Xue, Northeastern University, China + +% Last Modified 18 May, 2022 + y=[(((x(2)-0.5)*(x(3)-0.3))^(1/5)+sqrt(t))/sqrt(pi); + (x(1)-1)*gamma(2.2); + (x(2)-0.5)*gamma(2.3)/gamma(2.2)]; +end \ No newline at end of file diff --git a/FOTF Toolbox/c7mchua.m b/FOTF Toolbox/c7mchua.m new file mode 100644 index 0000000..b666c59 --- /dev/null +++ b/FOTF Toolbox/c7mchua.m @@ -0,0 +1,14 @@ +function y=c7mchua(~,x,k) +% C7MCHUA the function describing fractional Chua circuit +% Copyright (c) Dingyu Xue, Northeastern University, China + +% Last Modified 18 May, 2022 + a=10.725; b=10.593; c=0.268; m0=-1.1726; m1=-0.7872; + switch k + case 1 + f=m1*x(1)+0.5*(m0-m1)*(abs(x(1)+1)-abs(x(1)-1)); + y=a*(x(2)-x(1)-f); + case 2, y=x(1)-x(2)+x(3); + case 3, y=-b*x(2)-c*x(3); + end +end diff --git a/FOTF Toolbox/c8mchaosd.m b/FOTF Toolbox/c8mchaosd.m new file mode 100644 index 0000000..451d115 --- /dev/null +++ b/FOTF Toolbox/c8mchaosd.m @@ -0,0 +1,10 @@ +function Y=c8mchaosd(u) +% c8mchaosd - MATLAB function to express the chaotic Chua system + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Created 28 March, 2017 +% Last Modified 18 May, 2022 + a=10.725; b=10.593; c=0.268; m0=-1.1726; m1=-0.7872; + f=m1*u(1)+1/2*(m0-m1)*(abs(u(1)+1)-abs(u(1)-1)); + Y=[a*(u(2)-u(1)-f); u(1)-u(2)+u(3); -b*u(2)-c*u(3)]; +end \ No newline at end of file diff --git a/FOTF Toolbox/c8mchua.m b/FOTF Toolbox/c8mchua.m new file mode 100644 index 0000000..6592e6a --- /dev/null +++ b/FOTF Toolbox/c8mchua.m @@ -0,0 +1,15 @@ +function y=c8mchua(~,x,k) +% c8mchua - MATLAB function to express the chaotic Chua system + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Created 28 March, 2017 +% Last Modified 18 May, 2022 + a=10.725; b=10.593; c=0.268; m0=-1.1726; m1=-0.7872; + switch k + case 1 + f=m1*x(1)+0.5*(m0-m1)*(abs(x(1)+1)-abs(x(1)-1)); + y=a*(x(2)-x(1)-f); + case 2, y=x(1)-x(2)+x(3); + case 3, y=-b*x(2)-c*x(3); + end +end diff --git a/FOTF Toolbox/c8mexp1x.m b/FOTF Toolbox/c8mexp1x.m new file mode 100644 index 0000000..9a59def --- /dev/null +++ b/FOTF Toolbox/c8mexp1x.m @@ -0,0 +1,13 @@ +function y=c8mexp1x(t,x,k) +% c8mexp1x - MATLAB function to express the nonlinear fractional-order +% differential equation + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last Modified 18 May, 2022 + if k<3, y=x(k+1); + else + y=-t^0.1*ml_func([1,1.545],-t)/ml_func([1,1.445],-t)... + *exp(t)*x(1)*x(2)+exp(-2*t)-x(3)^2; + end +end diff --git a/FOTF Toolbox/c8mexp2m.m b/FOTF Toolbox/c8mexp2m.m new file mode 100644 index 0000000..cadedd9 --- /dev/null +++ b/FOTF Toolbox/c8mexp2m.m @@ -0,0 +1,11 @@ +function y=c8mexp2m(t,x) +% c8mexp2m - MATLAB function to express the nonlinear fractional-order +% differential equation + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last Modified 18 May, 2022 + y3=-t^0.1*ml_func([1,1.545],-t)/ml_func([1,1.445],-t)... + *exp(t)*x(1)*x(2)+exp(-2*t)-x(3)^2; + y=[x(2); x(3); y3]; +end diff --git a/FOTF Toolbox/c8mfss2a.m b/FOTF Toolbox/c8mfss2a.m new file mode 100644 index 0000000..df1d8a8 --- /dev/null +++ b/FOTF Toolbox/c8mfss2a.m @@ -0,0 +1,10 @@ +function y=c8mfss2a(u) +% c8mfss2a - MATLAB function to express the fractional state space + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + y=[2/sqrt(pi)*(((u(2)-0.3)*(u(3)-0.5*u(1)))^(1/5)+sqrt(u(4))); + gamma(1.4)/gamma(1.3)*((u(1)-1)/2)^0.3; + gamma(3.1)/gamma(1.6)*sqrt((u(2)-0.3)^3)]; + y=real(y); %for unknown reason, tiny imaginary part involved +end diff --git a/FOTF Toolbox/c8mimpfs.m b/FOTF Toolbox/c8mimpfs.m new file mode 100644 index 0000000..fc96756 --- /dev/null +++ b/FOTF Toolbox/c8mimpfs.m @@ -0,0 +1,4 @@ +function y = c8mimpfs(t) + y=1/8*t*(ml_func([1,1.8],-t/2)*ml_func([1,1.2],-t/2)+... + ml_func([1,1.7],-t/2)*ml_func([1,1.3],-t/2)); +end diff --git a/FOTF Toolbox/c8mmlfs.m b/FOTF Toolbox/c8mmlfs.m new file mode 100644 index 0000000..2b34ca8 --- /dev/null +++ b/FOTF Toolbox/c8mmlfs.m @@ -0,0 +1,7 @@ +function y=c8mmlfs(t) +% c8mmlfs - MATLAB function to express the Simulink block + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + y=t^0.1*exp(t)*ml_func([1,1.545],-t)/ml_func([1,1.445],-t); +end diff --git a/FOTF Toolbox/c8mmlfs1.m b/FOTF Toolbox/c8mmlfs1.m new file mode 100644 index 0000000..f31f82f --- /dev/null +++ b/FOTF Toolbox/c8mmlfs1.m @@ -0,0 +1,7 @@ +function y = c8mmlfs1(u) +% c8mmlfs1 - MATLAB function to express the Simulink block + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + y = u^(1.5-sqrt(2))*exp(u)*ml_func([1,3-sqrt(2)],-u)./ml_func([1,1.5],-u); +end diff --git a/FOTF Toolbox/c8mnlssd.m b/FOTF Toolbox/c8mnlssd.m new file mode 100644 index 0000000..0fc613f --- /dev/null +++ b/FOTF Toolbox/c8mnlssd.m @@ -0,0 +1,9 @@ +function y=c8mnlssd(u) +% c8mnlssd - MATLAB function to express the Simulink block + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + y=[(((u(2)-0.5)*(u(3)-0.3))^(1/5)+sqrt(u(4)))/sqrt(pi); + (u(1)-1)*gamma(2.2); (u(2)-0.5)*gamma(2.3)/gamma(2.2)]; + y=real(y); %for unknown reasons, tiny imaginary part involved +end diff --git a/FOTF Toolbox/c8nleq.m b/FOTF Toolbox/c8nleq.m new file mode 100644 index 0000000..422df1e --- /dev/null +++ b/FOTF Toolbox/c8nleq.m @@ -0,0 +1,7 @@ +function x1=c8nleq(t,x) +% c8nleq - MATLAB function to express the nonlinear fractional-order +% differential equation + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +x1=[x(2:end); -t^0.1*ml_func([1,1.545],-t)/ml_func([1,1.445],-t)*exp(t)*x(1)*x(112)+exp(-2*t)-x(201)^2]; diff --git a/FOTF Toolbox/c9ef1.m b/FOTF Toolbox/c9ef1.m new file mode 100644 index 0000000..55e3984 --- /dev/null +++ b/FOTF Toolbox/c9ef1.m @@ -0,0 +1,7 @@ +function f=c9ef1(x), t=[0:0.01:20]'; +% c9ef1 - MATLAB function to express ISE criterion of the system + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +s=tf('s'); G=1/(s+1)^5; Gc=x(1)+x(2)/s+x(3)*s; +e=step(feedback(1,Gc*G),t); f=sum(e.^2)*(t(2)-t(1)); diff --git a/FOTF Toolbox/c9ef2.m b/FOTF Toolbox/c9ef2.m new file mode 100644 index 0000000..9159ac5 --- /dev/null +++ b/FOTF Toolbox/c9ef2.m @@ -0,0 +1,7 @@ +function f=c9ef2(x), t=[0:0.01:20]'; +% c9ef1 - MATLAB function to express ITAE criterion of the system + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +s=tf('s'); G=1/(s+1)^5; Gc=x(1)+x(2)/s+x(3)*s; +e=step(feedback(1,Gc*G),t); f=sum(t.*abs(e))*(t(2)-t(1)); diff --git a/FOTF Toolbox/c9ef3.m b/FOTF Toolbox/c9ef3.m new file mode 100644 index 0000000..ac9d547 --- /dev/null +++ b/FOTF Toolbox/c9ef3.m @@ -0,0 +1,7 @@ +function f=c9ef3(x), t=[0:0.01:20]'; +% c9ef1 - MATLAB function to express IAE criterion of the system + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +s=tf('s'); G=1/(s+1)^5; Gc=x(1)+x(2)/s+x(3)*s; +e=step(feedback(1,Gc*G),t); f=sum(abs(e))*(t(2)-t(1)); diff --git a/FOTF Toolbox/c9mbvp1.m b/FOTF Toolbox/c9mbvp1.m new file mode 100644 index 0000000..271e706 --- /dev/null +++ b/FOTF Toolbox/c9mbvp1.m @@ -0,0 +1,12 @@ +function y=c9mbvp1(x) +% c9mbvp1 - MATLAB function to boundary value problem + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + W=get_param(gcs,'ModelWorkspace'); assignin(W,'a',x) + try + txy=sim('bp6_model.slx'); y0=txy.yout; + y=abs(y0(end)-exp(-2)); + catch, y=10; + end +end diff --git a/FOTF Toolbox/c9mbvp1a.m b/FOTF Toolbox/c9mbvp1a.m new file mode 100644 index 0000000..da9fe09 --- /dev/null +++ b/FOTF Toolbox/c9mbvp1a.m @@ -0,0 +1,11 @@ +function y=c9mbvp1a(x) +% c9mbvp1a - MATLAB function to boundary value problem + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + W=get_param(gcs,'ModelWorkspace'); assignin(W,'a',x) + try + txy=sim('bp6_model.slx'); y0=txy.yout; y=y0(end)-exp(-2); + catch, y=10; + end +end diff --git a/FOTF Toolbox/c9mbvp2.m b/FOTF Toolbox/c9mbvp2.m new file mode 100644 index 0000000..70659d0 --- /dev/null +++ b/FOTF Toolbox/c9mbvp2.m @@ -0,0 +1,13 @@ +function y=c9mbvp2(x) +% c9mbvp2 - MATLAB function to boundary value problem + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + W=get_param(gcs,'ModelWorkspace'); + assignin(W,'b',x(1)), assignin(W,'a',x(2)) + try + txy=sim('bp6a_model.slx'); y0=txy.yout; + y=abs(y0(end,1)-exp(-2))+abs(y0(end,2)-y0(1,1)+exp(-2)+1); + catch, y=10; + end +end \ No newline at end of file diff --git a/FOTF Toolbox/c9mbvp2a.m b/FOTF Toolbox/c9mbvp2a.m new file mode 100644 index 0000000..a3b8de4 --- /dev/null +++ b/FOTF Toolbox/c9mbvp2a.m @@ -0,0 +1,13 @@ +function y=c9mbvp2a(x) +% c9mbvp2a - MATLAB function to boundary value problem + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + W=get_param(gcs,'ModelWorkspace'); + assignin(W,'b',x(1)), assignin(W,'a',x(2)) + try + txy=sim('bp6a_model.slx'); y0=txy.yout; + y=[y0(end,1)-exp(-2); y0(end,2)-y0(1,1)+exp(-2)+1]; + catch, y=[10; 10]; + end +end \ No newline at end of file diff --git a/FOTF Toolbox/c9mbvp3.m b/FOTF Toolbox/c9mbvp3.m new file mode 100644 index 0000000..95a2cf3 --- /dev/null +++ b/FOTF Toolbox/c9mbvp3.m @@ -0,0 +1,13 @@ +function y=c9mbvp3(x) +% c9mbvp3 - MATLAB function to boundary value problem + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + W=get_param(gcs,'ModelWorkspace'); + assignin(W,'b',x(1)), assignin(W,'a',x(2)) + try + txy=sim('bp7a_model.slx'); y0=txy.yout; + y=[y0(end,1)-exp(-2); y0(end,2)+0.5*exp(-2)]; + catch, y=[10; 10]; + end +end diff --git a/FOTF Toolbox/c9mfpid.m b/FOTF Toolbox/c9mfpid.m new file mode 100644 index 0000000..a28cb94 --- /dev/null +++ b/FOTF Toolbox/c9mfpid.m @@ -0,0 +1,9 @@ +function feq=c9mfpid(x,wcg,phi,ws,B,wt,A,k,T,L) +jw=1i*wcg; G=@(s)k*exp(-L*s)/(T*s+1); +C=@(s)x(1)+x(2)/s^x(4)+x(3)*s^x(5); +F=@(s)C(s)*G(s); feq(1)=abs(F(jw))-1; +feq(2)=angle(F(jw))+pi-phi*pi/180; +feq(3)=angle(-(T/(T*jw+1)+L)*F(jw)-... + G(jw)*(x(2)*x(4)/jw^(x(4)+1)-x(3)*x(5)*jw^(x(5)-1))); +feq(4)=20*log10(abs(1/(1+F(ws*1i))))-B; +feq(5)=20*log10(abs(F(wt*1i)/(1+F(wt*1i))))-A; diff --git a/FOTF Toolbox/c9mfpid_con.m b/FOTF Toolbox/c9mfpid_con.m new file mode 100644 index 0000000..c06528f --- /dev/null +++ b/FOTF Toolbox/c9mfpid_con.m @@ -0,0 +1,6 @@ +function [c,ceq]=c9mfpid_con(x,wcg,phi,ws,B,wt,A,k,T,L) +jw=1i*wcg; G=@(s)k*exp(-L*s)/(T*s+1); +C=@(s)x(1)+x(2)/s^x(4)+x(3)*s^x(5); F=@(s)C(s)*G(s); +ceq=[abs(F(jw))-1; angle(F(jw))+pi-phi*pi/180]; +c=[20*log10(abs(1/(1+F(ws*1i))))-B; + 20*log10(abs(F(wt*1i)/(1+F(wt*1i))))-A]; diff --git a/FOTF Toolbox/c9mfpid_con1.m b/FOTF Toolbox/c9mfpid_con1.m new file mode 100644 index 0000000..8be3468 --- /dev/null +++ b/FOTF Toolbox/c9mfpid_con1.m @@ -0,0 +1,6 @@ +function [c,ceq]=c9mfpid_con1(x,wcg,phi,ws,B,wt,A,k,T,L) +jw=1i*wcg; G=@(s)k*exp(-L*s)/s/(T*s+1); +C=@(s)x(1)+x(2)/s^x(4)+x(3)*s^x(5); F=@(s)C(s)*G(s); +ceq=[abs(F(jw))-1; angle(F(jw))+pi-phi*pi/180]; +c=[20*log10(abs(1/(1+F(ws*1i))))-B; + 20*log10(abs(F(wt*1i)/(1+F(wt*1i))))-A]; diff --git a/FOTF Toolbox/c9mfpid_con2.m b/FOTF Toolbox/c9mfpid_con2.m new file mode 100644 index 0000000..a0be0ed --- /dev/null +++ b/FOTF Toolbox/c9mfpid_con2.m @@ -0,0 +1,6 @@ +function [c,ceq]=c9mfpid_con2(x,wcg,phi,ws,B,wt,A,k,T,L,a) +jw=1i*wcg; G=@(s)k*exp(-L*s)/(T*s^2+1); +C=@(s)x(1)+x(2)/s^x(4)+x(3)*s^x(5); F=@(s)C(s)*G(s); +ceq=[abs(F(jw))-1; angle(F(jw))+pi-phi*pi/180]; +c=[20*log10(abs(1/(1+F(ws*1i))))-B; + 20*log10(abs(F(wt*1i)/(1+F(wt*1i))))-A]; diff --git a/FOTF Toolbox/c9mfpid_conw.m b/FOTF Toolbox/c9mfpid_conw.m new file mode 100644 index 0000000..a937db2 --- /dev/null +++ b/FOTF Toolbox/c9mfpid_conw.m @@ -0,0 +1,7 @@ +function [c,ceq]=c9mfpid_conw(x,ww,wcg,phi,ws,B,wt,A,k,tau,L) +jw=1i*wcg; G=@(s)k*exp(-L*s)/(tau*s+1); +C=@(s)x(1)+x(2)/s^x(4)+x(3)*s^x(5); F=@(s)C(s)*G(s); +ceq=[abs(F(jw))-1; + angle(F(jw))+pi-phi*pi/180]; +c=[20*log10(abs(1/(1+F(ws*1i))))-B; + 20*log10(abs(F(wt*1i)/(1+F(wt*1i))))-A]; diff --git a/FOTF Toolbox/c9mfpid_opt.m b/FOTF Toolbox/c9mfpid_opt.m new file mode 100644 index 0000000..34f298c --- /dev/null +++ b/FOTF Toolbox/c9mfpid_opt.m @@ -0,0 +1,5 @@ +function y=c9mfpid_opt(x,wcg,phi,ws,B,wt,A,k,T,L) +jw=1i*wcg; G=@(s)k*exp(-L*s)/(T*s+1); +C=@(s)x(1)+x(2)/s^x(4)+x(3)*s^x(5); F=@(s)C(s)*G(s); +y=abs(angle(-(T/(T*jw+L)+L)*F(jw)-... + G(jw)*(x(2)*x(4)/jw^(x(4)+1)-x(3)*x(5)*jw^(x(5)-1)))); diff --git a/FOTF Toolbox/c9mfpid_opt1.m b/FOTF Toolbox/c9mfpid_opt1.m new file mode 100644 index 0000000..4549ab0 --- /dev/null +++ b/FOTF Toolbox/c9mfpid_opt1.m @@ -0,0 +1,5 @@ +function y=c9mfpid_opt1(x,wcg,phi,ws,B,wt,A,k,T,L) +s=1i*wcg; G=@(s)k*exp(-L*s)/s/(T*s+1); +C=@(s)x(1)+x(2)/s^x(4)+x(3)*s^x(5); F=@(s)C(s)*G(s); +y=abs(angle(-(L*s+2*T*s+L*T*s^2+1)/(T*s^2+s)*F(s)-... + G(s)*(x(2)*x(4)/s^(x(4)+1)-x(3)*x(5)*s^(x(5)-1)))); diff --git a/FOTF Toolbox/c9mfpid_opt2.m b/FOTF Toolbox/c9mfpid_opt2.m new file mode 100644 index 0000000..98229de --- /dev/null +++ b/FOTF Toolbox/c9mfpid_opt2.m @@ -0,0 +1,5 @@ +function y=c9mfpid_opt2(x,wcg,phi,ws,B,wt,A,k,T,L,a) +s=1i*wcg; G=@(s)k*exp(-L*s)/(T*s^a+1); +C=@(s)x(1)+x(2)/s^x(4)+x(3)*s^x(5); F=@(s)C(s)*G(s); +y=abs(angle(-(L*s+a*s^a*T+L*s^a+1)*T)/(s*(s^a*T+1)*F(s)-... + G(s)*(x(2)*x(4)/s^(x(4)+1)-x(3)*x(5)*s^(x(5)-1)))); diff --git a/FOTF Toolbox/c9mfpid_optw.m b/FOTF Toolbox/c9mfpid_optw.m new file mode 100644 index 0000000..0a035ef --- /dev/null +++ b/FOTF Toolbox/c9mfpid_optw.m @@ -0,0 +1,6 @@ +function y=c9mfpid_optw(x,ww,wcg,phi,ws,B,wt,A,k,tau,L) +jw=1i*ww; G=@(s)k*exp(-L*s)./(tau*s+1); +C=@(s)x(1)+x(2)./s.^x(4)+x(3)*s.^x(5); F=@(s)C(s).*G(s); +y=abs(angle(-(tau./(tau*jw+1)+L).*F(jw)-... + G(jw).*(x(2)*x(4)./jw.^(x(4)+1)-x(3)*x(5)*jw.^(x(5)-1)))); +y=sum(y); diff --git a/FOTF Toolbox/caputo.m b/FOTF Toolbox/caputo.m new file mode 100644 index 0000000..90b3fa7 --- /dev/null +++ b/FOTF Toolbox/caputo.m @@ -0,0 +1,23 @@ +function dy=caputo(y,t,gam,y0,L) +% caputo - O(h) Caputo derivative computation function +% +% dy=caputo(y,t,alfa,y0,L) +% +% y - the samples or function handle of the original function +% t - the time vector +% alpha - the fractional order +% y0 - the initial vector of signal and its integer-order derivatives +% L0 - the interpolation length +% dy - the Caputo derivative + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last Modified 18 May, 2022 + arguments, y(:,1), t(:,1), gam(1,1), y0, L(1,1)=10, end + dy=glfdiff(y,t,gam); + if gam>0, q=ceil(gam); if gam<=1, y0=y(1); end + for k=0:q-1, dy=dy-y0(k+1)*t.^(k-gam)./gamma(k+1-gam); end + yy1=interp1(t(L+1:end),dy(L+1:end),t(1:L),'spline'); + dy(1:L)=yy1; + end +end diff --git a/FOTF Toolbox/caputo9.m b/FOTF Toolbox/caputo9.m new file mode 100644 index 0000000..b762b06 --- /dev/null +++ b/FOTF Toolbox/caputo9.m @@ -0,0 +1,29 @@ +function dy=caputo9(y,t,gam,p) +% caputo9 - O(h^p) Caputo derivative computation function +% +% dy=caputo9(y,t,gam,p) +% +% y - the samples or function handle of the original function +% t - the time vector +% gam - the fractional order +% p - the order for precision +% dy - the Caputo derivative + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last Modified 18 May, 2022 + arguments, y(:,1), t(:,1) double, gam(1,1) double + p(1,1) {mustBePositiveInteger}=5 + end + if strcmp(class(y),'function_handle'), y=y(t); end + if gam<0, dy=glfdiff9(y,t,gam,p); return; end + h=t(2)-t(1); q=ceil(gam); + r=max(p,q); R=fliplr(vander((sym(0):(r-1))'*h)); + c=double(R\y(1:r)); u=0; du=0; + for i=1:r, u=u+c(i)*t.^(i-1); end + if q<r + for i=(q+1):p + du=du+c(i)*t.^(i-1-gam)*gamma(i)/gamma(i-gam); + end, end + v=y-u; dv=glfdiff9(v,t,gam,p); dy=dv+du; +end diff --git a/FOTF Toolbox/caputo_ics.m b/FOTF Toolbox/caputo_ics.m new file mode 100644 index 0000000..e305ca1 --- /dev/null +++ b/FOTF Toolbox/caputo_ics.m @@ -0,0 +1,20 @@ +function [c,y]=caputo_ics(a,na,b,nb,y0,u,t) +% caputo_ics - quivalent initial condition reconstruction, called by fode_caputo9 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last Modified 18 May, 2022 + arguments, a(1,:), na(1,:), b(1,:), nb(1,:) + y0(:,1), u(:,1), t(:,1) + end + na1=ceil(na); q=max(na1); K=length(t); + p=K+q-1; d1=y0./gamma(1:q)'; + I1=1:q; I2=(q+1):p; X=zeros(K,p); + for i=1:p, for k=1:length(a) + if i>na1(k) + X(:,i)=X(:,i)+a(k)*t.^(i-1-na(k))*gamma(i)/gamma(i-na(k)); + end, end, end + u1=0; for i=1:length(b), u1=u1+b(i)*caputo9(u,t,nb(i),K-1); end + X(1,:)=[]; u2=u1(2:end)-X(:,I1)*d1; d2=X(:,I2)\u2; + c=[d1;d2]; y=0; for i=1:p, y=y+c(i)*t.^(i-1); end +end diff --git a/FOTF Toolbox/caputosym.m b/FOTF Toolbox/caputosym.m new file mode 100644 index 0000000..f0279a9 --- /dev/null +++ b/FOTF Toolbox/caputosym.m @@ -0,0 +1,22 @@ +function dy=caputosym(f,alpha,t0,t) +%caputosym evaluates symbolically Caputo derivatives +% +% dy=caputosym(f,alpha,t0,t) +% +% f - symbolic expression or symbolic function +% alpha - fractional order, must be a symbolic number +% t0 - initial time, default of 0 +% t - final time, woth default of symbolic t + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + arguments, f(1,1), alpha(1,1), t0(1,1)=0, t(1,1)=symvar(f), end + if alpha<=0, dy=riemannsym(f,alpha,t0,t); return; end + syms tau; alpha=sym(alpha); m=ceil(alpha); gam=m-alpha; + switch class(f) + case 'sym', F=diff(subs(f,t,tau),m); + case 'symfun', F=diff(f(tau),m); + otherwise, error('f must be a symbolic expression') + end + dy=1/gamma(gam)*int(F/(t-tau)^(1-gam),tau,t0,t); +end diff --git a/FOTF Toolbox/carlson_fod.m b/FOTF Toolbox/carlson_fod.m new file mode 100644 index 0000000..bf047d2 --- /dev/null +++ b/FOTF Toolbox/carlson_fod.m @@ -0,0 +1,22 @@ +function H=carlson_fod(alpha,G,iter,epsx) +% carlson_fod - design function for the Carlson filter +% +% H=carlson_fod(alpha,G,iter) +% +% alpha - the fractional order +% G - the integer-order model +% iter - the number of iterations +% H - the Carlson filter such that H approx G^alpha + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last Modified 18 May, 2022 + arguments + alpha(1,1) double, G(1,1) + iter(1,1) {mustBePositiveInteger}, epsx(1,1)=eps; + end + q=alpha; m=q/2; H=1; + for i=1:iter + H=minreal(H*((q-m)*H^2+(q+m)*G)/((q+m)*H^2+(q-m)*G),epsx); + end +end diff --git a/FOTF Toolbox/charef_fod.m b/FOTF Toolbox/charef_fod.m new file mode 100644 index 0000000..e47832c --- /dev/null +++ b/FOTF Toolbox/charef_fod.m @@ -0,0 +1,22 @@ +function G=charef_fod(alpha,pT,delta,wM) +% charef_fod - design function for the Charef filter +% +% H=charef_fod(alpha,pT,delta,wM) +% +% alpha - the fractional order +% pT - the turning frequency +% delta - the error tolerance in dBs +% wM - maximum frequency +% H - the Charef filter designed + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last Modified 18 May, 2022 + arguments + alpha(1,1)double, pT(1,1)double, delta(1,1)double, wM(1,1)double + end + p0=pT*10^(delta/20/alpha); + a=10^(delta/10/(1-alpha)); b=10^(delta/10/alpha); + n=ceil(log(wM/p0)/log(a*b)); ii=1:n; p=p0*(a*b).^ii; + p=[p0 p]; z=a*p(1:n); K=prod(p)/prod(z); G=zpk(-z,-p,K); +end diff --git a/FOTF Toolbox/charef_opt.m b/FOTF Toolbox/charef_opt.m new file mode 100644 index 0000000..85dd094 --- /dev/null +++ b/FOTF Toolbox/charef_opt.m @@ -0,0 +1,39 @@ +function Ga=charef_opt(wr,n,G,wt,a,wc) +% charef_opt - design function for the optimum Charef filter +% +% Ga=charef_opt(wr,n,G,wt,a,wc) +% +% wr - the selected frequency vector +% n - the order of the filter +% G - the frequency response data for the irrational system model +% wt - weighting for the four terms in the formula +% a, wc - reference parameters for the filter design process +% Ga - the optimum Charef filter designed + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, wr(:,1), n(1,1){mustBeInteger, mustBePositive} + G(:,1), wt(1,4)=[1 1 1 1], a(1,1)=0.5, wc(1,1)=1 + end + e=1; x0(1)=10^(e/(10*a*(1-a))); + x0(2)=10^(e/(20*(1-a)))*wc*10^(e/(20*a)); + x0(3:n+3)=ones(1,n+1)/10^(e/(20*(1-a))); + ff=optimset; ff.Display='iter'; A=[];B=[];Aeq=[];Beq=[];CF=[]; + xm=[1 0 zeros(1,n+1)]; xM=[3 10 ones(1,n+1)]; + x1=fmincon(@charef_obj,x0,A,B,Aeq,Beq,xm,xM,CF,ff,wr,G,wt); + c=x1(1); wu0=x1(2); wu=wu0*c.^[0:n]; p=wu.*x1(3:end); + z=wu.^2./p; k=prod(p)/prod(z); Ga=zpk(-z',-p',k); +end +% 计算目标函数值的子函数 +function f=charef_obj(x,wr,G,wt) + n=length(x)-2; + c=x(1); wu0=x(2); wu=wu0*c.^(0:(n-1)); p=wu.*x(3:end); + z=wu.^2./p; k=prod(p)/prod(z); Ga=zpk(-z',-p',k); + Ga1=frd(Ga,wr); h=Ga1.ResponseData; Ga_fr=h(:); + f=wt(1)*norm(abs(angle(Ga_fr)-angle(G)),inf)+... + wt(2)*sum(abs(angle(Ga_fr)-angle(G)))/length(wr)+... + wt(3)*norm(abs(abs(Ga_fr)-abs(G)),inf)+... + wt(4)*sum(abs(abs(Ga_fr)-abs(G)))/length(wr); +end + diff --git a/FOTF Toolbox/common_order.m b/FOTF Toolbox/common_order.m new file mode 100644 index 0000000..85d4c62 --- /dev/null +++ b/FOTF Toolbox/common_order.m @@ -0,0 +1,12 @@ +function a=common_order(varargin) +% common_order - extract the common order from a set of orders +% +% a=common_order(a1,a2,a3,...) +% +% a1, a2, a3,... - the given set of orders +% a - the common order + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +a0=cell2mat(varargin); [c,d]=rat(a0,1e-20); +a=double(gcd(sym(c))/lcm(sym(d))); diff --git a/FOTF Toolbox/contfrac.m b/FOTF Toolbox/contfrac.m new file mode 100644 index 0000000..bac3904 --- /dev/null +++ b/FOTF Toolbox/contfrac.m @@ -0,0 +1,21 @@ +function [F,r]=contfrac(f,s,n,a) +% contfrac - the interface to the MuPAD function contfrac +% +% [cf,r]=contfrac(f,s,n,a) +% +% f - the symbolic expression of the original function +% s - the independent variable +% n - the approximation order of continued fractions +% a - the reference point +% cf - the symbolic expression of the continued fraction +% r - the symbolic expression of the rational form + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 28 March, 2017 +% Not recommended for the less support of MuPAD contfrac function + arguments, f(1,1), s(1,1), n(1,1), a(1,1), end + F=feval(symengine,'contfrac',f,[inputname(2) '=' num2str(a)],n); + if nargout==2 + r=feval(symengine,'contfrac::rational',F); +end, end diff --git a/FOTF Toolbox/contfrac0.m b/FOTF Toolbox/contfrac0.m new file mode 100644 index 0000000..8f491bf --- /dev/null +++ b/FOTF Toolbox/contfrac0.m @@ -0,0 +1,18 @@ +function [cf,r]=contfrac0(f,s,n,a) +% contfrac0 - the interface to the MuPAD function contfrac +% +% [cf,r]=contfrac0(f,s,n,a) +% +% f - the symbolic expression of the original function +% s - the independent variable +% n - the approximation order of continued fractions +% a - the reference point +% cf - the symbolic expression of the continued fraction +% r - the symbolic expression of the rational form + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +cf=feval(symengine,'contfrac',f,[inputname(2) '=' num2str(a)],n); +if nargout==2 + r=feval(symengine,'contfrac::rational',cf); +end diff --git a/FOTF Toolbox/cotf2fotf.m b/FOTF Toolbox/cotf2fotf.m new file mode 100644 index 0000000..268fb56 --- /dev/null +++ b/FOTF Toolbox/cotf2fotf.m @@ -0,0 +1,16 @@ +function G1=cotf2fotf(G,alpha) +% cotf2fotf - commensurate order TF to FOTF object conversion +% +% G1=cotf2fotf(G,alpha) +% +% G - the integer-order TF to describe the commensurate-order system +% alpha - the base order +% G1 - the converted 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(G); + for i=1:n, for j=1:m, g=fotf(G(i,j)); + g.num.na=g.num.na*alpha; g.den.na=g.den.na*alpha; G1(i,j)=g; +end, end, end diff --git a/FOTF Toolbox/default_vals.m b/FOTF Toolbox/default_vals.m new file mode 100644 index 0000000..227e770 --- /dev/null +++ b/FOTF Toolbox/default_vals.m @@ -0,0 +1,6 @@ +function varargout=default_vals(vals,varargin) +%no longer used in the new version +if nargout~=length(vals), error('number of arguments mismatch'); +else, nn=length(varargin)+1; + varargout=varargin; for i=nn:nargout, varargout{i}=vals{i}; +end, end, end \ No newline at end of file diff --git a/FOTF Toolbox/demos.xml b/FOTF Toolbox/demos.xml new file mode 100644 index 0000000..02c99c2 --- /dev/null +++ b/FOTF Toolbox/demos.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<demos><!--此文件是自动生成的,请不要修改--> + <name>FOTF Toolbox</name> + <type>toolbox</type> + <icon>HelpIcon.DEMOS</icon> + <website/> + <description>Updated version of FOTF Toolbox +Dedicated to the Tsinghua University Press book, cite as. +Xue D Y and Bai L. Fractional Calculus: Numerical Algorithms and Implementations. Beijing: Tsinghua University Press, 2022 + +Run fotfpath after installation to set Simulink model path</description> + <demosection> + <label>demo</label> + <demoitem> + <label>fminsearchbnd_demo</label> + <type>other</type> + <source>fminsearchbnd_demo</source> + <file>fminsearchbnd/demo/html/fminsearchbnd_demo.html</file> + </demoitem> + </demosection> +</demos> \ No newline at end of file diff --git a/FOTF Toolbox/dfod2.m b/FOTF Toolbox/dfod2.m new file mode 100644 index 0000000..bbb7690 --- /dev/null +++ b/FOTF Toolbox/dfod2.m @@ -0,0 +1,18 @@ +function H=dfod2(n,T,r) +% DFOD2 - discrete implementation of s^r +% +% H=dfod2(n,T,r) +% +% n - filter order +% T - sample time +% r - fractional order +% modified directly from Petras function, under the same name + arguments + n(1,1) {mustBePositiveInteger} + T(1,1) {mustBePositive}, r(1,1) double + end + if r>0 + bc=cumprod([1,1-((r+1)./[1:n])]); H=filt(bc,T^r,T); + elseif r<0 + bc=cumprod([1,1-((-r+1)./[1:n])]); H=filt(T^(-r),bc,T); +end, end diff --git a/FOTF Toolbox/fdcoef.m b/FOTF Toolbox/fdcoef.m new file mode 100644 index 0000000..4d8a2a3 --- /dev/null +++ b/FOTF Toolbox/fdcoef.m @@ -0,0 +1,28 @@ +function [coefs,del]=fdcoef(m,p,alpha,t0) +% fdcoef - for computing finite difference coefficients +% see my book Vol2 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 16 December, 2019 +% Last modified 18 May, 2022 + arguments + m(1,1){mustBePositiveInteger}, p(1,1){mustBePositiveInteger} + alpha(1,:) {mustBeInteger}, t0(1,1){mustBeInteger}=0 + end + m=m+1; del=sym(zeros(m,p,p)); del(1,1,1)=1; + c1=1; nm=min(p,m); + for n=2:p, c2=1; + for nu=1:n-1 + c3=alpha(n)-alpha(nu); c2=c2*c3; c4=1/c3; + a0=alpha(n)-t0; del(1,n,nu)=c4*(a0*del(1,n-1,nu)); + for M=2:nm + del(M,n,nu)=c4*(a0*del(M,n-1,nu)-(M-1)*del(M-1,n-1,nu)); + end, end + a0=(alpha(n-1)-t0); + del(1,n,n)=c1/c2*(-a0*del(1,n-1,n-1)); c4=c1/c2; + for M=2:nm + del(M,n,n)=c4*((M-1)*del(M-1,n-1,n-1)-a0*del(M,n-1,n-1)); + end, c1=c2; + end + coefs=del(m,p,:); coefs=coefs(:).'; +end diff --git a/FOTF Toolbox/fdiffcom.m b/FOTF Toolbox/fdiffcom.m new file mode 100644 index 0000000..50172d8 --- /dev/null +++ b/FOTF Toolbox/fdiffcom.m @@ -0,0 +1,8 @@ +function [y,h,n]=fdiffcom(f,t) +% commonly used file by many fractional differentiators + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + y=f; if strcmp(class(f),'function_handle'), y=f(t); end + h=t(2)-t(1); n=length(t); +end diff --git a/FOTF Toolbox/feedbacksym.m b/FOTF Toolbox/feedbacksym.m new file mode 100644 index 0000000..e4b47b3 --- /dev/null +++ b/FOTF Toolbox/feedbacksym.m @@ -0,0 +1,12 @@ +function H=feedbacksym(G1,G2,key) +% feedbacksym finds the closed-form transfer function matrix + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + arguments, G1, G2, key(1,1)=-1; end + G01=G1*G2; G02=G2*G1; [n1,m1]=size(G01); [n2,m2]=size(G02); + if n1~=m1 || n2~=m2, error('Model sizes are incompatible'), end + if n1<n2, H=inv(eye(n1)-key*G1*G2)*G1; + else, H=G1*inv(eye(n1)-key*G2*G1); end + if isa(H,'sym'), H=simplify(H); else, H=minreal(H); end +end diff --git a/FOTF Toolbox/fence_shadow.m b/FOTF Toolbox/fence_shadow.m new file mode 100644 index 0000000..a326d0c --- /dev/null +++ b/FOTF Toolbox/fence_shadow.m @@ -0,0 +1,32 @@ +function fence_shadow(t,f,gam,key) +% fence_shadow - geometric interpretation of the fractional-order integrals +% +% fence_shadow(t,f,gam,key) +% +% t - the tine vector +% f - the function handle of the original function +% gam - the integral order +% key - the three types of graphs, as in Igor Podlubny's paper + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, t(1,:), f, gam(1,1) double + key(1,1) {mustBeMember(key,[1,2,3])}; + end + x=t; z=f(x); tn=x(end); + switch key + case 1, y=(tn^gam-(tn-x).^gam)/gamma(1+gam); + axis([minmax(x),minmax(y),minmax(z)]), hold on + for i=1:length(x)-1, ii=[i,i,i+1,i+1]; x0=x(ii); + z0=[0 z(i:i+1) 0]; y0=[0 0 0 0]; patch(x0,y0,z0,'c') + y0=y(ii); patch(x0,y0,z0,'g') + x0=[0 0 0 0]; patch(x0,y0,z0,'r') + end, view(-37.5000,30) + case {2,3}, axis([minmax(x),minmax(z)]), hold on + for i=1:length(x)-1, x1=0:0.01:x(i+1); + tn=x1(end); y=(tn^gam-(tn-x1).^gam)/gamma(1+gam); + if key==2, plot(x1,y); + else, z=f(x1); plot(y,z,[y(end),y(end)],[z(end),0]); + end, end, end, hold off +end diff --git a/FOTF Toolbox/ffuz_param.m b/FOTF Toolbox/ffuz_param.m new file mode 100644 index 0000000..1b9f85b --- /dev/null +++ b/FOTF Toolbox/ffuz_param.m @@ -0,0 +1,29 @@ +function [sys,x0,str,ts]=ffuz_param(t,x,u,flag,T,fuz,K0) +% ffuz_param - S-function of the fuzzy inference system + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +switch flag + case 0, [sys,x0,str,ts] = mdlInitializeSizes(T); + case 2, sys = mdlUpdates(x,u); + case 3, sys = mdlOutputs(x,u,fuz,K0); + case {1, 4, 9}, sys = []; + otherwise, error(['Unhandled flag=',num2str(flag)]); +end +function [sys,x0,str,ts]=mdlInitializeSizes(T) +sizes=simsizes; +sizes.NumContStates=0; sizes.NumDiscStates=2; +sizes.NumOutputs=5; sizes.NumInputs=1; +sizes.DirFeedthrough=0; sizes.NumSampleTimes=1; +sys=simsizes(sizes); x0=zeros(2,1); str=[]; ts=[T 0]; +% +function sys = mdlUpdates(x,u) +sys=[u(1); u(1)-x(1)]; +% +function sys = mdlOutputs(x,u,fuz,K0) +Kfpid=K0+evalfis([x(1),x(2)],fuz)'; +assignin('base','Kp',Kfpid(1)); +assignin('base','Ki',Kfpid(2)); +assignin('base','Kd',Kfpid(3)); +assignin('base','lam',Kfpid(4)); +assignin('base','mu0',Kfpid(5)); sys=Kfpid; diff --git a/FOTF Toolbox/fmincon_global.m b/FOTF Toolbox/fmincon_global.m new file mode 100644 index 0000000..e282e71 --- /dev/null +++ b/FOTF Toolbox/fmincon_global.m @@ -0,0 +1,19 @@ +function [x,f0]=fmincon_global(f,a,b,n,N,varargin), f0=Inf; +% fmincon_global - a possible global solver for constrained optimization problems +% +% [x,f0]=fmincon_global(f,a,b,n,N,varargin) +% +% f - the objective function +% (a,b) - the interval for the decision variables +% n - the number of decision variables +% N - the number of runs of fmincon function +% x, f0 - the optimal decision variable and objective function + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + for i=1:N + x0=a+(b-a).*rand(n,1); [x1,f1,key]=fmincon(f,x0,varargin{:}); + if key>0 && f1<f0, x=x1; f0=f1; end + end +end diff --git a/FOTF Toolbox/fminsearchbnd/demo/fminsearchbnd_demo.m b/FOTF Toolbox/fminsearchbnd/demo/fminsearchbnd_demo.m new file mode 100644 index 0000000..53623ab --- /dev/null +++ b/FOTF Toolbox/fminsearchbnd/demo/fminsearchbnd_demo.m @@ -0,0 +1,47 @@ +%% Optimization of a simple (Rosenbrock) function, with no constraints +rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2; + +% With no constraints, operation simply passes through +% directly to fminsearch. The solution should be [1 1] +xsol = fminsearchbnd(rosen,[3 3]) + +%% Only lower bound constraints +xsol = fminsearchbnd(rosen,[3 3],[2 2]) + +%% Only upper bound constraints +xsol = fminsearchbnd(rosen,[-5 -5],[],[0 0]) + +%% Dual constraints +xsol = fminsearchbnd(rosen,[2.5 2.5],[2 2],[3 3]) + +%% Mixed constraints +xsol = fminsearchbnd(rosen,[0 0],[2 -inf],[inf 3]) + +%% Provide your own fminsearch options +opts = optimset('fminsearch'); +opts.Display = 'iter'; +opts.TolX = 1.e-12; +opts.MaxFunEvals = 100; + +n = [10,5]; +H = randn(n); +H=H'*H; +Quadraticfun = @(x) x*H*x'; + +% Global minimizer is at [0 0 0 0 0]. +% Set all lower bound constraints, all of which will +% be active in this test. +LB = [.5 .5 .5 .5 .5]; +xsol = fminsearchbnd(Quadraticfun,[1 2 3 4 5],LB,[],opts) + +%% Exactly fix one variable, constrain some others, and set a tolerance +opts = optimset('fminsearch'); +opts.TolFun = 1.e-12; + +LB = [-inf 2 1 -10]; +UB = [ inf inf 1 inf]; +xsol = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB,opts) + +%% All the standard outputs from fminsearch are still returned +[xsol,fval,exitflag,output] = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB) + diff --git a/FOTF Toolbox/fminsearchbnd/demo/html/fminsearchbnd_demo.html b/FOTF Toolbox/fminsearchbnd/demo/html/fminsearchbnd_demo.html new file mode 100644 index 0000000..86fb926 --- /dev/null +++ b/FOTF Toolbox/fminsearchbnd/demo/html/fminsearchbnd_demo.html @@ -0,0 +1,299 @@ +<html xmlns:mwsh="http://www.mathworks.com/namespace/mcode/v1/syntaxhighlight.dtd"> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + + <!-- +This HTML is auto-generated from an M-file. +To make changes, update the M-file and republish this document. + --> + <title>fminsearchbnd_demo</title> + <meta name="generator" content="MATLAB 7.0.1"> + <meta name="date" content="2006-07-24"> + <meta name="m-file" content="fminsearchbnd_demo"><style> +body { + background-color: white; + margin:10px; +} +h1 { + color: #990000; + font-size: x-large; +} +h2 { + color: #990000; + font-size: medium; +} +p.footer { + text-align: right; + font-size: xx-small; + font-weight: lighter; + font-style: italic; + color: gray; +} + +pre.codeinput { + margin-left: 30px; +} + +span.keyword {color: #0000FF} +span.comment {color: #228B22} +span.string {color: #A020F0} +span.untermstring {color: #B20000} +span.syscmd {color: #B28C00} + +pre.showbuttons { + margin-left: 30px; + border: solid black 2px; + padding: 4px; + background: #EBEFF3; +} + +pre.codeoutput { + color: gray; + font-style: italic; +} +pre.error { + color: red; +} + +/* Make the text shrink to fit narrow windows, but not stretch too far in +wide windows. On Gecko-based browsers, the shrink-to-fit doesn't work. */ +p,h1,h2,div { + /* for MATLAB's browser */ + width: 600px; + /* for Mozilla, but the "width" tag overrides it anyway */ + max-width: 600px; + /* for IE */ + width:expression(document.body.clientWidth > 620 ? "600px": "auto" ); +} + + </style></head> + <body> + <h2>Contents</h2> + <div> + <ul> + <li><a href="#1">Optimization of a simple (Rosenbrock) function, with no constraints</a></li> + <li><a href="#2">Only lower bound constraints</a></li> + <li><a href="#3">Only upper bound constraints</a></li> + <li><a href="#4">Dual constraints</a></li> + <li><a href="#5">Mixed constraints</a></li> + <li><a href="#6">Provide your own fminsearch options</a></li> + <li><a href="#7">Exactly fix one variable, constrain some others, and set a tolerance</a></li> + <li><a href="#8">All the standard outputs from fminsearch are still returned</a></li> + </ul> + </div> + <h2>Optimization of a simple (Rosenbrock) function, with no constraints<a name="1"></a></h2><pre class="codeinput">rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2; + +<span class="comment">% With no constraints, operation simply passes through</span> +<span class="comment">% directly to fminsearch. The solution should be [1 1]</span> +xsol = fminsearchbnd(rosen,[3 3]) +</pre><pre class="codeoutput"> +xsol = + + 0.99998 0.99995 + +</pre><h2>Only lower bound constraints<a name="2"></a></h2><pre class="codeinput">xsol = fminsearchbnd(rosen,[3 3],[2 2]) +</pre><pre class="codeoutput"> +xsol = + + 2 4 + +</pre><h2>Only upper bound constraints<a name="3"></a></h2><pre class="codeinput">xsol = fminsearchbnd(rosen,[-5 -5],[],[0 0]) +</pre><pre class="codeoutput"> +xsol = + + -1.0447e-13 -1.4451e-08 + +</pre><h2>Dual constraints<a name="4"></a></h2><pre class="codeinput">xsol = fminsearchbnd(rosen,[2.5 2.5],[2 2],[3 3]) +</pre><pre class="codeoutput"> +xsol = + + 2 3 + +</pre><h2>Mixed constraints<a name="5"></a></h2><pre class="codeinput">xsol = fminsearchbnd(rosen,[0 0],[2 -inf],[inf 3]) +</pre><pre class="codeoutput"> +xsol = + + 2 3 + +</pre><h2>Provide your own fminsearch options<a name="6"></a></h2><pre class="codeinput">opts = optimset(<span class="string">'fminsearch'</span>); +opts.Display = <span class="string">'iter'</span>; +opts.TolX = 1.e-12; +opts.MaxFunEvals = 100; + +n = [10,5]; +H = randn(n); +H=H'*H; +Quadraticfun = @(x) x*H*x'; + +<span class="comment">% Global minimizer is at [0 0 0 0 0].</span> +<span class="comment">% Set all lower bound constraints, all of which will</span> +<span class="comment">% be active in this test.</span> +LB = [.5 .5 .5 .5 .5]; +xsol = fminsearchbnd(Quadraticfun,[1 2 3 4 5],LB,[],opts) +</pre><pre class="codeoutput"> + Iteration Func-count min f(x) Procedure + 0 1 173.731 + 1 6 172.028 initial simplex + 2 8 162.698 expand + 3 9 162.698 reflect + 4 11 151.902 expand + 5 13 138.235 expand + 6 14 138.235 reflect + 7 16 126.604 expand + 8 17 126.604 reflect + 9 19 97.3266 expand + 10 20 97.3266 reflect + 11 21 97.3266 reflect + 12 22 97.3266 reflect + 13 24 73.7178 expand + 14 25 73.7178 reflect + 15 26 73.7178 reflect + 16 28 50.8236 expand + 17 29 50.8236 reflect + 18 31 41.6294 expand + 19 33 30.4252 expand + 20 34 30.4252 reflect + 21 36 27.782 reflect + 22 37 27.782 reflect + 23 39 27.782 contract inside + 24 41 22.6509 reflect + 25 42 22.6509 reflect + 26 43 22.6509 reflect + 27 44 22.6509 reflect + 28 45 22.6509 reflect + 29 47 21.0211 reflect + 30 48 21.0211 reflect + 31 49 21.0211 reflect + 32 51 21.0211 contract inside + 33 52 21.0211 reflect + 34 54 20.7613 contract inside + 35 55 20.7613 reflect + 36 56 20.7613 reflect + 37 57 20.7613 reflect + 38 59 20.6012 contract inside + 39 61 20.5324 contract inside + 40 63 20.4961 contract inside + 41 65 20.3886 contract inside + 42 67 20.2121 reflect + 43 69 20.0876 contract inside + 44 71 19.9164 reflect + 45 72 19.9164 reflect + 46 74 19.9164 contract inside + 47 76 19.9164 contract outside + 48 78 19.3349 expand + 49 80 19.3349 contract inside + 50 81 19.3349 reflect + 51 82 19.3349 reflect + 52 84 18.8721 expand + 53 85 18.8721 reflect + 54 87 18.6427 expand + 55 89 17.4548 expand + 56 90 17.4548 reflect + 57 92 16.0113 expand + 58 93 16.0113 reflect + 59 94 16.0113 reflect + 60 96 14.6134 expand + 61 98 12.5445 expand + 62 99 12.5445 reflect + 63 101 10.7311 expand + +Exiting: Maximum number of function evaluations has been exceeded + - increase MaxFunEvals option. + Current function value: 10.731146 + + +xsol = + + 1.7022 1.0787 1.2034 0.5006 0.64666 + +</pre><h2>Exactly fix one variable, constrain some others, and set a tolerance<a name="7"></a></h2><pre class="codeinput">opts = optimset(<span class="string">'fminsearch'</span>); +opts.TolFun = 1.e-12; + +LB = [-inf 2 1 -10]; +UB = [ inf inf 1 inf]; +xsol = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB,opts) +</pre><pre class="codeoutput"> +xsol = + + -4.9034e-07 2 1 5.1394e-07 + +</pre><h2>All the standard outputs from fminsearch are still returned<a name="8"></a></h2><pre class="codeinput">[xsol,fval,exitflag,output] = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB) +</pre><pre class="codeoutput"> +xsol = + + 3.1094e-05 2 1 -5.1706e-05 + + +fval = + + 2.2361 + + +exitflag = + + 1 + + +output = + + iterations: 77 + funcCount: 138 + algorithm: 'Nelder-Mead simplex direct search' + message: [1x194 char] + +</pre><p class="footer"><br> + Published with MATLAB® 7.0.1<br></p> + <!-- +##### SOURCE BEGIN ##### +%% Optimization of a simple (Rosenbrock) function, with no constraints +rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2; + +% With no constraints, operation simply passes through +% directly to fminsearch. The solution should be [1 1] +xsol = fminsearchbnd(rosen,[3 3]) + +%% Only lower bound constraints +xsol = fminsearchbnd(rosen,[3 3],[2 2]) + +%% Only upper bound constraints +xsol = fminsearchbnd(rosen,[-5 -5],[],[0 0]) + +%% Dual constraints +xsol = fminsearchbnd(rosen,[2.5 2.5],[2 2],[3 3]) + +%% Mixed constraints +xsol = fminsearchbnd(rosen,[0 0],[2 -inf],[inf 3]) + +%% Provide your own fminsearch options +opts = optimset('fminsearch'); +opts.Display = 'iter'; +opts.TolX = 1.e-12; +opts.MaxFunEvals = 100; + +n = [10,5]; +H = randn(n); +H=H'*H; +Quadraticfun = @(x) x*H*x'; + +% Global minimizer is at [0 0 0 0 0]. +% Set all lower bound constraints, all of which will +% be active in this test. +LB = [.5 .5 .5 .5 .5]; +xsol = fminsearchbnd(Quadraticfun,[1 2 3 4 5],LB,[],opts) + +%% Exactly fix one variable, constrain some others, and set a tolerance +opts = optimset('fminsearch'); +opts.TolFun = 1.e-12; + +LB = [-inf 2 1 -10]; +UB = [ inf inf 1 inf]; +xsol = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB,opts) + +%% All the standard outputs from fminsearch are still returned +[xsol,fval,exitflag,output] = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB) + + +##### SOURCE END ##### +--> + </body> +</html> \ No newline at end of file diff --git a/FOTF Toolbox/fminsearchbnd/doc/Understanding_fminsearchbnd.rtf b/FOTF Toolbox/fminsearchbnd/doc/Understanding_fminsearchbnd.rtf new file mode 100644 index 0000000..49eaa1c --- /dev/null +++ b/FOTF Toolbox/fminsearchbnd/doc/Understanding_fminsearchbnd.rtf @@ -0,0 +1,98 @@ +{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;\f1\fswiss\fcharset77 Helvetica-Bold;} +{\colortbl;\red255\green255\blue255;} +\margl1440\margr1440\vieww12760\viewh17780\viewkind0 +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc + +\f0\fs24 \cf0 \ + +\f1\b Understanding fminsearchbnd\ +\ +John D'Errico\ +woodchips@rochester.rr.com +\f0\b0 \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural +\cf0 \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qj +\cf0 \ +Fminsearchbnd is really quite simple in concept. I've implemented lower and upper bound constraints by the careful use of transformations of the variables. In turn, the optimization engine is itself fminsearch itself.\ +\ +Since fminsearch does not allow bound constraints, the trick is to insert a wrapper function around the user supplied objective function. I've done all the work, so all you, as the user, needs to do is supply a set of bounds. All the other arguments are identical to that which fminsearch would have expected. \ +\ +There are several classes of bound constraints one might consider. Simple lower bound constraints:\ +\ + LB(i) <= x(i)\ +\ +Upper bound constraints:\ +\ + x(i) <= UB(i)\ +\ +Dual constraints\ +\ + LB(i) <= x(i) <= UB(i)\ +\ +Two other classes that I allow are fully unbounded variables, and a dual constraint where the lower and upper bounds are identical. In essence, this last class of constraint fixes the variable at the given level. Of course, internally in fminsearchbnd, I just completely remove that variable from the optimization, so fminsearch never sees the variable at all.\ +\ +The bounded variables are transformed such that fminsearch itself sees a fully unconstrained problem. For example, in the case of a variable bounded on the lower end by LB(i), I use the transformation\ +\ + x(i) = LB(i) + z(i)^2\ +\ +The variable z(i) is fully unconstrained, but since the square of z(i) is always non-negative (for real z), then x(i) must necessarily be always greater than or equal to LB(i). Likewise, a pure upper bound constraint is implemented as\ +\ + x(i) = UB(i) - z(i)^2\ +\ +Clearly, x(i) in this case can never rise above UB(i). And finally, the dual bounded variable is handled by a trigonometric transformation,\ +\ + x(i) = LB(i) + (UB(i) - LB(i))*(sin(z(i))+1)/2\ +\ +In this last case, I do absolutely enforce the requirement that LB(i) <= x(i) <= UB(i), since the vagaries of floating point arithmetic might sometimes cause those bounds to be subtly exceeded.\ +\ +\ + +\f1\b Multiple solutions due to the transformations\ + +\f0\b0 \ +An artifact of the transformations used is the creation of multiple solutions to a problem that at one time may well have had a unique solution. While the presence of multiple local solutions is often a problem for an optimizer, each of these introduced solutions are fully equivalent. It matters not in the least which one is found.\ +\ +\ + +\f1\b Alternative choices for the transformations\ + +\f0\b0 \ +I have occasionally seen it suggested that one use a sin(z)^2 transformation instead of the chosen form based on sin(z). My own feeling is that either could be used to roughly equal advantage, but that the sin^2 transformation may be slightly more nonlinear, causing subtly more problems in terms of floating point arithmetic. Similarly, I've tried other one sided and two sided transformations. A two sided transformation that I found to be of interest utilized atan(z). My testing showed that it was often more slowly convergent near the bounds, taking more iterations to converge. The atan transformation was a good choice as a way to implement exclusive bounds (see below.)\ +\ +\ + +\f1\b Inclusive versus exclusive bounds\ + +\f0\b0 \ +A feature of the bound constraints that I have chosen to implement in fminsearchbnd is that they are inclusive bounds. That is, these constraints allow the boundary value itself to be achieved. Exclusive constraints would correspond to the strict inequalities, < and >. Why is this difference between inclusive and exclusive bound constraints an issue? As I said, fminsearchbnd allows its bounds to be fully achieved. So if your objective function includes an evaluation of log(x), where x is constrained to be greater than or equal to zero, then Matlab will generate a singularity.\ +\ +>> log(0)\ +Warning: Log of zero.\ +\ +ans =\ + -Inf\ +\ +An exclusive bound at zero would have prevented such an error. I've chosen not to implement them in that form however, as the necessary transformations tend to be somewhat more intractable, converging with less rapidity in practice. Also, the interface would have been more complex had I allowed the user to specify the actual boundary type for each constraint.\ +\ +All of this means that if you really need exclusive bounds, then you must offset your bound limits by a small amount.\ +\ +\ + +\f1\b Starting values, infeasible starting values, tolerances, etc.\ + +\f0\b0 \ +The transformations chosen for fminsearchbnd are all simply invertible. This allows the user supplied starting values for each variable (prior to any transformation) to be simply mapped back to a corresponding value. Infeasible starting values are simply resolved for the bound constrained problem by simply clipping to the bounded domain.\ +\ +A more difficult issue is the question of tolerances on the parameters, that is, TolX. The nonlinear transformations mean that fminsearch itself will see only the transformed parameters, not the parameters in their real domain. As I've implemented fminsearchbnd as an overlay to fminsearch itself, there is no simple way to provide explicit control over the variable tolerances without re-writing fminsearch. \ +\ +\ + +\f1\b Limitations of fminsearchbnd\ + +\f0\b0 \ +What does fminsearchbnd NOT do? You cannot provide general linear/nonlinear equality or inequality constraints, as are provided by fmincon, or lsqlin. Only simple bound constraints are allowed.\ +\ +\ +} \ No newline at end of file diff --git a/FOTF Toolbox/fminsearchbnd/doc/~$derstanding_fminsearchbnd.rtf b/FOTF Toolbox/fminsearchbnd/doc/~$derstanding_fminsearchbnd.rtf new file mode 100644 index 0000000..e8bb63f Binary files /dev/null and b/FOTF Toolbox/fminsearchbnd/doc/~$derstanding_fminsearchbnd.rtf differ diff --git a/FOTF Toolbox/fminsearchbnd/fminsearchbnd.m b/FOTF Toolbox/fminsearchbnd/fminsearchbnd.m new file mode 100644 index 0000000..95d419b --- /dev/null +++ b/FOTF Toolbox/fminsearchbnd/fminsearchbnd.m @@ -0,0 +1,304 @@ +function [x,fval,exitflag,output]=fminsearchbnd3(fun,x0,LB,UB,options,varargin) +% FMINSEARCHBND: FMINSEARCH, but with bound constraints by transformation +% usage: x=FMINSEARCHBND(fun,x0) +% usage: x=FMINSEARCHBND(fun,x0,LB) +% usage: x=FMINSEARCHBND(fun,x0,LB,UB) +% usage: x=FMINSEARCHBND(fun,x0,LB,UB,options) +% usage: x=FMINSEARCHBND(fun,x0,LB,UB,options,p1,p2,...) +% usage: [x,fval,exitflag,output]=FMINSEARCHBND(fun,x0,...) +% +% arguments: +% fun, x0, options - see the help for FMINSEARCH +% +% LB - lower bound vector or array, must be the same size as x0 +% +% If no lower bounds exist for one of the variables, then +% supply -inf for that variable. +% +% If no lower bounds at all, then LB may be left empty. +% +% Variables may be fixed in value by setting the corresponding +% lower and upper bounds to exactly the same value. +% +% UB - upper bound vector or array, must be the same size as x0 +% +% If no upper bounds exist for one of the variables, then +% supply +inf for that variable. +% +% If no upper bounds at all, then UB may be left empty. +% +% Variables may be fixed in value by setting the corresponding +% lower and upper bounds to exactly the same value. +% +% Notes: +% +% If options is supplied, then TolX will apply to the transformed +% variables. All other FMINSEARCH parameters should be unaffected. +% +% Variables which are constrained by both a lower and an upper +% bound will use a sin transformation. Those constrained by +% only a lower or an upper bound will use a quadratic +% transformation, and unconstrained variables will be left alone. +% +% Variables may be fixed by setting their respective bounds equal. +% In this case, the problem will be reduced in size for FMINSEARCH. +% +% The bounds are inclusive inequalities, which admit the +% boundary values themselves, but will not permit ANY function +% evaluations outside the bounds. These constraints are strictly +% followed. +% +% If your problem has an EXCLUSIVE (strict) constraint which will +% not admit evaluation at the bound itself, then you must provide +% a slightly offset bound. An example of this is a function which +% contains the log of one of its parameters. If you constrain the +% variable to have a lower bound of zero, then FMINSEARCHBND may +% try to evaluate the function exactly at zero. +% +% +% Example usage: +% rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2; +% +% fminsearch(rosen,[3 3]) % unconstrained +% ans = +% 1.0000 1.0000 +% +% fminsearchbnd(rosen,[3 3],[2 2],[]) % constrained +% ans = +% 2.0000 4.0000 +% +% See test_main.m for other examples of use. +% +% +% See also: fminsearch, fminspleas +% +% +% Author: John D'Errico +% E-mail: woodchips@rochester.rr.com +% Release: 4 +% Release date: 7/23/06 + +% size checks +xsize = size(x0); +x0 = x0(:); +n=length(x0); + +if (nargin<3) || isempty(LB) + LB = repmat(-inf,n,1); +else + LB = LB(:); +end +if (nargin<4) || isempty(UB) + UB = repmat(inf,n,1); +else + UB = UB(:); +end + +if (n~=length(LB)) || (n~=length(UB)) + error 'x0 is incompatible in size with either LB or UB.' +end + +% set default options if necessary +if (nargin<5) || isempty(options) + options = optimset('fminsearch'); +end + +% stuff into a struct to pass around +params.args = varargin; +params.LB = LB; +params.UB = UB; +params.fun = fun; +params.n = n; +params.OutputFcn = []; + +% 0 --> unconstrained variable +% 1 --> lower bound only +% 2 --> upper bound only +% 3 --> dual finite bounds +% 4 --> fixed variable +params.BoundClass = zeros(n,1); +for i=1:n + k = isfinite(LB(i)) + 2*isfinite(UB(i)); + params.BoundClass(i) = k; + if (k==3) && (LB(i)==UB(i)) + params.BoundClass(i) = 4; + end +end + +% transform starting values into their unconstrained +% surrogates. Check for infeasible starting guesses. +x0u = x0; +k=1; +for i = 1:n + switch params.BoundClass(i) + case 1 + % lower bound only + if x0(i)<=LB(i) + % infeasible starting value. Use bound. + x0u(k) = 0; + else + x0u(k) = sqrt(x0(i) - LB(i)); + end + + % increment k + k=k+1; + case 2 + % upper bound only + if x0(i)>=UB(i) + % infeasible starting value. use bound. + x0u(k) = 0; + else + x0u(k) = sqrt(UB(i) - x0(i)); + end + + % increment k + k=k+1; + case 3 + % lower and upper bounds + if x0(i)<=LB(i) + % infeasible starting value + x0u(k) = -pi/2; + elseif x0(i)>=UB(i) + % infeasible starting value + x0u(k) = pi/2; + else + x0u(k) = 2*(x0(i) - LB(i))/(UB(i)-LB(i)) - 1; + % shift by 2*pi to avoid problems at zero in fminsearch + % otherwise, the initial simplex is vanishingly small + x0u(k) = 2*pi+asin(max(-1,min(1,x0u(k)))); + end + + % increment k + k=k+1; + case 0 + % unconstrained variable. x0u(i) is set. + x0u(k) = x0(i); + + % increment k + k=k+1; + case 4 + % fixed variable. drop it before fminsearch sees it. + % k is not incremented for this variable. + end + +end +% if any of the unknowns were fixed, then we need to shorten +% x0u now. +if k<=n + x0u(k:n) = []; +end + +% were all the variables fixed? +if isempty(x0u) + % All variables were fixed. quit immediately, setting the + % appropriate parameters, then return. + + % undo the variable transformations into the original space + x = xtransform(x0u,params); + + % final reshape + x = reshape(x,xsize); + + % stuff fval with the final value + fval = feval(params.fun,x,params.args{:}); + + % fminsearchbnd was not called + exitflag = 0; + + output.iterations = 0; + output.funcount = 1; + output.algorithm = 'fminsearch'; + output.message = 'All variables were held fixed by the applied bounds'; + + % return with no call at all to fminsearch + return +end + +% Check for an outputfcn. If there is any, then substitute my +% own wrapper function. +if ~isempty(options.OutputFcn) + params.OutputFcn = options.OutputFcn; + options.OutputFcn = @outfun_wrapper; +end + +% now we can call fminsearch, but with our own +% intra-objective function. +[xu,fval,exitflag,output] = fminsearch(@intrafun,x0u,options,params); + +% undo the variable transformations into the original space +x = xtransform(xu,params); + +% final reshape +x = reshape(x,xsize); + +% Use a nested function as the OutputFcn wrapper + function stop = outfun_wrapper(x,varargin); + % we need to transform x first + xtrans = xtransform(x,params); + + % then call the user supplied OutputFcn + stop = params.OutputFcn(xtrans,varargin{1:(end-1)}); + + end + +end % mainline end + +% ====================================== +% ========= begin subfunctions ========= +% ====================================== +function fval = intrafun(x,params) +% transform variables, then call original function + +% transform +xtrans = xtransform(x,params); + +% and call fun +fval = feval(params.fun,xtrans,params.args{:}); + +end % sub function intrafun end + +% ====================================== +function xtrans = xtransform(x,params) +% converts unconstrained variables into their original domains + +xtrans = zeros(1,params.n); +% k allows some variables to be fixed, thus dropped from the +% optimization. +k=1; +for i = 1:params.n + switch params.BoundClass(i) + case 1 + % lower bound only + xtrans(i) = params.LB(i) + x(k).^2; + + k=k+1; + case 2 + % upper bound only + xtrans(i) = params.UB(i) - x(k).^2; + + k=k+1; + case 3 + % lower and upper bounds + xtrans(i) = (sin(x(k))+1)/2; + xtrans(i) = xtrans(i)*(params.UB(i) - params.LB(i)) + params.LB(i); + % just in case of any floating point problems + xtrans(i) = max(params.LB(i),min(params.UB(i),xtrans(i))); + + k=k+1; + case 4 + % fixed variable, bounds are equal, set it at either bound + xtrans(i) = params.LB(i); + case 0 + % unconstrained variable. + xtrans(i) = x(k); + + k=k+1; + end +end + +end % sub function xtransform end + + + + + diff --git a/FOTF Toolbox/fminsearchbnd/test/test_main.m b/FOTF Toolbox/fminsearchbnd/test/test_main.m new file mode 100644 index 0000000..404141c --- /dev/null +++ b/FOTF Toolbox/fminsearchbnd/test/test_main.m @@ -0,0 +1,53 @@ +%% Optimization of a simple (Rosenbrock) function, with no constraints +% The unconstrained solution is at [1,1] +rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2; + +% With no constraints, operation simply passes through +% directly to fminsearch. The solution should be [1 1] +xsol = fminsearchbnd(rosen,[3 3]) + +%% Full lower and upper bound constraints which will all be inactive +xsol = fminsearchbnd(rosen,[3 3],[-1 -1],[4 4]) + +%% Only lower bound constraints +xsol = fminsearchbnd(rosen,[3 3],[2 2]) + +%% Only upper bound constraints +xsol = fminsearchbnd(rosen,[-5 -5],[],[0 0]) + +%% Dual constraints +xsol = fminsearchbnd(rosen,[2.5 2.5],[2 2],[3 3]) + +%% Dual constraints, with an infeasible starting guess +xsol = fminsearchbnd(rosen,[0 0],[2 2],[3 3]) + +%% Mixed constraints +xsol = fminsearchbnd(rosen,[0 0],[2 -inf],[inf 3]) + +%% Provide your own fminsearch options +opts = optimset('fminsearch'); +opts.Display = 'iter'; +opts.TolX = 1.e-12; + +n = [10,5]; +H = randn(n); +H=H'*H; +Quadraticfun = @(x) x*H*x'; + +% Global minimizer is at [0 0 0 0 0]. +% Set all lower bound constraints, all of which will +% be active in this test. +LB = [.5 .5 .5 .5 .5]; +xsol = fminsearchbnd(Quadraticfun,[1 2 3 4 5],LB,[],opts) + +%% Exactly fix one variable, constrain some others, and set a tolerance +opts = optimset('fminsearch'); +opts.TolFun = 1.e-12; + +LB = [-inf 2 1 -10]; +UB = [ inf inf 1 inf]; +xsol = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB,opts) + +%% All the standard outputs from fminsearch are still returned +[xsol,fval,exitflag,output] = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB) + diff --git a/FOTF Toolbox/fode_caputo0.m b/FOTF Toolbox/fode_caputo0.m new file mode 100644 index 0000000..bfc8cdf --- /dev/null +++ b/FOTF Toolbox/fode_caputo0.m @@ -0,0 +1,24 @@ +function [y,z]=fode_caputo0(a,na,b,nb,y0,u,t) +% fode_caputo0 - simple Caputo FODE solver with nonzero initial conditions +% +% [y,z]=fode_caputo0(a,na,b,nb,y0,u,t) +% +% a,na,b,nb - coefficients/order vectors of numerator and denominator +% y0 - the initial vector of the output and its integer-order derivatives +% u - the samples of the input signal +% t - the time vector, corresponding to u +% y - the solutions of the Caputo equation, with O(h) +% z - the solution portion for zero initial condition ones + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + a(1,:), na(1,:), b(1,:), nb(1,:), y0(:,1), u(:,1), t(:,1) + end + h=t(2)-t(1); T=0; P=0; U=0; + for i=1:length(y0), T=T+y0(i)*t.^(i-1)/gamma(i); end + for i=1:length(na), P=P+a(i)*caputo9(T,t,na(i),5); end + for i=1:length(nb), U=U+b(i)*caputo9(u,t,nb(i),5); end + z=fode_sol(a,na,1,0,U-P.',t); y=z+T; +end diff --git a/FOTF Toolbox/fode_caputo9.m b/FOTF Toolbox/fode_caputo9.m new file mode 100644 index 0000000..1b9fecf --- /dev/null +++ b/FOTF Toolbox/fode_caputo9.m @@ -0,0 +1,31 @@ +function y=fode_caputo9(a,na,b,nb,y0,u,t,p) +% fode_caputo9 - O(h^p) Caputo FODE solver with nonzero initial conditions +% +% y=fode_caputo9(a,na,b,nb,y0,u,t,p) +% +% a,na,b,nb - coefficients/order vectors of numerator and denominator +% y0 - the initial vector of the output and its integer-order derivatives +% u - the samples of the input signal +% t - the time vector, corresponding to u +% p - the precision O(h^p) setting +% y - the solutions of the Caputo equation, with O(h^p) + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + a(1,:), na(1,:), b(1,:), nb(1,:), y0(:,1), u(:,1), t(:,1) + p(1,1) {mustBePositiveInteger}=5 + end + T=0; dT=0; + if p>length(y0) + yy0=caputo_ics(a,na,b,nb,y0,u(1:p),t(1:p)); + y0=yy0(1:p).*gamma(1:p)'; + elseif p==length(y0) + yy0=caputo_ics(a,na,b,nb,y0,u(1:p+1),t(1:p+1)); + y0=yy0(1:p+1).*gamma(1:p+1)'; + end + for i=1:length(y0), T=T+y0(i)/gamma(i)*t.^(i-1); end + for i=1:length(na), dT=dT+a(i)*caputo9(T,t,na(i),p); end + u=u-dT; y=fode_sol9(a,na,b,nb,u,t,p)+T; +end diff --git a/FOTF Toolbox/fode_sol.m b/FOTF Toolbox/fode_sol.m new file mode 100644 index 0000000..c4dd978 --- /dev/null +++ b/FOTF Toolbox/fode_sol.m @@ -0,0 +1,27 @@ +function y=fode_sol(a,na,b,nb,u,t) +% fode_sol - closed-form solution of FODE with zero initial conditions +% +% y=fode_sol(a,na,b,nb,u,t) +% +% a,na,b,nb - coefficients/order vectors of numerator and denominator +% u - the samples of the input signal +% t - the time vector, corresponding to u +% y - the solutions of the FODE, with O(h) + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + a(1,:), na(1,:), b(1,:), nb(1,:), u(:,1), t(:,1) + end + h=t(2)-t(1); D=sum(a./h.^na); nT=length(t); + D1=b(:)./h.^nb(:); nA=length(a); vec=[na nb]; + y1=zeros(nT,1); W=ones(nT,length(vec)); + for j=2:nT, W(j,:)=W(j-1,:).*(1-(vec+1)/(j-1)); end + for i=2:nT + A=[y1(i-1:-1:1)]'*W(2:i,1:nA); + y1(i,1)=(u(i)-sum(A.*a./h.^na))/D; + end + for i=2:nT, y(i,1)=(W(1:i,nA+1:end)*D1)'*y1(i:-1:1); end +end + diff --git a/FOTF Toolbox/fode_sol9.m b/FOTF Toolbox/fode_sol9.m new file mode 100644 index 0000000..f44c02b --- /dev/null +++ b/FOTF Toolbox/fode_sol9.m @@ -0,0 +1,30 @@ +function y=fode_sol9(a,na,b,nb,u,t,p) +% fode_sol9 - high precision solution of FODE with zero initial conditions +% +% y=fode_sol(a,na,b,nb,u,t) +% +% a,na,b,nb - coefficients/order vectors of numerator and denominator +% u - the samples of the input signal +% t - the time vector, corresponding to u +% p - the order of precision O(h^p) +% y - the solutions of the FODE, with O(h^p) + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + a(1,:), na(1,:), b(1,:), nb(1,:), u(:,1), t(:,1) + p(1,1) {mustBePositiveInteger}=5 + end + h=t(2)-t(1); n=length(t); vec=[na nb]; + g=double(genfunc(p)); W=[]; + for i=1:length(vec), W=[W; get_vecw(vec(i),n,g)]; end + D1=b./h.^nb; nA=length(a); y1=zeros(n,1); + W=W.'; D=sum((a.*W(1,1:nA))./h.^na); + for i=2:n + A=[y1(i-1:-1:1)]'*W(2:i,1:nA); + y1(i)=(u(i)-sum(A.*a./h.^na))/D; + end + for i=2:n, y(i,1)=(W(1:i,nA+1:end)*D1)'*y1(i:-1:1); end +end + diff --git a/FOTF Toolbox/fode_solm.m b/FOTF Toolbox/fode_solm.m new file mode 100644 index 0000000..363a704 --- /dev/null +++ b/FOTF Toolbox/fode_solm.m @@ -0,0 +1,14 @@ +function y=fode_solm(a,na,b,nb,u,t) +% fode_solm - matrix version of fode_sol, with the same syntax + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, a(1,:), na(1,:), b(1,:), nb(1,:), u(:,1), t(:,1), end + h=t(2)-t(1); u=u(:); A=0; B=0; g=double(genfunc(1)); + nt=length(t); n=length(a); m=length(b); + for i=1:n, A=A+get_vecw(na(i),nt,g)*a(i)/(h^na(i)); end + for i=1:m, B=B+get_vecw(nb(i),nt,g)*b(i)/(h^nb(i)); end + A=rot90(hankel(A(end:-1:1))); + B=rot90(hankel(B(end:-1:1))); y=B*(A\u); +end diff --git a/FOTF Toolbox/fopid.m b/FOTF Toolbox/fopid.m new file mode 100644 index 0000000..2961535 --- /dev/null +++ b/FOTF Toolbox/fopid.m @@ -0,0 +1,16 @@ +function Gc=fopid(Kp,Ki,Kd,lam,mu0,T) +% fopid - construct FOPID controller from given parameters +% +% Gc=fopid(Kp,Ki,Kd,lam,mu0) +% +% Kp,Ki,Kd,lam,mu0 - the FOPID parameters +% Gc - the composed FOPID controller + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + s=fotf('s'); + if length(Kp)~=1, Kp=[Kp,0]; else, if nargin==5, T=0; end, end + if length(Kp)==1, Gc=Kp+Ki*s^(-lam)+Kd*s^mu0/(T*s+1); + else, x=Kp; Gc=x(1)+x(2)*s^(-x(4))+x(3)*s^(x(5))/(x(6)*s+1); end +end diff --git a/FOTF Toolbox/fotf.png b/FOTF Toolbox/fotf.png new file mode 100644 index 0000000..96148d2 Binary files /dev/null and b/FOTF Toolbox/fotf.png differ diff --git a/FOTF Toolbox/fotf2sl.m b/FOTF Toolbox/fotf2sl.m new file mode 100644 index 0000000..c9c9a2b --- /dev/null +++ b/FOTF Toolbox/fotf2sl.m @@ -0,0 +1,55 @@ +function key=fotf2sl(G,str0) +% fotf2sl - construct multivariable FOTF block, called internally +% in FOTFLIB blockset + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +ik=strfind(str0,'|'); sG=str0(1:ik(1)-1); +key=1; M=[gcb '/FOTF_matx']; +if exist('G') & strcmp(class(G),'fotf') + [m,n]=size(G); open_system(M,'loadonly'); + set_param(M,'Location',[100,100,500,400]); + ll=get_param(M,'lines'); + bb=get_param(M,'blocks'); + for i=1:length(ll), delete_line(ll(i).Handle); end + for i=1:length(bb), str=char(bb(i)); + if ~strcmp(str,'In1') & ~strcmp(str,'Out1'), + delete_block([M,'/',str]); + end, end + set_param([M '/In1'],'Position',[40,80,70,94]); + add_block('built-in/Demux',[M '/Demux'],... + 'Position',[140,80,145,120],... + 'Outputs',int2str(n)); + add_block('built-in/Mux',[M '/Mux'],... + 'Position',[170+200*n,80,175+200*n,120],... + 'Inputs',int2str(m)); + set_param([M '/Out1'],'Position',... + [200+200*n,80,230+200*n,94]); + pos=zeros(n*m,4); s='+'; ss=repmat(s,1,n); + add_line(M,'In1/1','Demux/1','autorouting','on'); + add_line(M,'Mux/1','Out1/1','autorouting','on'); + for i=1:m, i1=int2str(i); + add_block('built-in/Sum',[M '/Add' i1],... + 'Inputs',ss,'Position',[110+200*n,... + 100+80*(i-1),125+200*n,100+80*(i-1)+10*n]); + for j=1:n, j1=int2str(j); + blkname=[M,'/' sG,i1,j1]; + pos(i+(j-1)*n,:)=[180+10*n+160*(j-1),... + 80+80*(i-1)+40*(j-1),300+10*n+160*(j-1),... + 120+80*(i-1)+40*(j-1)]; + add_block('fotflib/Approximate FOTF model',... + blkname,'Position',pos(i+(j-1)*n,:)); + str=get_param(blkname,'MaskValueString'); + ii=strfind(str,'|'); + str=[sG '(' i1,',',j1 ')' str(ii(1):ii(4)),... + str0(ik(1)+1:end) str(ii(7):end)]; + set_param(blkname,'MaskValueString',str) + add_line(M,['Demux/',j1],[sG i1 j1 '/1'],... + 'autorouting','on') + add_line(M,[sG i1 j1 '/1'],... + ['Add' i1 '/',j1],'autorouting','on') + end + add_line(M,['Add' i1 '/1'],['Mux/' i1],... + 'autorouting','on') + end +else, key=0; end diff --git a/FOTF Toolbox/fotf2sym.m b/FOTF Toolbox/fotf2sym.m new file mode 100644 index 0000000..78119c1 --- /dev/null +++ b/FOTF Toolbox/fotf2sym.m @@ -0,0 +1,11 @@ +function G1=sym(G) +% FOTF2sym convert FOTF to symbolic expression such that +% more accurate computations are allowed. +% See also, sym2fotf to convert results back + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + [n,m]=size(G); + for i=1:n, for j=1:m + G1(i,j)=ppoly2sym(G(i,j).num)/ppoly2sym(G(i,j).den); +end, end, end diff --git a/FOTF Toolbox/fotfpath.m b/FOTF Toolbox/fotfpath.m new file mode 100644 index 0000000..5884b9f --- /dev/null +++ b/FOTF Toolbox/fotfpath.m @@ -0,0 +1,17 @@ +function fotfpath +% fotfpath - set path after FOTF installation, for Simulink path + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + v=version; key=strfind(v,'.'); vers=eval(v(1:key(2)-1)); + p=path; + if vers>=9.12 + p=strrep(p,'FOTF Toolbox\simulink2019b\','FOTF Toolbox\Simulink\'); + p=strrep(p,'FOTF Toolbox\simulink2019b;','FOTF Toolbox\Simulink;'); + else + p=strrep(p,'FOTF Toolbox\Simulink\','FOTF Toolbox\simulink2019b\'); + p=strrep(p,'FOTF Toolbox\Simulink;','FOTF Toolbox\simulink2019b;'); + end + path(p); savepath +end + \ No newline at end of file diff --git a/FOTF Toolbox/fpidfun.m b/FOTF Toolbox/fpidfun.m new file mode 100644 index 0000000..12ad918 --- /dev/null +++ b/FOTF Toolbox/fpidfun.m @@ -0,0 +1,11 @@ +function fy=fpidfun(x,G,t,key) +% fpidfun - objective function for optimum fractional-order PID + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 19 May, 2022 + arguments, x(1,:), G, t(:,1), key=1; end + C=fopid(x); dt=t(2)-t(1); e=step(feedback(1,G*C),t); + if key==1, fy=dt*sum(t.*abs(e)); else, fy=dt*sum(e.^2); end + disp([x(:).', fy]) +end diff --git a/FOTF Toolbox/fpidfuns.m b/FOTF Toolbox/fpidfuns.m new file mode 100644 index 0000000..f156fd1 --- /dev/null +++ b/FOTF Toolbox/fpidfuns.m @@ -0,0 +1,26 @@ +function [fy,C]=fpidfuns(x) +% fpidfuns - general objective function for optimum fractional-order PID + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + global G t key1 key2 C + s=fotf('s'); t=t(:); + switch key1 + case {'fpid',1}, C=x(1)+x(2)*s^(-x(4))+x(3)*s^(x(5)); + case {'fpi',2}, C=x(1)+x(2)*s^(-x(3)); + case {'fpd',3}, C=x(1)+x(2)*s^x(3); + case {'fpidx',4}, C=x(1)+x(2)/s+x(3)*s^x(4); + case {'pid','PID',5}, C=x(1)+x(2)/s+x(3)*s; + end + dt=t(2)-t(1); e=step(feedback(1,G*C),t); e=e(:).'; + switch key2 + case {'itae','ITAE',1}, fy=dt*abs(e)*t; + case {'ise','ISE',2}, fy=dt*sum(e.^2); + case {'iae','IAE',3}, fy=dt*sum(abs(e)); + case {'itse','ITSE',4}, fy=dt*e.^2*t; + otherwise + error('Available criteria are itae, ise, iae, itse.') + end + disp([x(:).' fy]) +end diff --git a/FOTF Toolbox/fpidtune.m b/FOTF Toolbox/fpidtune.m new file mode 100644 index 0000000..268d538 --- /dev/null +++ b/FOTF Toolbox/fpidtune.m @@ -0,0 +1,28 @@ +function [Gc,x,y]=fpidtune(x0,xm,xM,kAlg) +% fpidtune - design of optimum fractional-order PID controllers +% +% [Gc,x,y]=fpidtune(x0,xm,xM,kAlg) +% +% x0 - initial parameters +% xm, xM - boundary values of the decision variables +% kAlg - optimization algorithm specifications +% Gc - optimum FOPID controller +% x - optimal decision variables +% y - optimal value of the objective function + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + n=length(x0); if nargin==5, ff=optimset; ff.MaxIter=50; end + switch kAlg + case {1,2} + x=fminsearchbnd(@fpidfuns,x0,xm,xM); + case 3 + x=patternsearch(@fpidfuns,x0,[],[],[],[],xm,xM); + case 4 + x=ga(@fpidfuns,n,[],[],[],[],xm,xM); + case 5 + x=particleswarm(@fpidfuns,n,xm,xM); + end + [y,Gc]=fpidfuns(x); +end diff --git a/FOTF Toolbox/ftpde_sol.m b/FOTF Toolbox/ftpde_sol.m new file mode 100644 index 0000000..66a1cb3 --- /dev/null +++ b/FOTF Toolbox/ftpde_sol.m @@ -0,0 +1,37 @@ +function [U,X,T]=ftpde_sol(a,f,alpha,L,T0,phi1,phi2,psi1,psi2,m,n) +% ftpde_sol - numerical solutions of time-fractional PDE +% +% Equation u^alpha_t=a*u_xx+f, x0<=x<=uX, t0<=t<=uT +% +% For details see the book + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + arguments + a(1,1) double, f, alpha(1,1){mustBePositive} + L(1,:) double, T0(1,:) double + phi1(1,1), phi2, psi1(1,1), psi2(1,1) + m(1,1){mustBeInteger}=100; n(1,1){mustBeInteger}=100; + end + if isscalar(L), L=[0,L]; end, dx=(L(2)-L(1))/m; + if isscalar(T0), T0=[0,T0]; end, dt=(T0(2)-T0(1))/n; + x=L(1)+(0:m)'*dx; t=T0(1)+(0:n)'*dt; + [T,X]=meshgrid(t,x); F=f(X,T); + r=a*(dt^alpha)/dx/dx; U=zeros(m+1,n+1); v=phi1(x); V=v; I=2:m; + if alpha>1, v1=phi2(x)*dt; V=[V zeros(m+1,n)]; end + if alpha>1, for i=1:n, v=v+v1; V(:,i+1)=v; end, end + if alpha>1, dV=zeros(m+1,n+1); + for j=2:n+1, dV(I,j)=r*V(I-1,j)-2*r*V(I,j)+r*V(I+1,j); end + else, dV(I)=r*V(I-1)-2*r*V(I)+r*V(I+1); dV=[dV(:); 0]; end + F=F*(dt^alpha)+dV; r0=r*ones(m-2,1); + g=genfunc(1); w=get_vecw(alpha,n+1,double(g))'; + A0=(2*r+1)*eye(m-1)-diag(r0,1)-diag(r0,-1); A0=inv(A0); + U(1,:)=psi1(t)-V(1,:)'; U(m+1,:)=psi2(t)-V(m+1,:)'; + for j=1:n + b1=[r*U(1,j+1); zeros(m-3,1); r*U(m+1,j+1)]; + b1=b1-U(2:m,1:j)*w(j+1:-1:2)+F(2:m,j+1); + U(2:m,j+1)=A0*b1; % use predefined inverse for multiplication + end + U=U+V; % fund the solution matrix +end + diff --git a/FOTF Toolbox/fun_opts.m b/FOTF Toolbox/fun_opts.m new file mode 100644 index 0000000..a8f0430 --- /dev/null +++ b/FOTF Toolbox/fun_opts.m @@ -0,0 +1,12 @@ +function fy=fun_opts(x) + global G t key1 key2; + t0=t(1); t1=t(end); N=length(t); + dt=t(2)-t(1); Gf=get_fpidf(x,G,key1); U='1/s'; + [t,y]=INVLAP_new(Gf,t0,t1,N,1,U); e=1-y; + switch key2 + case {'itae','ITAE',1}, fy=dt*sum(t.*abs(e)); + case {'ise','ISE',2}, fy=dt*sum(e.^2); + case {'iae','IAE',3}, fy=dt*sum(abs(e)); + end + disp([x(:).' fy]) +end diff --git a/FOTF Toolbox/funmsym.m b/FOTF Toolbox/funmsym.m new file mode 100644 index 0000000..deb5df0 --- /dev/null +++ b/FOTF Toolbox/funmsym.m @@ -0,0 +1,26 @@ +function F=funmsym(A,fun,x) +% funmsym - symbolic evaluation of matrix functions +% +% F=funmsym(A,fun,x) +% +% A - the constant matrix +% fun - the prototype of the symbolic function +% x - independent variable +% F - the matrix function + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + [V,T]=jordan(A); vec=diag(T); v1=[0,diag(T,1)',0]; + v2=find(v1==0); lam=vec(v2(1:end-1)); m=length(lam); + for i=1:m + k=v2(i):v2(i+1)-1; J1=T(k,k); F(k,k)=funJ(J1,fun,x); + end + F=V*F*inv(V); +end +function fJ=funJ(J,fun,x) + lam=J(1,1); f1=fun; fJ=subs(fun,x,lam)*eye(size(J)); + H=diag(diag(J,1),1); H1=H; + for i=2:length(J) + f1=diff(f1,x); a1=subs(f1,x,lam); fJ=fJ+a1*H1; H1=H1*H/i; +end, end diff --git a/FOTF Toolbox/gamma_c.m b/FOTF Toolbox/gamma_c.m new file mode 100644 index 0000000..5b019c2 --- /dev/null +++ b/FOTF Toolbox/gamma_c.m @@ -0,0 +1,16 @@ +function y=gamma_c(z) +% gamma_c - Gamma function with complex arguments +% +% y=gamma_c(z) +% +% z - the independent variable containing complex quantities +% y - the values of the Gamma function + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + if isreal(z), y=gamma(z); + else, f=@(t)exp(-t).*t.^(z-1); + y=integral(f,0,inf,'ArrayValued',true); + end +end diff --git a/FOTF Toolbox/genfunc.m b/FOTF Toolbox/genfunc.m new file mode 100644 index 0000000..702caea --- /dev/null +++ b/FOTF Toolbox/genfunc.m @@ -0,0 +1,14 @@ +function g=genfunc(p) +% genfunc - computing the generating function vector +% +% g=genfunc(p) +% +% p - the order of precision p +% g - the coefficients of the generating function as a symbolic variable + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, p(1,1) {mustBePositiveInteger}, end + a=1:p+1; A=rot90(vander(a)); g=(1-a)/sym(A'); +end diff --git a/FOTF Toolbox/gershgorin.m b/FOTF Toolbox/gershgorin.m new file mode 100644 index 0000000..887b6a5 --- /dev/null +++ b/FOTF Toolbox/gershgorin.m @@ -0,0 +1,33 @@ +function gershgorin(H,key) +% gershgorin - draw Nyquist plots with Gershgorin bands +% +% gershgorin(H,key) +% +% H - the frequency response data in FRD format +% key - if key=1, the inverse Nyquist plots are drawn + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +if nargin==1, key=0; end +t=[0:.1:2*pi,2*pi]'; [nr,nc]=size(H); nw=nr/nc; ii=1:nc; +for i=1:nc, circles{i}=[]; end +for k=1:nw % evaluate inverse Nyquist array for the frequencies + G=H((k-1)*nc+1:k*nc,:); + if nargin==2 && key==1, G=inv(G); end, H1(:,:,k)=G; + for j=1:nc, ij=find(ii~=j); + v=min([sum(abs(G(ij,j))),sum(abs(G(j,ij)))]); + x0=real(G(j,j)); y0=imag(G(j,j)); + r=sum(abs(v)); % compute Gershgorin circles radius + circles{j}=[circles{j} x0+r*cos(t)+sqrt(-1)*(y0+r*sin(t))]; +end, end +hold off; nyquist(tf(zeros(nc)),'w'); hold on; +h=get(gcf,'child'); h0=h(end:-1:2); +for i=ii, for j=ii + axes(h0((j-1)*nc+i)); NN=H1(i,j,:); NN=NN(:); + if i==j % diagonal plots with Gershgorin circles + cc=circles{i}(:); x1=min(real(cc)); x2=max(real(cc)); + y1=min(imag(cc)); y2=max(imag(cc)); plot(NN) + plot(circles{i}), plot(0,0,'+'), axis([x1,x2,y1,y2]) + else, plot(NN), end % non-diagonal elements +end, end, hold off +if key==1, title('Inverse Nyquist Diagram'); end diff --git a/FOTF Toolbox/get_fpidf.m b/FOTF Toolbox/get_fpidf.m new file mode 100644 index 0000000..eff47c3 --- /dev/null +++ b/FOTF Toolbox/get_fpidf.m @@ -0,0 +1,22 @@ +function Gf=get_fpidf(x,G,key1), x=[x(:).',1 1]; +% get_fpidf - build string expression of the open-loop model +% +% Gf=get_fpidf(x,G,key1) +% +% x - the decision variable of FOPID controllers +% +% key - if key=1, the inverse Nyquist plots are drawn + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +x1=num2str(x(1)); x2=num2str(x(2)); x4=num2str(x(4)); +x3=num2str(x(3)); x5=num2str(x(5)); +switch key1 + case {'fpid',1} + Gc=['(' x1 '+' x2 '*s^-' x4 '+' x3 '*s^' x5 ')']; + case {'fpi',2}, Gc=['(' x1 '+' x2 '*s^-' x3 ')']; + case {'fpd',3}, Gc=['(' x1 '+' x2 '*s^' x3 ')']; + case {'fpidx',4}, Gc=['(' x1 '+' x2 '/s+' x3 '*s^' x4 ')']; + case {'pid',5}, Gc=['(' x1 '+' x2 '/s+' x3 '*s)']; +end +G=strrep(G,'+-','-'); Gf=[G '*' Gc]; diff --git a/FOTF Toolbox/get_vecw.m b/FOTF Toolbox/get_vecw.m new file mode 100644 index 0000000..bc443da --- /dev/null +++ b/FOTF Toolbox/get_vecw.m @@ -0,0 +1,22 @@ +function w=get_vecw(gam,n,g) +% get_vecw - computation of O(h^p) weighting coefficients +% +% w=get_vecw(gam,n,g) +% +% gam - the fractional order +% n - +% g - the generating function vector +% w - the weighting coefficients + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + p=length(g)-1; b=1+gam; g0=g(1); + w=zeros(1,n); w(1)=g(1)^gam; + for m=2:p, M=m-1; dA=b/M; + w(m)=-g(2:m).*((1-dA):-dA:(1-b))*w(M:-1:1).'/g0; + end + for k=p+1:n, M=k-1; dA=b/M; + w(k)=-g(2:(p+1)).*((1-dA):-dA:(1-p*dA))*w(M:-1:(k-p)).'/g0; + end +end diff --git a/FOTF Toolbox/glfdiff.m b/FOTF Toolbox/glfdiff.m new file mode 100644 index 0000000..7bf178e --- /dev/null +++ b/FOTF Toolbox/glfdiff.m @@ -0,0 +1,19 @@ +function dy=glfdiff(y,t,gam) +% glfdiff_mat - evaluation of O(h) GL derivatives with matrix algorithm +% +% dy=glfdiff_mat(y,t,gam) +% +% y - the samples of the function handle of the original function +% t - the time vector +% gam - the fractional order +% dy - the fractional-order derivatives, or integrals if gam<0 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, y(:,1), t(:,1) double, gam(1,1) double, end + [y,h,n]=fdiffcom(y,t); w=[1,zeros(1,n-1)]; a0=y(1); dy(1)=0; + if a0~=0 && gam>0, dy(1)=sign(a0)*Inf; end + for j=2:n, w(j)=w(j-1)*(1-(gam+1)/(j-1)); end + for i=1:length(t), dy(i,1)=w(1:i)*y(i:-1:1)/h^gam; end +end diff --git a/FOTF Toolbox/glfdiff0.m b/FOTF Toolbox/glfdiff0.m new file mode 100644 index 0000000..b17aaa9 --- /dev/null +++ b/FOTF Toolbox/glfdiff0.m @@ -0,0 +1,19 @@ +function [df,C]=glfdiff0(f,t,gam) +% glfdiff0 - evaluation of GL derivatives, not recommended +% +% dy=glfdiff0(y,t,gam) +% +% y - the samples of the function handle of the original function +% t - the time vector +% gam - the fractional order +% dy - the fractional-order derivatives, or integrals if gam<0 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, f(1,:), t(1,:) double, gam(1,1) double, end + [f,h,n]=fdiffcom(f,t); J=0:(n-1); a0=f(1); + if a0~=0 && gam>0, dy(1)=sign(a0)*Inf; end + C=gamma(gam+1)*(-1).^J./gamma(J+1)./gamma(gam-J+1)/h^gam; + for i=2:n, dy(i)=C(1:i)*f(i:-1:1); end +end \ No newline at end of file diff --git a/FOTF Toolbox/glfdiff2.m b/FOTF Toolbox/glfdiff2.m new file mode 100644 index 0000000..2450d03 --- /dev/null +++ b/FOTF Toolbox/glfdiff2.m @@ -0,0 +1,21 @@ +function dy=glfdiff2(y,t,gam,p) +% glfdiff2 - evaluation of O(h^p) GL derivatives, not recommended +% +% dy=glfdiff2(y,t,gam,p) +% +% y - the samples of the function handle of the original function +% t - the time vector +% gam - the fractional order +% p - the order for the precision setting +% dy - the fractional-order derivatives, or integrals if gam<0 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, y(:,1), t(:,1), gam(1,1) + p(1,1){mustBePositive, mustBeInteger}=5 + end + g=double(genfunc(p)); [y,h,n]=fdiffcom(y,t); + w=get_vecw(gam,n,g); dy=zeros(n,1); + for i=1:n, dy(i)=w(1:i)*y(i:-1:1)/h^gam; end +end diff --git a/FOTF Toolbox/glfdiff9.m b/FOTF Toolbox/glfdiff9.m new file mode 100644 index 0000000..040f37f --- /dev/null +++ b/FOTF Toolbox/glfdiff9.m @@ -0,0 +1,26 @@ +function dy=glfdiff9(y,t,gam,p) +% glfdiff9 - evaluation of O(h^p) GL derivatives, recommended +% +% dy=glfdiff9(y,t,gam,p) +% +% y - the samples of the function handle of the original function +% t - the time vector +% gam - the fractional order +% p - the order for the precision setting +% dy - the fractional-order derivatives, or integrals if gam<0 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, y(:,1), t(:,1) double, gam(1,1) double + p(1,1){mustBePositiveInteger}=5 + end + [y,h,n]=fdiffcom(y,t); u=0; du=0; r=(0:p)*h; + R=sym(fliplr(vander(r))); c=double(R)\y(1:p+1); + for i=1:p+1, u=u+c(i)*t.^(i-1); + du=du+c(i)*t.^(i-1-gam)*gamma(i)/gamma(i-gam); + end + v=y-u; g=double(genfunc(p)); w=get_vecw(gam,n,g); + for i=1:n, dv(i,1)=w(1:i)*v(i:-1:1)/h^gam; end + dy=dv+du; if abs(y(1))<1e-10, dy(1)=0; end +end diff --git a/FOTF Toolbox/glfdiff9_mat.m b/FOTF Toolbox/glfdiff9_mat.m new file mode 100644 index 0000000..aee9370 --- /dev/null +++ b/FOTF Toolbox/glfdiff9_mat.m @@ -0,0 +1,26 @@ +function dy=glfdiff9_mat(y,t,gam,p) +% glfdiff9 - evaluation of O(h^p) GL derivatives, matrix version +% +% dy=glfdiff9_mat(y,t,gam,p) +% +% y - the samples of the function handle of the original function +% t - the time vector +% gam - the fractional order +% p - the order for the precision setting +% dy - the fractional-order derivatives, or integrals if gam<0 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, y(:,1), t(:,1) double, gam(1,1) double + p(1,1){mustBePositiveInteger}=5 + end + [y,h,n]=fdiffcom(y,t); u=0; du=0; r=(0:p)*h; + R=sym(fliplr(vander(r))); c=double(R\y(1:p+1)); + for i=1:p+1, u=u+c(i)*t.^(i-1); + du=du+c(i)*t.^(i-1-gam)*gamma(i)/gamma(i-gam); + end + v=y-u; g=double(genfunc(p)); w=get_vecw(gam,n,g); + dv=rot90(hankel(w(end:-1:1)))*v/h^gam; + dy=dv+du; if abs(y(1))<1e-10, dy(1)=0; end +end \ No newline at end of file diff --git a/FOTF Toolbox/glfdiff_fft.m b/FOTF Toolbox/glfdiff_fft.m new file mode 100644 index 0000000..1fae085 --- /dev/null +++ b/FOTF Toolbox/glfdiff_fft.m @@ -0,0 +1,25 @@ +function dy=glfdiff_fft(y,t,gam,p) +% glfdiff_fft - evaluation of O(h^p) GL derivatives with FFT, not recommended +% +% dy=glfdiff_fft(y,t,gam,p) +% +% y - the samples of the function handle of the original function +% t - the time vector +% gam - the fractional order +% p - the order for the precision setting +% dy - the fractional-order derivatives, or integrals if gam<0 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, y(:,1), t(:,1), gam(1,1) + p(1,1){mustBePositiveInteger}=5 + end + [y,h,n]=fdiffcom(y,t); dy=zeros(n,1); + g=double(genfunc(p)); T=2*pi/(n-1); + if y(1)~=0 && gam>0, dy(1)=sign(y(1))*Inf; end + tt=0:T:2*pi; F=g(1); f1=exp(1i*tt); f0=f1; + for i=2:p+1, F=F+g(i)*f1; f1=f1.*f0; end + w=real(fft(F.^gam))*T/2/pi; + for k=2:n, dy(k)=w(1:k)*y(k:-1:1)/h^gam; end +end diff --git a/FOTF Toolbox/glfdiff_h.m b/FOTF Toolbox/glfdiff_h.m new file mode 100644 index 0000000..2ffece3 --- /dev/null +++ b/FOTF Toolbox/glfdiff_h.m @@ -0,0 +1,36 @@ +function dy=glfdiff_h(y,t,gam,nd) + h=t(2)-t(1); y=y(:); t=t(:); a0=y(1); dy(1)=0; n=length(t); +% if a0~=0 & gam>0, dy(1)=sign(a0)*Inf; end + switch nd + case 1 + w=1; for k=2:n, w(k)=w(k-1)*(1-(gam+1)/(k-1)); end + case 2 + w0=(3/2)^gam; w1=-4*gam*w0/3; w=[w0, w1]; + for k=3:n, w(k)=(4*(k-2-gam)*w(k-1)+(-k+3+2*gam)*w(k-2))/3/(k-1); end + case 3 + w0=(11/6)^gam; w1=-18*gam*w0/11; w2=9*gam*w0/11+9*(1-gam)*w1/11; + w=[w0,w1,w2]; + for k=4:n, w(k)=(18*(k-2-gam)*w(k-1)-9*(k-3-2*gam)*w(k-2)+2*(k-4-3*gam)*w(k-3))/11/(k-1); end + case 4 + w0=(25/12)^gam; w1=-gam*48*w0/25; w2=(24*(1-gam)*w1+36*gam*w0)/25; + w3=(-gam*w0*16+(2*gam-1)*w1*12+(2-gam)*w2*16)/25; + w=[w0,w1,w2,w3]; + for k=5:n, w(k)=(48*(k-2-gam)*w(k-1)+36*(2*gam-k+3)*w(k-2)+16*(k-4-3*gam)*w(k-3)+3*(4*gam-k+5)*w(k-4))/25/(k-1); end + case 5 + w0=(137/60)^gam; w1=-gam*300/137*w0; w2=(150*(1-gam)*w1+300*gam*w0)/137; + w3=(-200*gam*w0+100*(2*gam-1)*w1+100*(2-gam)*w2)/137; + w4=(75*(3-gam)*w3+150*(gam-1)*w2+50*(1-3*gam)*w1+75*gam*w0)/137; + w=[w0,w1,w2,w3,w4]; + for k=6:n, w(k)=(300*(k-2-gam)*w(k-1)+300*(2*gam-k+3)*w(k-2)+200*(k-4-3*gam)*w(k-3)+75*(4*gam-k+5)*w(k-4)+12*(k-6-5*gam)*w(k-5))/137/(k-1); end + case 6 + w0=(147/60)^gam; w1=-gam*360/147*w0; w2=(180*(1-gam)*w1+450*gam*w0)/147; + w3=(-400*gam*w0+150*(2*gam-1)*w1+120*(2-gam)*w2)/147; + w4=(90*(3-gam)*w3+225*(gam-1)*w2+100*(1-3*gam)*w1+225*gam*w0)/147; + w5=(72*(4-gam)*w4+90*(2*gam-3)*w3+80*(2-3*gam)*w2+45*(4*gam-1)*w1-72*gam*w0)/147; + w=[w0,w1,w2,w3,w4,w5]; + for k=7:n, w(k)=(360*(k-2-gam)*w(k-1)+450*(2*gam-k+3)*w(k-2)+400*(k-4-3*gam)*w(k-3)+225*(4*gam-k+5)*w(k-4)+72*(k-6-5*gam)*w(k-5)-10*(k-7-6*gam)*w(k-6))/147/(k-1); end + otherwise + disp('order is too high') + end +% for i=nd+1:n, w(i)=aa*w(i-1:-1:i-nd); end + for i=2:n, dy(i)=w(1:i)*[y(i:-1:1)]/h^gam; end diff --git a/FOTF Toolbox/glfdiff_mat.m b/FOTF Toolbox/glfdiff_mat.m new file mode 100644 index 0000000..d64377b --- /dev/null +++ b/FOTF Toolbox/glfdiff_mat.m @@ -0,0 +1,18 @@ +function dy=glfdiff(y,t,gam) +% glfdiff_mat - evaluation of O(h) GL derivatives with matrix algorithm +% +% dy=glfdiff_mat(y,t,gam) +% +% y - the samples of the function handle of the original function +% t - the time vector +% gam - the fractional order +% dy - the fractional-order derivatives, or integrals if gam<0 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, y(:,1), t(:,1) double, gam(1,1) double, end + [y,h,n]=fdiffcom(y,t); w=[1,zeros(1,n-1)]; + for j=2:n, w(j)=w(j-1)*(1-(gam+1)/(j-1)); end + dy=rot90(hankel(w(end:-1:1)))*y/h^gam; +end diff --git a/FOTF Toolbox/glfdiff_mem.m b/FOTF Toolbox/glfdiff_mem.m new file mode 100644 index 0000000..cd4cb6c --- /dev/null +++ b/FOTF Toolbox/glfdiff_mem.m @@ -0,0 +1,21 @@ +function dy=glfdiff_mem(y,t,gam,L0) +% glfdiff_mem - evaluation of O(h) GL derivatives with short memory principle +% +% dy=glfdiff_mem(y,t,gam,L0) +% +% y - the samples of the function handle of the original function +% t - the time vector +% gam - the fractional order +% L0 - the memory length +% dy - the fractional-order derivatives, or integrals if gam<0 + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, y(:,1), t(:,1), gam(1,1), L0=length(t); end + [y,h,n]=fdiffcom(y,t); w=[1,zeros(1,n-1)]; dy(1)=0; + for j=2:L0+1, w(j)=w(j-1)*(1-(gam+1)/(j-1)); end + for i=1:n + L=min([i,L0]); dy(i,1)=w(1:L)*y(i:-1:i-L+1)/h^gam; + end +end diff --git a/FOTF Toolbox/gml_fun.m b/FOTF Toolbox/gml_fun.m new file mode 100644 index 0000000..97f996e --- /dev/null +++ b/FOTF Toolbox/gml_fun.m @@ -0,0 +1,49 @@ +% Generalized Mittag-Leffler function +% Reference: +% A. A. KILBAS, M. SAIGOb, and R. K. SAXENA, 揋eneralized Mittag-Leffler function and +% generalized fractional calculus operators,� Integral Transforms and Special Functions, +% vol. 15, No. 1, 2004, pp. 31�49. +% Prepared by YangQuan Chen. 07/23/2008 +% Based on the ml_fun code in Dingyu Xue, YangQuan Chen* and Derek Atherton. +% 揕inear Feedback Control � Analysis and Design with Matlab�. SIAM Press, 2007, +% ISBN: 978-0-898716-38-2. (348 pages) +% a: \rho +% b: \mu +% c: \gamma +% x: the variable +% eps0: specified accuracy + + function f=gml_fun(a,b,c,x,eps0) + gamma_c=1.0/gamma(c); + if nargin<5, eps0=eps; end + f=0; fa=1; j=0; + while norm(fa,1)>=eps0 + fa=(gamma(c+j)*gamma_c)/gamma(j+1)/gamma(a*j+b) *x.^j; + f=f+fa; j=j+1; + end + +% === +% % GML test code +% % exp(x) +% deltat=0.01; +% x=[-1:deltat:1]; +% y1=gml_fun(1,1,1,x); +% figure;plot(x,y1,'r',x,exp(x),'k') +% figure;plot(x,y1-exp(x),'k') +% % ok, now try MLF when c=1 +% y2=gml_fun(0.5,0.5,1,x); +% y3=MLF_M(0.5,0.5,x); % Igor Podlubny's code +% figure;plot(x,y1,'b',x,y2,'r',x,y3,'k') +% %figure;plot(x, y2-y3','k') +% legend('e^x=E_{1,1}^{(1)}', 'E_{0.5,0.5}^{(1)} - this code', 'E_{0.5,0.5}^{(1)} - Podlubny code') +% % okay, let us now try GML +% y5=gml_fun(0.5,0.5,0.5,x); +% y6=gml_fun(0.5,0.5,1.5,x); +% figure;plot(x,y2,'r',x,y5,'k',x,y6,'b') +% legend('GML \gamma=1','GML \gamma=.5','GML \gamma=1.5') +% title('E_{0.5,0.5}^\gamma(x)') +% +% +% +% +% diff --git a/FOTF Toolbox/iir_pade.m b/FOTF Toolbox/iir_pade.m new file mode 100644 index 0000000..02339c3 --- /dev/null +++ b/FOTF Toolbox/iir_pade.m @@ -0,0 +1,22 @@ +function H=iir_pade(r,a,n,T) +% iir_pade - design IIR filter with Pade approximants +% +% H=iir_pade(r,a,n,T) +% +% r - the fractional order +% a - weighting factor +% n - the filter order +% T - sample time + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + arguments, r(1,1) double, a(1,1){mustBeInRange(a,0,1)}=0 + n(1,1){mustBePositiveInteger}=3 + T(1,1){mustBePositive}=0.01 + end + syms x, b=(3+a-2*sqrt(3*a))/(3-a); + k0=6*b/T/(3-a); f=((1-x^2)/(1+b*x)^2)^r; + c=taylor(f,x,'Order',2*n); c=sym2poly(c); + c=c(end:-1:1); [N,D]=padefcn(c,n-1,n); + H=k0^r*tf(N(end:-1:1),D(end:-1:1),'Variable','z^-1','Ts',T); +end diff --git a/FOTF Toolbox/irid_fod.m b/FOTF Toolbox/irid_fod.m new file mode 100644 index 0000000..1da86ac --- /dev/null +++ b/FOTF Toolbox/irid_fod.m @@ -0,0 +1,74 @@ +% Impulse response invariant discretization of fractional order +% integrators/differentiators +% +% irid_fod function is prepared to compute a discrete-time finite dimensional +% (z) transfer function to approximate a continuous irrational transfer +% function s^r, where "s" is the Laplace transform variable, and "r" is a +% real number in the range of (-1,1). s^r is called a fractional order +% differentiator if 0 < r < 1 and a fractional order integrator if -1 < r < 0. +% +% The proposed approximation keeps the impulse response "invariant" +% +% IN: +% r: the fractional order +% Ts: the sampling period +% norder: the finite order of the approximate z-transfer function +% (the orders of denominator and numerator z-polynomial are the same) +% OUT: +% sr: returns the LTI object that approximates the s^r in the sense +% of impulse response. +% TEST CODE +% dfod=irid_fod(-.5,.01,5);figure;pzmap(dfod) +% +% Reference: YangQuan Chen. "Impulse-invariant and step-invariant +% discretization of fractional order integrators and differentiators". +% August 2008. CSOIS AFC (Applied Fractional Calculus) Seminar. +% http://fractionalcalculus.googlepages.com/ +% -------------------------------------------------------------------- +% YangQuan Chen, Ph.D, Associate Professor and Graduate Coordinator +% Department of Electrical and Computer Engineering, +% Director, Center for Self-Organizing and Intelligent Systems (CSOIS) +% Utah State University, 4120 Old Main Hill, Logan, UT 84322-4120, USA +% E: yqchen@ece.usu.edu or yqchen@ieee.org, T/F: 1(435)797-0148/3054; +% W: http://www.csois.usu.edu or http://yangquan.chen.googlepages.com +% -------------------------------------------------------------------- +% +% 9/5/2009 +% +function [sr]=irid_fod(r,Ts,norder) +if nargin<3; norder=5; end +% if Ts < 0 , sprintf('%s','Sampling period has to be positive'), return, end +% if abs(r)>=1, sprintf('%s','The fractional order should be less than 1.'), return, end +% if norder<2, sprintf('%s','The order of the approximate transfer function has to be greater than 1'), return, end +% +L=200; %number of points of the impulse response function h(n) +Taxis=[0:L-1]*Ts; r0=r; r=abs(r); +ha0=(7*Ts/8)^r; n=1:L-1; h=[ha0, (Ts^r)*(n.^(r-1))/gamma(r)]; +[b,a]=prony(h,norder,norder); +sr=tf(b,a,Ts);if r0>0, sr=1/sr; r=-r0; end + +if 1 % change this to 0 if you do not want to see plots +% approximated h() +wmax0=2*pi/Ts/2; % rad./sec. Nyquist frequency +if r0>0, hhat=impulse(1/sr,Taxis); +else, hhat=impulse(sr,Taxis); end +% figure;plot(Taxis,hhat,'r');hold on;plot(Taxis,h,'ok') +% xlabel('time');ylabel('impulse response'); legend(['true for 1/s^{',num2str(abs(r)),'}'],'approximated') +% figure; +wmax=floor(1+ log10(wmax0) ); wmin=wmax-5; +w=logspace(wmin,wmax,1000); +srfr=(j*w).^(-r); +% subplot(2,1,1) +% semilogx(w,20*log10(abs(srfr)),'r');grid on +% hold on; +srfrhat=freqresp(sr,w); %semilogx(w,20*log10(abs(reshape(srfrhat, 1000, 1))),'k');grid on +% xlabel('frequency in Hz');ylabel('dB'); +% legend('true mag. Bode','approximated mag. Bode') +% subplot(2,1,2) +% semilogx(w,(180/pi) * (angle(srfr)),'r');grid on;hold on +% semilogx(w,(180/pi) * (angle(reshape(srfrhat, 1000, 1))),'k');grid on +% xlabel('frequency in Hz');ylabel('degree'); +% legend('true phase Bode','approximated Phase Bode') +end % if 1 + + diff --git a/FOTF Toolbox/irid_folpf.m b/FOTF Toolbox/irid_folpf.m new file mode 100644 index 0000000..97f6a5e --- /dev/null +++ b/FOTF Toolbox/irid_folpf.m @@ -0,0 +1,69 @@ +% Impulse response invariant discretization of fractional order +% low-pass filters +% +% irid_folpf function is prepared to compute a discrete-time finite +% dimensional (z) transfer function to approximate a continuous-time +% fractional order low-pass filter (LPF) [1/(\tau s +1)]^r, where "s" is +% the Laplace transform variable, and "r" is a real number in the range of +% (0,1), \tau is the time constant of LPF [1/(\tau s +1)]. +% +% The proposed approximation keeps the impulse response "invariant" +% +% IN: +% tau: the time constant of (the first order) LPF +% r: the fractional order \in (0,1) +% Ts: the sampling period +% norder: the finite order of the approximate z-transfer function +% (the orders of denominator and numerator z-polynomial are the same) +% OUT: +% sr: returns the LTI object that approximates the [1/(\tau s +1)]^r +% in the sense of invariant impulse response. +% TEST CODE +% dfod=irid_folpf(.01,0.5,.001,5);figure;pzmap(dfod) +% +% Reference: YangQuan Chen. "Impulse-invariant discretization of fractional +% order low-pass filters". +% Sept. 2008. CSOIS AFC (Applied Fractional Calculus) Seminar. +% http://fractionalcalculus.googlepages.com/ +% -------------------------------------------------------------------- +% YangQuan Chen, Ph.D, Associate Professor and Graduate Coordinator +% Department of Electrical and Computer Engineering, +% Director, Center for Self-Organizing and Intelligent Systems (CSOIS) +% Utah State University, 4120 Old Main Hill, Logan, UT 84322-4120, USA +% E: yqchen@ece.usu.edu or yqchen@ieee.org, T/F: 1(435)797-0148/3054; +% W: http://www.csois.usu.edu or http://yangquan.chen.googlepages.com +% -------------------------------------------------------------------- +% +% 9/7/2009 +% Only supports when r in (0,1). That is fractional order low pass filter. +% HOWEVER, if r is in (-1,0), we call this is a "fractional order +% (proportional and derivative controller)" - we call it FO(PD). +% Note: it may be needed to make FO-LPF discretization minimum phase first. +% +% See also irid_fod.m +% at http://www.mathworks.com/matlabcentral/files/21342/irid_fod.m +% See also srid_fod.m +% (See how the nonminimum phase zeros are handled) +% See also gml_fun.m +% at http://www.mathworks.com/matlabcentral/files/20849/gml_fun.m + +function [sr]=irid_folpf(tau,r,Ts,norder) + +if nargin<4; norder=5; end +% if tau < 0 , sprintf('%s','Time constant has to be positive'), return, end +% if Ts < 0 , sprintf('%s','Sampling period has to be positive'), return, end +% if r>=1 | r<= 0, sprintf('%s','The fractional order should be in (0,1)'), return, end +% if norder<2, sprintf('%s','The order of the approximate transfer function has to be greater than 1'), return, end + +wmax0=2*pi/Ts/2; % rad./sec. Nyquist frequency +L=abs(tau)*4/Ts; % decides the number of points of the impulse response function h(n) +Taxis=[0:L-1]*Ts; +ha0=(7.0*Ts/8)^r; +n=1:L-1; n=n*Ts; +h1=gml_fun(1,r,r,-1/tau*n); % http://www.mathworks.com/matlabcentral/files/20849/gml_fun.m +h2=(1/tau)^r*h1.*(n.^(r-1)); +h0= ha0*(1/(tau+ (7.0*Ts/8)))^r; +h=[h0,h2*Ts]; %% [ha0, (Ts^r)*(n.^(r-1))/gamma(r)]; +q=norder;p=norder; +[b,a]=prony((h),q,p); +sr=tf(b,a,Ts); diff --git a/FOTF Toolbox/kronsum.m b/FOTF Toolbox/kronsum.m new file mode 100644 index 0000000..0857597 --- /dev/null +++ b/FOTF Toolbox/kronsum.m @@ -0,0 +1,15 @@ +function C=kronsum(A,B) +% kronsum - evaluate the Kronecker sum of two matrices +% +% C=kronsum(A,B) +% +% A, B - the two matrices +% C - the kronecker sum of matrices A and B + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + [ma,na]=size(A); [mb,nb]=size(B); + A=reshape(A,[1 ma 1 na]); B=reshape(B,[mb 1 nb 1]); + C=reshape(A+B,[ma*mb na*nb]); +end diff --git a/FOTF Toolbox/license.txt b/FOTF Toolbox/license.txt new file mode 100644 index 0000000..20471cd --- /dev/null +++ b/FOTF Toolbox/license.txt @@ -0,0 +1,27 @@ +Copyright (c) 2017, Dingyu Xue +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution + +* Neither the name of Northeastern University, China nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/FOTF Toolbox/matsuda_fod.m b/FOTF Toolbox/matsuda_fod.m new file mode 100644 index 0000000..55909d6 --- /dev/null +++ b/FOTF Toolbox/matsuda_fod.m @@ -0,0 +1,24 @@ +function G=matsuda_fod(G0,n,wb,wh) +% matsuda_fod - design of Matsuda-Fujii filter +% +% G=matsuda_fod(f,w) +% G=matsuda_fod(gam,n,wb,wh) +% G=matsuda_fod(G0,n,wb,wh) +% +% f, w - the frequency response and frequency vector to be approximated +% gam - the fractional order +% G0 - the FOTF model to be fit +% wb, wh, n - the frequency interval (wb,wh) and order of the filter + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, G0, n, wb(1,1)=1e-3, wh(1,1){mustBeGreaterThan(wh,wb)}=1e3, end + if nargin==2, f=G0; w=n; n=length(w); + else, if isa(G0,'double'), s=fotf('s'); G0=s^G0; end + w=logspace(log10(wb),log10(wh),n); f=mfrd(G0,w); + end + v=abs(f(:).'); s=tf('s'); n=length(w); + for k=1:n, a(k)=v(k); v=(w-w(k))./(v-v(k)); end + G=a(n); for k=n-1:-1:1, G=a(k)+(s-w(k))/G; end +end diff --git a/FOTF Toolbox/mfd2frd.m b/FOTF Toolbox/mfd2frd.m new file mode 100644 index 0000000..b0d2af6 --- /dev/null +++ b/FOTF Toolbox/mfd2frd.m @@ -0,0 +1,14 @@ +function H=mfd2frd(H1,w) +% mfd2frd - conversion from MFD data type to FRD +% +% H=mfd2frd(H1,w) +% +% H1, w - the frequency response and frequency vector to be approximated +% 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 + [nr,~]=size(H1); nw=length(w); nr=nr/nw; + for i=1:nw, H(:,:,i)=H1((i-1)*nr+(1:nr),:); end, H=frd(H,w); +end \ No newline at end of file diff --git a/FOTF Toolbox/mfrd.m b/FOTF Toolbox/mfrd.m new file mode 100644 index 0000000..175a475 --- /dev/null +++ b/FOTF Toolbox/mfrd.m @@ -0,0 +1,14 @@ +function H1=mfrd(G,w) +% mfrd - frequency response of an FOTF object +% +% H=mfrd(G,w) +% +% G, w - the FOTF object and the frequency vector +% H - the frequency response data in MFD format + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + H=frd(G,w); h=H.ResponseData; H1=[]; + for i=1:length(w); H1=[H1; h(:,:,i)]; end +end \ No newline at end of file diff --git a/FOTF Toolbox/mfrdadd.m b/FOTF Toolbox/mfrdadd.m new file mode 100644 index 0000000..31aae0c --- /dev/null +++ b/FOTF Toolbox/mfrdadd.m @@ -0,0 +1,8 @@ +function H=mfrdadd(H1,H2,n) +% Add up two MFD freq response arrays + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + [H1,H2]=mfrdmat(H1,H2,n); H=H1+H2; +end + \ No newline at end of file diff --git a/FOTF Toolbox/mfrddly.m b/FOTF Toolbox/mfrddly.m new file mode 100644 index 0000000..dc3562d --- /dev/null +++ b/FOTF Toolbox/mfrddly.m @@ -0,0 +1,9 @@ +function H=mfrddly(H1,D,w) +% Frequency response of MFD with delay matrix D + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + n=length(w); m=size(H1,1)/n; H=[]; + if length(D)==1, D=repmat(D,m,size(H1,2)); end + for i=1:n, H=[H; H1((i-1)*m+1:m*i,:).*exp(-1i*D*w(i))]; end +end diff --git a/FOTF Toolbox/mfrdget.m b/FOTF Toolbox/mfrdget.m new file mode 100644 index 0000000..5d25123 --- /dev/null +++ b/FOTF Toolbox/mfrdget.m @@ -0,0 +1,7 @@ +function h=mfrdget(H,i,j,m) +% Extract MFD freq response array from MV MFD + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + h=[]; for k=1:length(i), h=[h; H(i(k):m:end,j)]; end +end diff --git a/FOTF Toolbox/mfrdinv.m b/FOTF Toolbox/mfrdinv.m new file mode 100644 index 0000000..0f137ea --- /dev/null +++ b/FOTF Toolbox/mfrdinv.m @@ -0,0 +1,9 @@ +function H=mfrdinv(H1,n) +% Inverse of a MFD freq response array + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + m=size(H1,1)/n; H=[]; + if m==size(H1,2), for i=1:n, H=[H; inv(H1((i-1)*m+1:m*i,:))]; end + else, error('system matrix is not square, no inverse found'); end +end diff --git a/FOTF Toolbox/mfrdmat.m b/FOTF Toolbox/mfrdmat.m new file mode 100644 index 0000000..8051278 --- /dev/null +++ b/FOTF Toolbox/mfrdmat.m @@ -0,0 +1,9 @@ +function [H1,H2,m]=mfrdmat(H1,H2,n) +% Add up two MFD freq response arrays + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + if size(H1,1)<size(H2,1), m=size(H1,1); H1=repmat(H1,n,1); + elseif size(H1,1)>size(H2,1), m=size(H2,1); H2=repmat(H2,n,1); + else, m=size(H1,1)/n; end +end diff --git a/FOTF Toolbox/mfrdtimes.m b/FOTF Toolbox/mfrdtimes.m new file mode 100644 index 0000000..ff5ab6f --- /dev/null +++ b/FOTF Toolbox/mfrdtimes.m @@ -0,0 +1,8 @@ +function H=mfrdtimes(H1,H2,n) +% multiply two MFD freq response arrays + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + [H1,H2,m]=mfrdmat(H1,H2,n); H=[]; + for i=1:m:size(H1,1), ix=i:i+m-1; H=[H; H1(ix,:)*H2(ix,:)]; end +end diff --git a/FOTF Toolbox/mittag_leffler.m b/FOTF Toolbox/mittag_leffler.m new file mode 100644 index 0000000..01f32e5 --- /dev/null +++ b/FOTF Toolbox/mittag_leffler.m @@ -0,0 +1,19 @@ +function f=mittag_leffler(v,z) +% mittag_leffler - symbolic computation of Mittag-Leffler functions +% +% f=mittag_leffler(alpha,z) +% f=mittag_leffler([alpha,beta],z) +% f=mittag_leffler([alpha,beta,gam],z) +% f=mittag_leffler([alpha,beta,gam,q],z) +% +% alpha, beta - the parameters for Mittag-Leffler functions +% z - the independent variable +% f - the Mittag-Leffler function. MATLAB R2008a or earler are recommended + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, v(1,:), z(1,1); end + v=sym([v,1,1,1]); a=v(1); b=v(2); c=v(3); q=v(4); syms k; + f=symsum(pochhammer(c,k*q)*z^k/gamma(a*k+b)/gamma(k+1),k,0,inf); +end \ No newline at end of file diff --git a/FOTF Toolbox/ml_func.m b/FOTF Toolbox/ml_func.m new file mode 100644 index 0000000..0d4d0ca --- /dev/null +++ b/FOTF Toolbox/ml_func.m @@ -0,0 +1,38 @@ +function f=ml_func(aa,z,n,eps0) +% ml_func - numeric computation of Mittag-Leffler functions and derivatives +% +% f=ml_func(alpha,z) +% f=ml_func([alpha,beta],z) +% f=ml_func([alpha,beta,gamma],z) +% f=ml_func([alpha,beta,gamma,q],z) +% f=ml_func(pars,z,n) +% f=ml_func(pars,z,n,eps0) +% +% alpha, beta, gamma, q - the parameters for Mittag-Leffler functions +% z - the independent variable samples in a vector +% n - the integer-order for derivatives of Mittag-Leffler functions +% eps0 - the error tolerance +% f - the numerical samples of Mittag-Leffler function or derivatives + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + aa(1,:) double, z double + n(1,1) {mustBeNonnegativeInteger}=0, eps0(1,1)=eps; + end + aa=[aa,1,1,1]; a=aa(1); b=aa(2); c=aa(3); q=aa(4); + f=0; k=0; fa=1; + if n==0 + while norm(fa,1)>=eps0 + fa=prod(c:(c+q*k-1))/gamma(k+1)/gamma(a*k+b)*z.^k; + f=f+fa; k=k+1; + end + if ~isfinite(f) + if c*q==1, N=round(-log10(eps0)); + f=mlf(a,b,z(:),N); f=reshape(f,size(z)); + else, error('Error: truncation method failed'); end, end + else + aa(2)=aa(2)+n*aa(1); aa(3)=aa(3)+aa(4)*n; + f=prod(c:(c+q*k-1))*ml_func(aa,z,0,eps0); +end, end diff --git a/FOTF Toolbox/ml_step3.m b/FOTF Toolbox/ml_step3.m new file mode 100644 index 0000000..3f395fd --- /dev/null +++ b/FOTF Toolbox/ml_step3.m @@ -0,0 +1,22 @@ +function y=ml_step3(a,b,t,eps0) +% ml_step3 - step response of three-term FODE +% +% y=ml_step3(a1,a2,a3,b1,b2,t,eps0) +% +% a1, a2, a3, b1, b2 - the parameters of the three-term FODE +% t - the time vector +% eps0 - the error tolerance +% y - the numerical solutions of the three-term FODE + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, a(1,3), b(1,2), t(:,1), eps0(1,1)=eps; end + y=0; k=0; ya=1; + a1=a(1); a2=a(2)/a1; a3=a(3)/a1; b1=b(1); b2=b(2); + while max(abs(ya))>=eps0 + ya=(-1)^k/gamma(k+1)*a3^k*t.^((k+1)*b1).*... + ml_func([b1-b2,b1+b2*k+1],-a2*t.^(b1-b2),k,eps0); + y=y+ya; k=k+1; + end, y=y/a1; +end diff --git a/FOTF Toolbox/mlf.m b/FOTF Toolbox/mlf.m new file mode 100644 index 0000000..bbc1c7f --- /dev/null +++ b/FOTF Toolbox/mlf.m @@ -0,0 +1,153 @@ +function [e]=mlf(alf,bet,c,fi); +% +% MLF -- Mittag-Leffler function. +% MLF (alpha,beta,Z,P) is the Mittag-Leffler function E_{alpha,beta}(Z) +% evaluated with accuracy 10^(-P) for each element of Z. +% (C) 2001-2005 Igor Podlubny, Martin Kacenak + + +if nargin<4 , fi=6; end +if nargin<3 | alf<=0 | fi<=0 +else + [r,s]=size(c); [r1,s1]=size(alf); [r2,s2]=size(bet); + mx=max([r,s]); mx1=max([r1,s1]); mx2=max([r2,s2]); + if (r>1 & s>1) | (r1>1 & s1>1) | (r2>1 & s2>1) | (mx1>1 & mx2>1) + sprintf('wrong number of input parameters') + else + if mx1>mx2 , mxx=mx1; e=zeros(mx,mx1); + else, mxx=mx2; e=zeros(mx,mx2);end; + for i1= 1:mx + for i2=1:mxx + + if r>s , z=c(i1,1); else,z=c(1,i1); end + if mx1>mx2 , if r1>s1 , alfa=alf(i2,1); else, alfa=alf(1,i2);end, beta=bet; + else if r2>s2 ,beta=bet(i2,1); else, beta=bet(1,i2); end, alfa=alf; end + if beta<0 , rc=(-2*log(10^(-fi)*pi/(6*(abs(beta)+2)*(2*abs(beta))^(abs(beta)))))^alfa; + else , rc=(-2*log(10^(-fi)*pi/6))^alfa; end + r0=max([1,2*abs(z),rc]); + if (alfa==1 & beta==1) + e(i1,i2)=exp(z); + else + if (alfa<1 & abs(z)<=1) | (1<=alfa<2 & abs(z)<=floor(20/(2.1-alfa)^(5.5-2*alfa))) | (alfa>=2 & abs(z)<=50) + oldsum=0; + k=0; + while (alfa*k+beta)<=0 + k=k+1; + end + newsum=z^k/gamma(alfa*k+beta); + while newsum~=oldsum + oldsum=newsum; + k=k+1; + term=z^k/gamma(alfa*k+beta); + newsum=newsum+term; + k=k+1; + term=z^k/gamma(alfa*k+beta); + newsum=newsum+term; + end + e(i1,i2)=newsum; + else + if (alfa<=1 & abs(z)<=fix(5*alfa+10)) + if ((abs(angle(z))>pi*alfa) & (abs(abs(angle(z))-(pi*alfa))>10^(-fi))) + if beta<=1 + e(i1,i2)=rombint('K',0,r0,fi,alfa,beta,z); + else + eps=1; + e(i1,i2)=rombint('K',eps,r0,fi,alfa,beta,z)+ ... + rombint('P',-pi*alfa,pi*alfa,fi,alfa,beta,z,eps); + end + elseif (abs(angle(z))<pi*alfa & abs(abs(angle(z))-(pi*alfa))>10^(-fi)) + if beta<=1 + e(i1,i2)=rombint('K',0,r0,fi,alfa,beta,z)+ ... + (z^((1-beta)/alfa))*(exp(z^(1/alfa))/alfa); + else + eps=abs(z)/2; + e(i1,i2)=rombint('K',eps,r0,fi,alfa,beta,z)+ ... + rombint('P',-pi*alfa,pi*alfa,fi,alfa,beta,z,eps)+ ... + (z^((1-beta)/alfa))*(exp(z^(1/alfa))/alfa); + end + else + eps=abs(z)+0.5; + e(i1,i2)=rombint('K',eps,r0,fi,alfa,beta,z)+ ... + rombint('P',-pi*alfa,pi*alfa,fi,alfa,beta,z,eps); + end + else + if alfa<=1 + if (abs(angle(z))<(pi*alfa/2+min(pi,pi*alfa))/2) + % alfa + newsum=(z^((1-beta)/alfa))*exp(z^(1/alfa))/alfa; + for k=1:floor(fi/log10(abs(z))) + newsum=newsum-((z^(-k))/gamma(beta-alfa*k)); + % k + end + e(i1,i2)=newsum; + else + newsum=0; + for k=1:floor(fi/log10(abs(z))) + newsum=newsum-((z^-k)/gamma(beta-alfa*k)); + end + e(i1,i2)=newsum; + end + else + if alfa>=2 + m=floor(alfa/2); + sum=0; + for h=0:m + zn=(z^(1/(m+1)))*exp((2*pi*i*h)/(m+1)); + sum=sum+mlf(alfa/(m+1),beta,zn,fi); + end + e(i1,i2)=(1/(m+1))*sum; + else + e(i1,i2)=(mlf(alfa/2,beta,z^(1/2),fi)+mlf(alfa/2,beta,-z^(1/2),fi))/2; + end + end + end + end + end + end + end + end +end + + +function [res]=rombint(funfcn,a,b,order,varargin); +if nargin<4 ,order=6; end +if nargin<3 + Warning ('Error in input format') +else + rom=zeros(2,order); + h=b-a; + rom(1,1)=h*(feval(funfcn,a,varargin{:})+feval(funfcn,b,varargin{:}))/2; + + ipower=1; + for i= 2:order + sum=0; + for j=1:ipower + sum=sum+feval(funfcn,(a+h*(j-0.5)),varargin{:}); + end + rom(2,1)=(rom(1,1)+h*sum)/2; + for k=1:i-1 + rom(2,k+1)=((4^k)*rom(2,k)-rom(1,k))/((4^k)-1); + end + + for j=0:i-1 + rom(1,j+1)=rom(2,j+1); + end + ipower=ipower*2; + h=h/2; + end + res=rom(1,order); +end + + +function res=K(r,alfa,beta,z) +res=r.^((1-beta)/alfa).*exp(-r.^(1/alfa)).*(r*sin(pi*(1-beta))-... +z*sin(pi*(1-beta+alfa)))/(pi*alfa*(r.^2-2*r*z*cos(pi*alfa)+z.^2)); + + +function res=P(r,alfa,beta,z,eps) +w=(eps^(1/alfa))*sin(r/alfa)+r*(1+(1-beta)/alfa); +res=((eps^(1+(1-beta)/alfa))/(2*pi*alfa))*((exp((eps^(1/alfa))*cos(r/alfa)).*... + (cos(w)+i*sin(w))))/(eps*exp(i*r)-z); + + + diff --git a/FOTF Toolbox/mlf_new.m b/FOTF Toolbox/mlf_new.m new file mode 100644 index 0000000..d76ecb8 --- /dev/null +++ b/FOTF Toolbox/mlf_new.m @@ -0,0 +1,149 @@ +function [e]=mlf(alf,bet,c,fi); +% +% MLF -- Mittag-Leffler function. +% MLF (alpha,beta,Z,P) is the Mittag-Leffler function E_{alpha,beta}(Z) +% evaluated with accuracy 10^(-P) for each element of Z. +% (C) 2001-2005 Igor Podlubny, Martin Kacenak + + +if nargin<4 , fi=6; end +if nargin<3 | alf<=0 | fi<=0 +else + [r,s]=size(c); [r1,s1]=size(alf); [r2,s2]=size(bet); + mx=max([r,s]); mx1=max([r1,s1]); mx2=max([r2,s2]); + if (r>1 & s>1) | (r1>1 & s1>1) | (r2>1 & s2>1) | (mx1>1 & mx2>1) + sprintf('wrong number of input parameters') + else + if mx1>mx2 , mxx=mx1; e=zeros(mx,mx1); + else, mxx=mx2; e=zeros(mx,mx2);end; + for i1= 1:mx + for i2=1:mxx + + if r>s , z=c(i1,1); else,z=c(1,i1); end + if mx1>mx2 , if r1>s1 , alfa=alf(i2,1); else, alfa=alf(1,i2);end, beta=bet; + else if r2>s2 ,beta=bet(i2,1); else, beta=bet(1,i2); end, alfa=alf; end + if beta<0 , rc=(-2*log(10^(-fi)*pi/(6*(abs(beta)+2)*(2*abs(beta))^(abs(beta)))))^alfa; + else , rc=(-2*log(10^(-fi)*pi/6))^alfa; end + r0=max([1,2*abs(z),rc]); + if (alfa==1 & beta==1) + e(i1,i2)=exp(z); + else + if (alfa<1 & abs(z)<=1) | (1<=alfa<2 & abs(z)<=floor(20/(2.1-alfa)^(5.5-2*alfa))) | (alfa>=2 & abs(z)<=50) + oldsum=0; + k=0; + while (alfa*k+beta)<=0 + k=k+1; + end + newsum=z^k/gamma(alfa*k+beta); + while newsum~=oldsum + oldsum=newsum; + k=k+1; + term=z^k/gamma(alfa*k+beta); + newsum=newsum+term; + k=k+1; + term=z^k/gamma(alfa*k+beta); + newsum=newsum+term; + end + e(i1,i2)=newsum; + else + if (alfa<=1 & abs(z)<=fix(5*alfa+10)) + if ((abs(angle(z))>pi*alfa) & (abs(abs(angle(z))-(pi*alfa))>10^(-fi))) + if beta<=1 + e(i1,i2)=rombint('K',0,r0,fi,alfa,beta,z); + else + eps=1; + e(i1,i2)=rombint('K',eps,r0,fi,alfa,beta,z)+ ... + rombint('P',-pi*alfa,pi*alfa,fi,alfa,beta,z,eps); + end + elseif (abs(angle(z))<pi*alfa & abs(abs(angle(z))-(pi*alfa))>10^(-fi)) + if beta<=1 + e(i1,i2)=rombint('K',0,r0,fi,alfa,beta,z)+ ... + (z^((1-beta)/alfa))*(exp(z^(1/alfa))/alfa); + else + eps=abs(z)/2; + e(i1,i2)=rombint('K',eps,r0,fi,alfa,beta,z)+ ... + rombint('P',-pi*alfa,pi*alfa,fi,alfa,beta,z,eps)+ ... + (z^((1-beta)/alfa))*(exp(z^(1/alfa))/alfa); + end + else + eps=abs(z)+0.5; + e(i1,i2)=rombint('K',eps,r0,fi,alfa,beta,z)+ ... + rombint('P',-pi*alfa,pi*alfa,fi,alfa,beta,z,eps); + end + else + if alfa<=1 + if (abs(angle(z))<(pi*alfa/2+min(pi,pi*alfa))/2) + % alfa + newsum=(z^((1-beta)/alfa))*exp(z^(1/alfa))/alfa; + for k=1:floor(fi/log10(abs(z))) + newsum=newsum-((z^(-k))/gamma(beta-alfa*k)); + % k + end + e(i1,i2)=newsum; + else + newsum=0; + for k=1:floor(fi/log10(abs(z))) + newsum=newsum-((z^-k)/gamma(beta-alfa*k)); + end + e(i1,i2)=newsum; + end + else + if alfa>=2 + m=floor(alfa/2); + sum=0; + for h=0:m + zn=(z^(1/(m+1)))*exp((2*pi*i*h)/(m+1)); + sum=sum+mlf(alfa/(m+1),beta,zn,fi); + end + e(i1,i2)=(1/(m+1))*sum; + else + e(i1,i2)=(mlf(alfa/2,beta,z^(1/2),fi)+mlf(alfa/2,beta,-z^(1/2),fi))/2; + end + end + end + end + end + end + end + end +end + + +function [res]=rombint(funfcn,a,b,order,varargin); +if nargin<4 ,order=6; end +if nargin<3 + Warning ('Error in input format') +else + rom=zeros(2,order); + h=b-a; + rom(1,1)=h*(feval(funfcn,a,varargin{:})+feval(funfcn,b,varargin{:}))/2; + + ipower=1; + for i= 2:order + sum=0; + for j=1:ipower + sum=sum+feval(funfcn,(a+h*(j-0.5)),varargin{:}); + end + rom(2,1)=(rom(1,1)+h*sum)/2; + k=1:i-1; + rom(2,k+1)=((4.^k).*rom(2,k)-rom(1,k))./((4.^k)-1); + j=0:i-1; rom(1,j+1)=rom(2,j+1); + ipower=ipower*2; + h=h/2; + end + res=rom(1,order); +end + + +function res=K(r,alfa,beta,z) +res=r.^((1-beta)/alfa).*exp(-r.^(1/alfa)).*(r*sin(pi*(1-beta))-... +z*sin(pi*(1-beta+alfa)))/(pi*alfa*(r.^2-2*r*z*cos(pi*alfa)+z.^2)); + + +function res=P(r,alfa,beta,z,eps) +w=(eps^(1/alfa))*sin(r/alfa)+r*(1+(1-beta)/alfa); +res=((eps^(1+(1-beta)/alfa))/(2*pi*alfa))*((exp((eps^(1/alfa))*cos(r/alfa)).*... + (cos(w)+i*sin(w))))/(eps*exp(i*r)-z); + + + diff --git a/FOTF Toolbox/more_sols.m b/FOTF Toolbox/more_sols.m new file mode 100644 index 0000000..9fc18db --- /dev/null +++ b/FOTF Toolbox/more_sols.m @@ -0,0 +1,26 @@ +function more_sols(f,X0,A,tol,tlim,ff) +% morw_sols - find multiple solutions of a matrix equation + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + arguments, f, X0, A=1000, tol=eps, tlim=10, ff=optimset; end + X=X0; if length(A)==1, a=-0.5*A; b=0.5*A; else, a=A(1); b=A(2); end + ar=real(a); br=real(b); ai=imag(a); bi=imag(b); [n,m,i]=size(X0); + ff.Display='off'; ff.TolX=tol; ff.TolFun=1e-20; tic + if i==0, X0=zeros(n,m); %check whether 0 matrix is a solution + if norm(f(X0))<tol, i=1; X(:,:,i)=X0; end + end + while (1) %infinite loop, press Ctrl+C to terminate or wait + x0=ar+(br-ar)*rand(n,m); %initial random matrix + if ~isreal(A), x0=x0+(ai+(bi-ai)*rand(n,m))*1i; end %complex + try [x,~,key]=fsolve(f,x0,ff); catch, continue; end %discard it + t=toc; if t>tlim, break; end %no new solution found + if key>0, N=size(X,3); %find the number of solutions found + for j=1:N, if norm(X(:,:,j)-x)<1e-4; key=0; break; end, end + if key==0 %if more precise solution is found + if norm(f(x))<norm(f(X(:,:,j))), X(:,:,j)=x; end + elseif key>0, X(:,:,i+1)=x; % record the new solution + if norm(imag(x))>1e-8, i=i+1; X(:,:,i+1)=conj(x); %try conjugate + end, assignin('base','X',X); i=i+1, tic %更新信息 + end, assignin('base','X',X); +end, end, end diff --git a/FOTF Toolbox/mustBeNonnegativeInteger.m b/FOTF Toolbox/mustBeNonnegativeInteger.m new file mode 100644 index 0000000..4911244 --- /dev/null +++ b/FOTF Toolbox/mustBeNonnegativeInteger.m @@ -0,0 +1,14 @@ +function mustBeNonnegativeInteger(a) +%mustBeNonnegativeInteger a function to validate the argument + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + if a<0 + eid='Value:Positive'; msg='Inputs must be nonnegative.'; + throwAsCaller(MException(eid,msg)) + end + if round(a)~=a + eid='Value:Integer'; msg='Inputs must be an integer.'; + throwAsCaller(MException(eid,msg)) + end +end \ No newline at end of file diff --git a/FOTF Toolbox/mustBePositiveInteger.m b/FOTF Toolbox/mustBePositiveInteger.m new file mode 100644 index 0000000..b961f0b --- /dev/null +++ b/FOTF Toolbox/mustBePositiveInteger.m @@ -0,0 +1,14 @@ +function mustBePositiveInteger(a) +%mustBePositiveInteger a function to validate the argument + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last Modified 18 May, 2022 + if a<=0 + eid='Value:Positive'; msg='Inputs must be positive.'; + throwAsCaller(MException(eid,msg)) + end + if round(a)~=a + eid='Value:Integer'; msg='Inputs must be an integer.'; + throwAsCaller(MException(eid,msg)) + end +end \ No newline at end of file diff --git a/FOTF Toolbox/new_fod.m b/FOTF Toolbox/new_fod.m new file mode 100644 index 0000000..5fa6bc9 --- /dev/null +++ b/FOTF Toolbox/new_fod.m @@ -0,0 +1,20 @@ +function G=new_fod(r,N,wb,wh,b,d) +% new_fod - design of a modified Oustaloup filter +% +% G=new_fod(r,N,wb,wh) +% +% r - the fractional order +% wb, wh, N - the interested frequency interval (wb,wh) and the order +% G - the designed modified Oustaloup filter, as a TF object + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + r(1,1) double, N(1,1){mustBePositiveInteger}=5 + wb(1,1) double=1e-3; wh(1,1) double=1e3; + b(1,1) {mustBeNumeric}=10; d(1,1) {mustBeNumeric}=9; + end + G=(d/b)^r*tf([d,b*wh,0],[d*(1-r),b*wh,d*r]); + G=G*ousta_fod(r,N,wb,wh); +end \ No newline at end of file diff --git a/FOTF Toolbox/new_inv.m b/FOTF Toolbox/new_inv.m new file mode 100644 index 0000000..916622d --- /dev/null +++ b/FOTF Toolbox/new_inv.m @@ -0,0 +1,18 @@ +function A2=new_inv(A) +% new_inv - a simple matrix inverse function +% +% A2=new_inv(A) +% +% A, A2 - the matrix and its inverse +% +% not recommended, try symbolic version for FOTF matrices + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + A1=A; [n,~]=size(A); E0=eye(n); aa=[]; + for i=1:n, ij=1:n; ij=ij(ij~=i); E=eye(n); a0=A1(i,i); + aa=[aa,a0]; E(ij,i)=-A1(ij,i)/a0; E0=E*E0; A1=E*A1; + end + A2=diag(1./aa)*E0; +end diff --git a/FOTF Toolbox/nlfec.m b/FOTF Toolbox/nlfec.m new file mode 100644 index 0000000..611e878 --- /dev/null +++ b/FOTF Toolbox/nlfec.m @@ -0,0 +1,38 @@ +function [y,t]=nlfec(fun,alpha,y0,yp,t,p,err) +% nlfec - O(h^p) corrector solution of nonlinear multi-term FODEs +% +% [y,t]=nlfec(fun,alpha,y0,yp,t,p,err) +% +% fun - function handles for the nonlinear explicit FODE +% alpha - the maximum order +% y0 - initial vector of the output and its integer-order derivatives +% yp - predictor solutions +% t - time vector +% p - the order for precision +% err - error tolerance +% y - the solution vector + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 30 March, 2017 +% Last modified 18 May, 2022 + arguments + fun, alpha(1,:), y0(:,1), yp(:,1), t(:,1) + p(1,1){mustBePositiveInteger}, err(1,1) double=1e-10 + end + h=t(2)-t(1); m=length(t); ha=h.^alpha; + [T,dT,w,d2]=aux_func(t,y0,alpha,p); + [z,y]=repeat_funs(fun,t,yp,T,d2,alpha,dT,ha,w,m,p); + while norm(z)>err, yp=y; z=zeros(m,1); + [z,y]=repeat_funs(fun,t,yp,T,d2,alpha,dT,ha,w,m,p); + end + % repeatedly called subfunction + function [z,y]=repeat_funs(fun,t,yp,T,d2,alpha,dT,ha,w,m,p) + for i=1:d2 + dyp(:,i)=glfdiff9(yp-T,t,alpha(i),p)+dT(:,i); + end + f=fun(t,yp,dyp(:,2:d2))-dyp(:,1); y=yp; z=zeros(m,1); + for i=2:m, ii=(i-1):-1:1; + z(i)=(f(i)*(ha(1))-w(2:i,1)'*z(ii))/w(1,1); + y(i)=z(i)+yp(i); + end, end +end diff --git a/FOTF Toolbox/nlfep.m b/FOTF Toolbox/nlfep.m new file mode 100644 index 0000000..204f62d --- /dev/null +++ b/FOTF Toolbox/nlfep.m @@ -0,0 +1,40 @@ +function [y,t]=nlfep(fun,alpha,y0,tn,h,p,err) +% nlfec - O(h^p) predictor solution of nonlinear multi-term FODEs +% +% [y,t]=nlfep(fun,alpha,y0,tn,h,p,err) +% +% fun - function handles for the nonlinear explicit FODE +% alpha - the maximum order +% y0 - initial vector of the output and its integer-order derivatives +% tn - terminate time in the solution +% h - fixed step-size +% p - the order for precision +% err - error tolerance +% y, t - the solution vector and time vector + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 30 March, 2017 +% Last modified 18 May, 2022 + arguments + fun, alpha(1,:), y0(1,:), tn(1,1), h(1,1){mustBePositive} + p(1,1) {mustBePositiveInteger}, err(1,1) double=1e-10 + end + m=ceil(tn/h)+1; t=(0:(m-1))'*h; ha=h.^alpha; z=0; + [T,dT,w,d2]=aux_func(t,y0,alpha,p); y=z+T(1); + for k=1:m-1 + zp=z(end); yp=zp+T(k+1); y=[y; yp]; z=[z; zp]; + [zc,yc]=repeat_funs(fun,t,y,d2,w,k,z,ha,dT,T); + while abs(zc-zp)>err + yp=yc; zp=zc; y(end)=yp; z(end)=zp; + [zc,yc]=repeat_funs(fun,t,y,d2,w,k,z,ha,dT,T); + end, end +% repeatedly called subfunction + function [zc,yc]=repeat_funs(fun,t,y,d2,w,k,z,ha,dT,T) + dy=zeros(1,d2-1); + for j=1:(d2-1) + dy(j)=w(1:k+1,j+1)'*z((k+1):-1:1)/ha(j+1)+dT(k,j+1); + end, f=fun(t(k+1),y(k+1),dy); + zc=((f-dT(k+1,1))*ha(1)-w(2:k+1,1)'*z(k:-1:1))/w(1,1); + yc=zc+T(k+1); + end +end \ No newline at end of file diff --git a/FOTF Toolbox/nlfode_mat.m b/FOTF Toolbox/nlfode_mat.m new file mode 100644 index 0000000..0c070f5 --- /dev/null +++ b/FOTF Toolbox/nlfode_mat.m @@ -0,0 +1,39 @@ +function [y,t]=nlfode_mat(f,alpha,y0,tn,h,p,yp) +% nlfode_mat - O(h^p) predictor solution of nonlinear single-term FODEs +% +% [y,t]=nlfode_mat(f,alpha,y0,tn,h,p,yp) +% +% f - function handles for the nonlinear explicit FODE +% alpha - the maximum order +% y0 - initial vector of the output and its integer-order derivatives +% tn - terminate time in the solution +% h - fixed step-size +% p - the order for precision +% yp - the predictor solution +% y, t - the solution vector and time vector + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + f, alpha(1,:) double, y0(:,1) double, tn(1,1) double + h(1,1){mustBePositive}, p(1,1){mustBePositiveInteger} + yp(:,1) double=zeros(ceil(tn/h)+1,1); + end + alfn=ceil(alpha); m=ceil(tn/h)+1; + t=(0:(m-1))'*h; d1=length(y0); d2=length(alpha); + B=zeros(m,m,d2); g=double(genfunc(p)); + for i=1:d2, w=get_vecw(alpha(i),m,g); + B(:,:,i)=rot90(hankel(w(end:-1:1)))/h^alpha(i); + end + c=y0./gamma(1:d1)'; du=zeros(m,d2); + u=0; for i=1:d1, u=u+c(i)*t.^(i-1); end + for i=1:d2 + if alfn(i)==0, du(:,i)=u; + elseif alfn(i)<d1 + for k=(alfn(i)+1):d1 + du(:,i)=du(:,i)+(t.^(k-1-alpha(i)))*c(k)... + *gamma(k)/gamma(k-alpha(i)); + end, end, end + v=fsolve(f,yp,[],t,u,B,du); y=u+v; +end diff --git a/FOTF Toolbox/nlfode_vec.m b/FOTF Toolbox/nlfode_vec.m new file mode 100644 index 0000000..54a54d4 --- /dev/null +++ b/FOTF Toolbox/nlfode_vec.m @@ -0,0 +1,31 @@ +function [x,t]=nlfode_vec(f,alpha,x0,h,tn,L0) +% nlfode_vec - O(h^p) predictor solution of nonlinear single-term FODEs +% +% [x,t]=nlfode_vec(f,alpha,x0,h,tn,L0) +% +% f - function handles for the nonlinear explicit FODE +% alpha - the maximum order +% x0 - initial state vector +% h - fixed step-size +% tn - terminate time in the solution +% L0 - the memory length for short-memory principle +% x, t - the solution matrix for the states and time vector + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + f, alpha(1,:), x0(:,1), h(1,1){mustBePositive} + tn(1,1){mustBePositive}, L0(1,1){mustBePositive}=1e20; + end + n=length(x0); m=round(tn/h)+1; t=0; g=double(genfunc(1)); + ha=h.^alpha; z=zeros(n,m); x1=x0; + for i=1:n, W(i,:)=get_vecw(alpha(i),min(m,L0+1),g); end + for k=2:m, tk=(k-1)*h; L=min(k-1,L0); + for i=1:n + x1(i)=f(tk,x1,i)*ha(i)-W(i,2:L+1)*z(i,k-1:-1:k-L).'+x0(i); + end + t=[t,tk]; z(:,k)=x1-x0; + end + x=(z+repmat(x0,[1,m])).'; t=t(:); +end diff --git a/FOTF Toolbox/nlfode_vec1.m b/FOTF Toolbox/nlfode_vec1.m new file mode 100644 index 0000000..e693fb6 --- /dev/null +++ b/FOTF Toolbox/nlfode_vec1.m @@ -0,0 +1,19 @@ +function [x,t]=nlfode_vec1(f,alpha,x0,h,tn,L0) +% nlfode_vec - another version of nlfode_vec, not recommended + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + f, alpha(1,:), x0(:,1), h(1,1), tn(1,1), L0(1,1)=1e20; + end + n=length(x0); m=round(tn/h)+1; t=0; g=double(genfunc(1)); + x1=x0; ha=h.^alpha(:); z=zeros(n,m); tk=0; + for i=1:n, W(i,:)=get_vecw(alpha(i),min(m,L0+1),g); end + for k=2:m, tk=(k-1)*h; L=min(k-1,L0); + for i=1:n, F0(i,1)=W(i,2:L+1)*z(i,k-1:-1:k-L).'-x0(i); end + F=@(x)x-f(tk,x).*ha+F0; + x1=fsolve(F,x1); t=[t; tk]; z(:,k)=x1-x0; + end + x=(z+repmat(x0,[1,m])).'; +end diff --git a/FOTF Toolbox/num_diff.m b/FOTF Toolbox/num_diff.m new file mode 100644 index 0000000..5f28ff0 --- /dev/null +++ b/FOTF Toolbox/num_diff.m @@ -0,0 +1,13 @@ +function [f,t]=num_diff(y,h,n,p) +% num_diff integer-order numerical differentiation + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + arguments, y(:,1), h(1,1) {mustBePositive} + n(1,1){mustBeInteger,mustBePositive} + p(1,1){mustBeInteger,mustBePositive} + end + m=n+p; alpha=0:m; c=double(fdcoef(n,m,alpha)); + t=(0:length(y)-m)'*h; + for i=1:length(y)-m+1, yy=y(i:i+m-1); f(i,1)=c*yy/h^n; end +end diff --git a/FOTF Toolbox/opt_app.m b/FOTF Toolbox/opt_app.m new file mode 100644 index 0000000..b3a7f5c --- /dev/null +++ b/FOTF Toolbox/opt_app.m @@ -0,0 +1,39 @@ +function Gr=opt_app(G,r,k,key,G0) + arguments + G, r(1,1) {mustBePositiveInteger} + k(1,1) {mustBePositiveInteger} + key(1,1){mustBeMember(key,[0,1])}=0, G0=0 + end + GS=tf(G); Td=totaldelay(GS); + GS.ioDelay=0; GS.InputDelay=0; GS.OutputDelay=0; s=tf('s'); + if nargin<5, G0=(s+1)^r/(s+1)^k; end + beta=G0.num{1}(k+1-r:k+1); alph=G0.den{1}; Tau=1.5*Td; + x=[beta(1:r),alph(2:k+1)]; if abs(Tau)<1e-5, Tau=0.5; end + dc=dcgain(GS); if key==1, x=[x,Tau]; end + y=opt_fun(x,GS,key,r,k,dc); + x=fminsearch(@opt_fun,x,[],GS,key,r,k,dc); + alph=[1,x(r+1:r+k)]; beta=x(1:r+1); if key==0, Td=0; end + beta(r+1)=alph(end)*dc; if key==1, Tau=x(end)+Td; else, Tau=0; end + Gr=tf(beta,alph,'ioDelay',Tau); +end +function y=opt_fun(x,G,key,r,k,dc) + ff0=1e10; a=[1,x(r+1:r+k)]; b=x(1:r+1); b(end)=a(end)*dc; + if key==1, tau=x(end); + if tau<=0, tau=eps; end, [n,d]=pade(tau,3); gP=tf(n,d); + else, gP=1; end + G_e=G-tf(b,a)*gP; G_e.num{1}=[0,G_e.num{1}(1:end-1)]; + [y,ierr]=geth2(G_e); if ierr==1, y=10*ff0; else, ff0=y; end +end +function [v,ierr]=geth2(G) + G=tf(G); num=G.num{1}; den=G.den{1}; ierr=0; v=0; n=length(den); + if abs(num(1))>eps + disp('System not strictly proper'); + ierr=1; return + else, a1=den; b1=num(2:length(num)); end + for k=1:n-1 + if (a1(k+1)<=eps), ierr=1; return + else + aa=a1(k)/a1(k+1); bb=b1(k)/a1(k+1); v=v+bb*bb/aa; k1=k+2; + for i=k1:2:n-1, a1(i)=a1(i)-aa*a1(i+1); b1(i)=b1(i)-bb*a1(i+1); + end, end, end, v=sqrt(0.5*v); +end diff --git a/FOTF Toolbox/optfpid_fun.m b/FOTF Toolbox/optfpid_fun.m new file mode 100644 index 0000000..79d27a2 --- /dev/null +++ b/FOTF Toolbox/optfpid_fun.m @@ -0,0 +1,9 @@ +function y=optfpid_fun(x) + assignin('base','Kp',x(1)); assignin('base','Ki',x(2)); + assignin('base','Kd',x(3)); + assignin('base','mu0',x(4)); + try + [~,~,y_out]=sim('c9mfpidd',[0,20]); + catch, y_out=1e100; end + y=y_out(end,1); disp([x(:).' y]) +end diff --git a/FOTF Toolbox/optimPID/OptimPID.mlapp b/FOTF Toolbox/optimPID/OptimPID.mlapp new file mode 100644 index 0000000..93a54a0 Binary files /dev/null and b/FOTF Toolbox/optimPID/OptimPID.mlapp differ diff --git a/FOTF Toolbox/optimPID/c7multi_step.m b/FOTF Toolbox/optimPID/c7multi_step.m new file mode 100644 index 0000000..a1bd25b --- /dev/null +++ b/FOTF Toolbox/optimPID/c7multi_step.m @@ -0,0 +1,23 @@ +function [sys,x0,str,ts,SSC]=c7multi_step(t,~,~,flag,tTime,yStep) + switch flag + case 0 % initialization + [sys,x0,str,ts] = mdlInitializeSizes; SSC='DefaultSimState'; + case 3 % computes the outputs + sys = mdlOutputs(t,tTime,yStep); + case {1, 2, 4, 9} % undefined flag + sys = []; + otherwise % error found + error(['Unhandled flag = ',num2str(flag)]); + end +end +function [sys,x0,str,ts] = mdlInitializeSizes + sizes = simsizes; + sizes.NumContStates = 0; sizes.NumDiscStates = 0; + sizes.NumOutputs = 1; sizes.NumInputs = 0; + sizes.DirFeedthrough = 0; sizes.NumSampleTimes = 1; + sys = simsizes(sizes); + x0 = []; str = []; ts = [0 0]; +end +function sys = mdlOutputs(t,tTime,yStep) + i=find(tTime<=t); sys=yStep(i(end)); +end diff --git a/FOTF Toolbox/optimPID/fig1.jpg b/FOTF Toolbox/optimPID/fig1.jpg new file mode 100644 index 0000000..43a3144 Binary files /dev/null and b/FOTF Toolbox/optimPID/fig1.jpg differ diff --git a/FOTF Toolbox/optimPID/fig2.jpg b/FOTF Toolbox/optimPID/fig2.jpg new file mode 100644 index 0000000..438abe5 Binary files /dev/null and b/FOTF Toolbox/optimPID/fig2.jpg differ diff --git a/FOTF Toolbox/optimPID/fig3.jpg b/FOTF Toolbox/optimPID/fig3.jpg new file mode 100644 index 0000000..b0a120d Binary files /dev/null and b/FOTF Toolbox/optimPID/fig3.jpg differ diff --git a/FOTF Toolbox/optpidfun_0.m b/FOTF Toolbox/optpidfun_0.m new file mode 100644 index 0000000..0a66c89 --- /dev/null +++ b/FOTF Toolbox/optpidfun_0.m @@ -0,0 +1,8 @@ +function y=optfpid_fun(x) +assignin('base','Kp',x(1)); assignin('base','Ki',x(2)); +assignin('base','Kd',x(3)); assignin('base','lam',x(4)); +assignin('base','mu0',x(5)); +try + [~,~,y_out]=sim('c9mfpidd',[0,20.000000]); +catch, y_out=1e10; end +y=y_out(end,1); diff --git a/FOTF Toolbox/ousta_fod.m b/FOTF Toolbox/ousta_fod.m new file mode 100644 index 0000000..ea9a476 --- /dev/null +++ b/FOTF Toolbox/ousta_fod.m @@ -0,0 +1,22 @@ +function G=ousta_fod(gam,N,wb,wh) +% ousta_fod - design of an Oustaloup filter +% +% G=ousta_fod(r,N,wb,wh) +% +% r - the fractional order +% wb, wh, N - the interested frequency interval (wb,wh) and the order +% G - the designed Oustaloup filter, as a TF object + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + gam(1,1) double, N(1,1){mustBePositiveInteger}=9 + wb(1,1) double=1e-4; wh(1,1){mustBeGreaterThan(wh,wb)}=1e4; + end + if round(gam)==gam, G=tf('s')^gam; + else + k=1:N; wu=sqrt(wh/wb); + wkp=wb*wu.^((2*k-1-gam)/N); wk=wu^(2*gam/N)*wkp; + G=zpk(-wkp,-wk,wh^gam); +end, end diff --git a/FOTF Toolbox/pade_app.m b/FOTF Toolbox/pade_app.m new file mode 100644 index 0000000..ec67276 --- /dev/null +++ b/FOTF Toolbox/pade_app.m @@ -0,0 +1,11 @@ +function Gr=pade_app(c,r,k) +% pade_app Pade approximation of TFs + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + w=-c(r+2:r+k+1)'; vv=[c(r+1:-1:1)'; zeros(k-1-r,1)]; + W=rot90(hankel(c(r+k:-1:r+1),vv)); V=rot90(hankel(c(r:-1:1))); + x=[1 (W\w)']; dred=x(k+1:-1:1)/x(k+1); + y=[c(1) x(2:r+1)*V'+c(2:r+1)]; nred=y(r+1:-1:1)/x(k+1); + Gr=tf(nred,dred); +end diff --git a/FOTF Toolbox/padefcn.m b/FOTF Toolbox/padefcn.m new file mode 100644 index 0000000..db13b2a --- /dev/null +++ b/FOTF Toolbox/padefcn.m @@ -0,0 +1,10 @@ +function [nP,dP]=padefcn(c,r,m) +% padefcn Pade approximation with time moments + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + w=-c(r+2:m+r+1)'; vv=[c(r+1:-1:1)'; zeros(m-1-r,1)]; + W=rot90(hankel(c(m+r:-1:r+1),vv)); V=rot90(hankel(c(r:-1:1))); + x=[1 (W\w)']; y=[1 x(2:r+1)*V'+c(2:r+1)]; + dP=x(m+1:-1:1)/x(m+1); nP=y(r+1:-1:1)/x(m+1); +end diff --git a/FOTF Toolbox/paderm.m b/FOTF Toolbox/paderm.m new file mode 100644 index 0000000..5ce2064 --- /dev/null +++ b/FOTF Toolbox/paderm.m @@ -0,0 +1,8 @@ +function [n,d]=paderm(tau,r,k) +% paderm Pade approximation of TFs with different orders + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + c(1)=1; for i=2:r+k+1, c(i)=-c(i-1)*tau/(i-1); end + Gr=pade_app(c,r,k); n=Gr.num{1}(k-r+1:end); d=Gr.den{1}; +end diff --git a/FOTF Toolbox/pepc_nlfode.m b/FOTF Toolbox/pepc_nlfode.m new file mode 100644 index 0000000..484e44f --- /dev/null +++ b/FOTF Toolbox/pepc_nlfode.m @@ -0,0 +1,43 @@ +function [y,t]=pepc_nlfode(f,alpha,y0,h,tn,err,key) +% pepc_nlfode - numerical solution of nonlinear single-term FODEs +% +% [y,t]=pepc_nlfode(f,alpha,y0,h,tn,err,key) +% +% f - function handles for the nonlinear explicit FODE +% alpha - the maximum order +% y0 - initial vector of the output and its integer-order derivatives +% h - fixed step-size +% tn - terminate time in the solution +% err - error tolerance +% key - identifier, 0 for with predictor, 1 for bypass predictor, +% 2 for predictor alone +% y, t - the solution vector and time vector + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments + f, alpha(1,1), y0, h(1,1), tn(1,1){mustBePositive}, + err(1,1)=1e-6; key{mustBeMember(key,1:3)}=0 + end + t=0; y1=y0; q=ceil(alpha); a1=alpha+1; m=round(tn/h); + K=h^alpha/alpha/a1; Ga=1/gamma(alpha); + y=[y1 zeros(size(y0,1),m)]; n=length(y1); + for k=0:m-1, tk1=t(end)+h; t=[t,tk1]; ii=0:k; y01=0; + for i=1:q,y01=y01+tk1^(i-1)/factorial(i-1)*y0(:,i); end + if key==1, yp=y(:,k+1); + else, yp=y01; + b=h^alpha/alpha*((k+1-ii).^alpha-(k-ii).^alpha); + for i=0:k, yp=yp+b(i+1)*f(t(i+1),y(:,i+1))*Ga; end + end + if key~=2 + ii=1:k; a2=(k-ii+2).^a1+(k-ii).^a1-2*(k-ii+1).^a1; + a0=k^a1-(k-alpha)*(k+1)^alpha; a=[a0 a2 1]*K; + while (1), y1=y01+a(k+2)*f(tk1,yp)*Ga; + for i=0:k, y1=y1+a(i+1)*f(t(i+1),y(:,i+1))*Ga; end + if (norm(y1-yp)<err||(key==0&&n==1)||key==3), break; + else, yp=y1; end + end + else, y1=yp; end, y(:,k+2)=y1; + end, y=y'; t=t(:); +end diff --git a/FOTF Toolbox/ppoly2sym.m b/FOTF Toolbox/ppoly2sym.m new file mode 100644 index 0000000..75ffd83 --- /dev/null +++ b/FOTF Toolbox/ppoly2sym.m @@ -0,0 +1,14 @@ +function P=ppoly2sym(p,s) +% ppoly2sym - convert ppoly object to symbolic expression +% +% P=ppoly2sym(p,s) +% +% p - a ppoly object +% s - a symbolic variable + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + arguments, p(1,1), s(1,1)=sym('s'); end + p=collect(p); n=length(p.a); P=sym(0); + for i=1:n, P=P+p.a(i)*s^(p.na(i)); end +end diff --git a/FOTF Toolbox/pseudiag.m b/FOTF Toolbox/pseudiag.m new file mode 100644 index 0000000..88468a7 --- /dev/null +++ b/FOTF Toolbox/pseudiag.m @@ -0,0 +1,22 @@ +function Kp=pseudiag(G1,R) +% pseudiag - design of pseudodiagonalisation matrix +% +% Kp=pseudiag(G1,R) +% +% G1 - frequency response of the multivariable plant model, in MFD format +% R - weighting in the responses, optional +% Kp - the pre-compensator matrix + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +A=real(G1); B=imag(G1); [n,m]=size(G1); N=n/m; Kp=[]; +if nargin==1, R=ones(N,1); end +for q=1:m, L=1:m; L(q)=[]; + for i=1:m, for l=1:m, a=0; + for r=1:N, k=(r-1)*m; + a=a+R(r)*sum(A(k+i,L).*A(k+l,L)+B(k+i,L).*B(k+l,L)); + end, + Ap(i,l)=a; + end, end + [x,d]=eig(Ap); [xm,ii]=min(diag(d)); Kp=[Kp; x(:, ii)']; +end diff --git a/FOTF Toolbox/riemannsym.m b/FOTF Toolbox/riemannsym.m new file mode 100644 index 0000000..3f92d86 --- /dev/null +++ b/FOTF Toolbox/riemannsym.m @@ -0,0 +1,20 @@ +function dy=riemannsym(f,alpha,t0,t) +% riemannsym Symbolic computing of Roemann-Liouville derivatives + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + arguments, f(1,1), alpha(1,1), t0(1,1)=0, t(1,1)=symvar(f), end + syms tau; alpha=sym(alpha); + switch class(f) + case 'sym', F=subs(f,t,tau); + case 'symfun', F=f(tau); + otherwise, error('f must be a symbolic expression') + end + if alpha<0, alpha=-alpha; + dy=1/gamma(alpha)*int(F/(t-tau)^(1-alpha),tau,t0,t); + elseif alpha==0, dy=f; + else, n=ceil(alpha); + f1=int(F/(t-tau)^(1+alpha-n),tau,t0,t); + dy=diff(f1,t,n)/gamma(n-alpha); + end +end diff --git a/FOTF Toolbox/rlfdiff.m b/FOTF Toolbox/rlfdiff.m new file mode 100644 index 0000000..1633ed8 --- /dev/null +++ b/FOTF Toolbox/rlfdiff.m @@ -0,0 +1,24 @@ +function [dy,t]=rlfdiff(y,t,r) +% rlfdiff - computation of RL derivatives, not recommended +% +% [dy,t]=rlfdiff(y,t,r) +% +% y, t - the samples of the function at time vector t +% r - the fractional order, can be nagative for integrals +% dy - the Riemann-Liouville derivative of y + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + arguments, y(:,1), t(:,1) double, r(1,1) double, end + [y,h,n]=fdiffcom(y,t); dy1=zeros(1,n); + if r>-1, m=ceil(r)+1; p=m-r; y3=t.^(p-1); + elseif r==-1 + yy=0.5*(y(1:n-1)+y(2:n)).*diff(t); + for i=2:n, dy(i)=dy(i-1)+yy(i-1); end, return + else, m=-r; y3=t.^(m-1); end + for i=1:n, dy1(i)=y(i:-1:1).'*(y3(1:i)); end + if r>-1, dy=diff(dy1,m)/(h^(m-1))/gamma(p); t=t(1:n-m); + else, dy=dy1*h/gamma(m); end, dy=dy(:); +end + diff --git a/FOTF Toolbox/sfun_mls.m b/FOTF Toolbox/sfun_mls.m new file mode 100644 index 0000000..a655943 --- /dev/null +++ b/FOTF Toolbox/sfun_mls.m @@ -0,0 +1,17 @@ +function [sys,x0,str,ts]=sfun_mls(t,x,u,flag,a) +% sfun_mls - S-function version of Mittag-Leffler function for Simulink +% +% The additional parameter a for Mittag-Leffler coefficients + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +switch flag + case 0, sizes = simsizes; + sizes.NumContStates = 0; sizes.NumDiscStates = 0; + sizes.NumOutputs = 1; sizes.NumInputs = 1; + sizes.DirFeedthrough = 1; sizes.NumSampleTimes = 1; + sys = simsizes(sizes); x0 = []; str = []; ts = [-1 0]; + case 3, sys = ml_func(a,u); + case {1,2,4,9}, sys = []; + otherwise, error(['Unhandled flag = ',num2str(flag)]); +end diff --git a/FOTF Toolbox/simulink2019b/bench/bp1_model.slx b/FOTF Toolbox/simulink2019b/bench/bp1_model.slx new file mode 100644 index 0000000..1f621a0 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp1_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp1_model2.slx b/FOTF Toolbox/simulink2019b/bench/bp1_model2.slx new file mode 100644 index 0000000..88329a1 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp1_model2.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp2_model.slx b/FOTF Toolbox/simulink2019b/bench/bp2_model.slx new file mode 100644 index 0000000..617d990 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp2_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp3_fcn.m b/FOTF Toolbox/simulink2019b/bench/bp3_fcn.m new file mode 100644 index 0000000..0d37ff3 --- /dev/null +++ b/FOTF Toolbox/simulink2019b/bench/bp3_fcn.m @@ -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 diff --git a/FOTF Toolbox/simulink2019b/bench/bp3_model.slx b/FOTF Toolbox/simulink2019b/bench/bp3_model.slx new file mode 100644 index 0000000..ac8ef54 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp3_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp4_fcn.m b/FOTF Toolbox/simulink2019b/bench/bp4_fcn.m new file mode 100644 index 0000000..f37c049 --- /dev/null +++ b/FOTF Toolbox/simulink2019b/bench/bp4_fcn.m @@ -0,0 +1,4 @@ +function y=bp4_fcn(t) + y=1/8*t*(ml_func([1,1.8],-t/2)*ml_func([1,1.2],-t/2)+... + ml_func([1,1.7],-t/2)*ml_func([1,1.3],-t/2)); +end diff --git a/FOTF Toolbox/simulink2019b/bench/bp4_model.slx b/FOTF Toolbox/simulink2019b/bench/bp4_model.slx new file mode 100644 index 0000000..cf390fa Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp4_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp5_fcn.m b/FOTF Toolbox/simulink2019b/bench/bp5_fcn.m new file mode 100644 index 0000000..74e8bab --- /dev/null +++ b/FOTF Toolbox/simulink2019b/bench/bp5_fcn.m @@ -0,0 +1,5 @@ +function y=bp5_fcn(u) + y=[(((u(2)-0.5)*(u(3)-0.3))^(1/5)+sqrt(u(4)))/sqrt(pi); + (u(1)-1)*gamma(2.2); (u(2)-0.5)*gamma(2.3)/gamma(2.2)]; + y=real(y); %{\kaishu\,因未知原因混入微小的虚数,所以需要提取实部} +end \ No newline at end of file diff --git a/FOTF Toolbox/simulink2019b/bench/bp5_model.slx b/FOTF Toolbox/simulink2019b/bench/bp5_model.slx new file mode 100644 index 0000000..946362c Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp5_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp5_model2.slx b/FOTF Toolbox/simulink2019b/bench/bp5_model2.slx new file mode 100644 index 0000000..76a2d9e Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp5_model2.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp5a_fcn2.m b/FOTF Toolbox/simulink2019b/bench/bp5a_fcn2.m new file mode 100644 index 0000000..81a9ec3 --- /dev/null +++ b/FOTF Toolbox/simulink2019b/bench/bp5a_fcn2.m @@ -0,0 +1,6 @@ +function y=c8mfss3a(u) + y=[2/sqrt(pi)*(((u(2)-0.3)*(u(3)-0.5*u(1)))^(1/5)+sqrt(u(5))); + gamma(1.4)/gamma(1.3)*((u(1)-1)/2)^0.3; + u(4); gamma(3.1)/gamma(1.6)*sqrt((u(2)-0.3)^3)]; + y=real(y); %{\kaishu\,因未知原因混入微小的虚数,所以需要提取实部} +end diff --git a/FOTF Toolbox/simulink2019b/bench/bp5a_model.slx b/FOTF Toolbox/simulink2019b/bench/bp5a_model.slx new file mode 100644 index 0000000..50580ce Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp5a_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp5a_model2.slx b/FOTF Toolbox/simulink2019b/bench/bp5a_model2.slx new file mode 100644 index 0000000..a4508ae Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp5a_model2.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp5b_fcn.m b/FOTF Toolbox/simulink2019b/bench/bp5b_fcn.m new file mode 100644 index 0000000..27715ae --- /dev/null +++ b/FOTF Toolbox/simulink2019b/bench/bp5b_fcn.m @@ -0,0 +1,6 @@ +function y=bp5b_fcn(u) + y=[4/sqrt(pi)*((u(2)-0.3)*(u(3)-0.5*u(1)))^(1/5); + gamma(1.4)/gamma(1.3)*((u(1)-1)/2)^0.3; + gamma(3.1)/gamma(1.6)*sqrt((u(2)-0.3)^3)]; + y=real(y); %{\kaishu\,因未知原因混入微小的虚数,所以需要提取实部} +end diff --git a/FOTF Toolbox/simulink2019b/bench/bp6_fcn.m b/FOTF Toolbox/simulink2019b/bench/bp6_fcn.m new file mode 100644 index 0000000..dcf4a44 --- /dev/null +++ b/FOTF Toolbox/simulink2019b/bench/bp6_fcn.m @@ -0,0 +1,3 @@ +function y = bp6_fcn(u) +y=u^(1.5-sqrt(2))*exp(u)*... + ml_func([1,3-sqrt(2)],-u)./ml_func([1,1.5],-u); diff --git a/FOTF Toolbox/simulink2019b/bench/bp6_model.slx b/FOTF Toolbox/simulink2019b/bench/bp6_model.slx new file mode 100644 index 0000000..14ced1f Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp6_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp6a_model.slx b/FOTF Toolbox/simulink2019b/bench/bp6a_model.slx new file mode 100644 index 0000000..4290392 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp6a_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp7_model.slx b/FOTF Toolbox/simulink2019b/bench/bp7_model.slx new file mode 100644 index 0000000..492c089 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp7_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp7_opts.m b/FOTF Toolbox/simulink2019b/bench/bp7_opts.m new file mode 100644 index 0000000..caed381 --- /dev/null +++ b/FOTF Toolbox/simulink2019b/bench/bp7_opts.m @@ -0,0 +1,5 @@ +function y=bp7_opts(x) + W=get_param(gcs,'ModelWorkspace'); assignin(W,'a',x(1)) + try, txy=sim('bp7_model'); y0=txy.yout; y=abs(y0(end)-exp(-1)); + catch, y=10; end +end diff --git a/FOTF Toolbox/simulink2019b/bench/bp7a_model.slx b/FOTF Toolbox/simulink2019b/bench/bp7a_model.slx new file mode 100644 index 0000000..7fe6e8b Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp7a_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp8_fcn.m b/FOTF Toolbox/simulink2019b/bench/bp8_fcn.m new file mode 100644 index 0000000..cef9868 --- /dev/null +++ b/FOTF Toolbox/simulink2019b/bench/bp8_fcn.m @@ -0,0 +1,3 @@ +function y = bp7_fcn(u) +y=u^(1.5-sqrt(2))*exp(u)*... + ml_func([1,3-sqrt(2)],-u)./ml_func([1,1.5],-u); diff --git a/FOTF Toolbox/simulink2019b/bench/bp8_model.slx b/FOTF Toolbox/simulink2019b/bench/bp8_model.slx new file mode 100644 index 0000000..53a95ee Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp8_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp8a_fcn.m b/FOTF Toolbox/simulink2019b/bench/bp8a_fcn.m new file mode 100644 index 0000000..052c88b --- /dev/null +++ b/FOTF Toolbox/simulink2019b/bench/bp8a_fcn.m @@ -0,0 +1,4 @@ +function y=bp8a_fcn(t) + y=t^(1.5-sqrt(2))*exp(t-0.3)*... + ml_func([1,3-sqrt(2)],-t)./ml_func([1,1.5],-t); +end diff --git a/FOTF Toolbox/simulink2019b/bench/bp8a_model.slx b/FOTF Toolbox/simulink2019b/bench/bp8a_model.slx new file mode 100644 index 0000000..5099ee2 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp8a_model.slx differ diff --git a/FOTF Toolbox/simulink2019b/bench/bp_models.slx b/FOTF Toolbox/simulink2019b/bench/bp_models.slx new file mode 100644 index 0000000..1f27a30 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/bench/bp_models.slx differ diff --git a/FOTF Toolbox/simulink2019b/c10mpdm2.slx b/FOTF Toolbox/simulink2019b/c10mpdm2.slx new file mode 100644 index 0000000..cfc798b Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c10mpdm2.slx differ diff --git a/FOTF Toolbox/simulink2019b/c5mimp.slx b/FOTF Toolbox/simulink2019b/c5mimp.slx new file mode 100644 index 0000000..34f833e Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c5mimp.slx differ diff --git a/FOTF Toolbox/simulink2019b/c5mqft.slx b/FOTF Toolbox/simulink2019b/c5mqft.slx new file mode 100644 index 0000000..0195dc0 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c5mqft.slx differ diff --git a/FOTF Toolbox/simulink2019b/c5msim1.slx b/FOTF Toolbox/simulink2019b/c5msim1.slx new file mode 100644 index 0000000..11b0fad Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c5msim1.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mblk1a.slx b/FOTF Toolbox/simulink2019b/c8mblk1a.slx new file mode 100644 index 0000000..102cde2 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mblk1a.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mblk1b.slx b/FOTF Toolbox/simulink2019b/c8mblk1b.slx new file mode 100644 index 0000000..5a07707 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mblk1b.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mblk2.slx b/FOTF Toolbox/simulink2019b/c8mblk2.slx new file mode 100644 index 0000000..73e7405 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mblk2.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mblk3.slx b/FOTF Toolbox/simulink2019b/c8mblk3.slx new file mode 100644 index 0000000..4549a00 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mblk3.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mblk5.slx b/FOTF Toolbox/simulink2019b/c8mblk5.slx new file mode 100644 index 0000000..c6ef1a5 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mblk5.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mchaos.slx b/FOTF Toolbox/simulink2019b/c8mchaos.slx new file mode 100644 index 0000000..97692a3 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mchaos.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mchaos2.slx b/FOTF Toolbox/simulink2019b/c8mchaos2.slx new file mode 100644 index 0000000..70854b6 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mchaos2.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mchaos_v.slx b/FOTF Toolbox/simulink2019b/c8mchaos_v.slx new file mode 100644 index 0000000..e47bde4 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mchaos_v.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mchuasim.slx b/FOTF Toolbox/simulink2019b/c8mchuasim.slx new file mode 100644 index 0000000..d7362e3 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mchuasim.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mexp2s.slx b/FOTF Toolbox/simulink2019b/c8mexp2s.slx new file mode 100644 index 0000000..f925ede Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mexp2s.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mfpid.slx b/FOTF Toolbox/simulink2019b/c8mfpid.slx new file mode 100644 index 0000000..5c023f8 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mfpid.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mfpid1.slx b/FOTF Toolbox/simulink2019b/c8mfpid1.slx new file mode 100644 index 0000000..409d912 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mfpid1.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mimps.slx b/FOTF Toolbox/simulink2019b/c8mimps.slx new file mode 100644 index 0000000..be588ba Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mimps.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mmimo.slx b/FOTF Toolbox/simulink2019b/c8mmimo.slx new file mode 100644 index 0000000..cf09c5c Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mmimo.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mnlf1.slx b/FOTF Toolbox/simulink2019b/c8mnlf1.slx new file mode 100644 index 0000000..c921fde Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mnlf1.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mnlf2.slx b/FOTF Toolbox/simulink2019b/c8mnlf2.slx new file mode 100644 index 0000000..52c9b10 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mnlf2.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mnlf3.slx b/FOTF Toolbox/simulink2019b/c8mnlf3.slx new file mode 100644 index 0000000..f090493 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mnlf3.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mod_3.slx b/FOTF Toolbox/simulink2019b/c8mod_3.slx new file mode 100644 index 0000000..264608c Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mod_3.slx differ diff --git a/FOTF Toolbox/simulink2019b/c8mstep.slx b/FOTF Toolbox/simulink2019b/c8mstep.slx new file mode 100644 index 0000000..c04fa6c Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c8mstep.slx differ diff --git a/FOTF Toolbox/simulink2019b/c9mdde1a.slx b/FOTF Toolbox/simulink2019b/c9mdde1a.slx new file mode 100644 index 0000000..b32414c Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c9mdde1a.slx differ diff --git a/FOTF Toolbox/simulink2019b/c9mdde1b.slx b/FOTF Toolbox/simulink2019b/c9mdde1b.slx new file mode 100644 index 0000000..150146e Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c9mdde1b.slx differ diff --git a/FOTF Toolbox/simulink2019b/c9mdde3.slx b/FOTF Toolbox/simulink2019b/c9mdde3.slx new file mode 100644 index 0000000..76821bc Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c9mdde3.slx differ diff --git a/FOTF Toolbox/simulink2019b/c9mfpid2.slx b/FOTF Toolbox/simulink2019b/c9mfpid2.slx new file mode 100644 index 0000000..267a2fb Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c9mfpid2.slx differ diff --git a/FOTF Toolbox/simulink2019b/c9mfpids.slx b/FOTF Toolbox/simulink2019b/c9mfpids.slx new file mode 100644 index 0000000..9a12c5a Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c9mfpids.slx differ diff --git a/FOTF Toolbox/simulink2019b/c9mimp3.slx b/FOTF Toolbox/simulink2019b/c9mimp3.slx new file mode 100644 index 0000000..e002855 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c9mimp3.slx differ diff --git a/FOTF Toolbox/simulink2019b/c9mplant.slx b/FOTF Toolbox/simulink2019b/c9mplant.slx new file mode 100644 index 0000000..6d5a25c Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c9mplant.slx differ diff --git a/FOTF Toolbox/simulink2019b/c9mvofuz.slx b/FOTF Toolbox/simulink2019b/c9mvofuz.slx new file mode 100644 index 0000000..78a5336 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c9mvofuz.slx differ diff --git a/FOTF Toolbox/simulink2019b/c9mvofuz2.slx b/FOTF Toolbox/simulink2019b/c9mvofuz2.slx new file mode 100644 index 0000000..ef7db50 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/c9mvofuz2.slx differ diff --git a/FOTF Toolbox/simulink2019b/fotflib.slx b/FOTF Toolbox/simulink2019b/fotflib.slx new file mode 100644 index 0000000..1874570 Binary files /dev/null and b/FOTF Toolbox/simulink2019b/fotflib.slx differ diff --git a/FOTF Toolbox/simulink2019b/pidctrl_model.slx b/FOTF Toolbox/simulink2019b/pidctrl_model.slx new file mode 100644 index 0000000..c521efd Binary files /dev/null and b/FOTF Toolbox/simulink2019b/pidctrl_model.slx differ diff --git a/FOTF Toolbox/slblocks.m b/FOTF Toolbox/slblocks.m new file mode 100644 index 0000000..95329d0 --- /dev/null +++ b/FOTF Toolbox/slblocks.m @@ -0,0 +1,10 @@ +function blkStruct = slblocks +%SLBLOCKS Defines the block library for FOTF Toolbox or Blockset. + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 28 March, 2017 +% Last modified 18 May, 2022 + blkStruct.Name = sprintf('%s\n%s','FOTF Blockset','Toolbox'); + blkStruct.OpenFcn = 'fotflib'; + blkStruct.IsFlat = 1; +end diff --git a/FOTF Toolbox/srid_fod.m b/FOTF Toolbox/srid_fod.m new file mode 100644 index 0000000..d6e5b7a --- /dev/null +++ b/FOTF Toolbox/srid_fod.m @@ -0,0 +1,116 @@ +% Step response invariant discretization of fractional order integrators +% +% srid_fod function is prepared to compute a discrete-time finite dimensional +% (z) transfer function to approximate a continuous-time fractional order +% integrator/differentiator function s^r, where "s" is the Laplace transform variable, and "r" is a +% real number in the range of (-1,1). s^r is called a fractional order +% differentiator if 0 < r < 1 and a fractional order integrator if -1 < r < 0. +% +% The proposed approximation keeps the step response "invariant" +% +% IN: +% r: the fractional order +% Ts: the sampling period +% norder: the finite order of the approximate z-transfer function +% (the orders of denominator and numerator z-polynomial are the same) +% OUT: +% sr: returns the LTI object that approximates the s^r in the sense +% of step response. +% TEST CODE +% dfod=srid_fod(-.5,.01,5);figure;pzmap(dfod) +% +% Reference: YangQuan Chen. "Impulse-invariant and step-invariant +% discretization of fractional order integrators and differentiators". +% August 2008. CSOIS AFC (Applied Fractional Calculus) Seminar. +% http://fractionalcalculus.googlepages.com/ +% -------------------------------------------------------------------- +% YangQuan Chen, Ph.D, Associate Professor and Graduate Coordinator +% Department of Electrical and Computer Engineering, +% Director, Center for Self-Organizing and Intelligent Systems (CSOIS) +% Utah State University, 4120 Old Main Hill, Logan, UT 84322-4120, USA +% E: yqchen@ece.usu.edu or yqchen@ieee.org, T/F: 1(435)797-0148/3054; +% W: http://www.csois.usu.edu or http://yangquan.chen.googlepages.com +% -------------------------------------------------------------------- +% +% 9/6/2009 +% Only supports when r in (-1,0). That is fractional order integrator +% To get fractional order differentiator, use 1/sr. +% +% See also irid_fod.m at +% http://www.mathworks.com/matlabcentral/files/21342/irid_fod.m + +function [sr]=srid_fod(r,Ts,norder) +if nargin<3; norder=5; end +if Ts < 0 , sprintf('%s','Sampling period has to be positive'), return, end +if r>=0 | r<= -1, sprintf('%s','The fractional order should be in (-1,0)'), return, end +if norder<2, sprintf('%s','The order of the approximate transfer function has to be greater than 1'), return, end +% +L=200; %number of points of the step response function h(n) +Taxis=[0:L-1]*Ts;r0=r;r=abs(r);n=0:L-1;h=[(Ts^r)*(n.^(r))/gamma(r)/r]; +[b,a] = stmcb(h,ones(size(h)),norder,norder,100);sr=tf(b,a,Ts); + +% Note that the generated "sr" LTI object might be nonminimum phase! +% although a good fitting is obtained + +if 1 % change this to 0 if you do not want to see plots +% approximated h() +wmax0=2*pi/Ts/2; % rad./sec. Nyquist frequency +hhat=step(sr,Taxis); +% figure;plot(Taxis,hhat,'r');hold on;plot(Taxis,h,'ok') +% xlabel('time');ylabel('step response'); legend(['approximated for 1/s^{',num2str(abs(r)),'}'],'true') +% figure; +wmax=floor(1+ log10(wmax0) ); wmin=wmax-5; +w=logspace(wmin,wmax,1000); +srfr=(j*w).^(-r); +% subplot(2,1,1) +% semilogx(w,20*log10(abs(srfr)),'r');grid on +% hold on; +srfrhat=freqresp(sr,w); %semilogx(w,20*log10(abs(reshape(srfrhat, 1000, 1))),'k');grid on +% xlabel('frequency in Hz');ylabel('dB'); +% legend('true mag. Bode','approximated mag. Bode') +% subplot(2,1,2) +% semilogx(w,(180/pi) * (angle(srfr)),'r');grid on;hold on +% semilogx(w,(180/pi) * (angle(reshape(srfrhat, 1000, 1))),'k');grid on +% xlabel('frequency in Hz');ylabel('degree'); +% legend('true phase Bode','approximated Phase Bode') +% figure;pzmap(sr) +end % if 1 +% get stable, minimum phase approximation. +[zz,pp,kk]=zpkdata(sr,'v'); +for i=1:norder; + if abs(zz(i)) > 1 + kk=kk*(-zz(i)); zz(i)=1/zz(i); + sprintf('%s','nonminimum phase approximation - forced minimum phase!!'), + end + if abs(pp(i)) > 1 + kk=kk/(-pp(i)); pp(i)=1/pp(i); + sprintf('%s','unstable approximation - forced stable!!'), + end +end +sr1=zpk(zz,pp,kk,Ts); + +if 1 % change this to 0 if you do not want to see plots +% approximated h() +wmax0=2*pi/Ts/2; % rad./sec. Nyquist frequency +hhat=step(sr1,Taxis); +% figure;plot(Taxis,hhat,'r');hold on;plot(Taxis,h,'ok') +% xlabel('time');ylabel('step response'); legend(['approximated for 1/s^{',num2str(abs(r)),'}'],'true') +% figure; +wmax=floor(1+ log10(wmax0) ); wmin=wmax-5; +w=logspace(wmin,wmax,1000); +srfr=(j*w).^(-r); +% subplot(2,1,1) +% semilogx(w,20*log10(abs(srfr)),'r');grid on +% hold on; +srfrhat=freqresp(sr1,w); %semilogx(w,20*log10(abs(reshape(srfrhat, 1000, 1))),'k');grid on +% xlabel('frequency in Hz');ylabel('dB'); +% legend('true mag. Bode','approximated mag. Bode') +% subplot(2,1,2) +% semilogx(w,(180/pi) * (angle(srfr)),'r');grid on;hold on +% semilogx(w,(180/pi) * (angle(reshape(srfrhat, 1000, 1))),'k');grid on +% xlabel('frequency in Hz');ylabel('degree'); +% legend('true phase Bode','approximated Phase Bode') +% figure;pzmap(sr1) +end % if 1 + + \ No newline at end of file diff --git a/FOTF Toolbox/svec2sl.m b/FOTF Toolbox/svec2sl.m new file mode 100644 index 0000000..a9f1292 --- /dev/null +++ b/FOTF Toolbox/svec2sl.m @@ -0,0 +1,34 @@ +function key=svec2sl(v) +% svec2sl - construct vectorized s operator block, called internally +% in FOTFLIB blockset + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + key=1; M=gcb; + m=length(v); open_system(M,'loadonly'); + set_param(M,'Location',[100,100,800,500]); + ll=get_param(M,'lines'); + bb=get_param(M,'blocks'); + for i=1:length(ll), delete_line(ll(i).Handle); end + for i=1:length(bb), str=char(bb(i)); + if ~strcmp(str,'In1') && ~strcmp(str,'Out1') + delete_block([M,'/',str]); + end, end + add_block('built-in/Demux',[M '/Demux'],'Position',[100,40,105,60],... + 'Outputs',int2str(m)); + add_block('built-in/Mux',[M '/Mux'],'Position',[200,40,205,60],... + 'Inputs',int2str(m)); + for k=1:length(v) + blk=[M '/G' int2str(k)]; + add_block('cstblocks/LTI System',blk,... + 'Position',[60,50+k*30,90,70+k*30],'sys',['G(' int2str(k) ')']); + add_line(M,['Demux/' int2str(k)],['G' int2str(k) ,'/1'],'autorouting','on') + add_line(M,['G' int2str(k) '/1'],['Mux/' int2str(k)],'autorouting','on') + end + add_block('built-in/Integrator',[M '/Integrator'],... + 'Position',[250,80,275,120],... + 'InitialCondition','x0'); + add_line(M,'Integrator/1','Out1/1','autorouting','on') + add_line(M,'Mux/1','Integrator/1','autorouting','on') + add_line(M,'In1/1','Demux/1','autorouting','on') +end diff --git a/FOTF Toolbox/sym2fotf.m b/FOTF Toolbox/sym2fotf.m new file mode 100644 index 0000000..5c514c4 --- /dev/null +++ b/FOTF Toolbox/sym2fotf.m @@ -0,0 +1,14 @@ +function G1=sym2fotf(G) +% sym2fotf convert symbolic expression to FOTF matrix + +% Copyright (c) Dingyu Xue, Northeastern University, China +% Last modified 18 May, 2022 + [n,m]=size(G); G1=fotf(zeros(n,m)); + for i=1:n, for j=1:m + [num,den]=numden(G(i,j)); + G1(i,j)=fotf(sym2ppoly(den),sym2ppoly(num)); +end, end, end +function p1=sym2ppoly(p) + syms s real; [C,T]=coeffs(p); T=log(T)/log(s); T=simplify(subs(T,s,2)); + p1=ppoly(double(C),double(T)); +end \ No newline at end of file diff --git a/FOTF Toolbox/voffuzzy.fis b/FOTF Toolbox/voffuzzy.fis new file mode 100644 index 0000000..fd8cac2 --- /dev/null +++ b/FOTF Toolbox/voffuzzy.fis @@ -0,0 +1,147 @@ +[System] +Name='voffuzzy' +Type='mamdani' +Version=2.0 +NumInputs=2 +NumOutputs=5 +NumRules=49 +AndMethod='min' +OrMethod='max' +ImpMethod='min' +AggMethod='max' +DefuzzMethod='centroid' + +[Input1] +Name='e' +Range=[-0.3 0.3] +NumMFs=7 +MF1='NB':'zmf',[-0.3 -0.1] +MF2='NM':'trimf',[-0.3 -0.2 0] +MF3='NS':'trimf',[-0.3 -0.1 0.1] +MF4='Z':'trimf',[-0.2 0 0.2] +MF5='PS':'trimf',[-0.1 0.1 0.3] +MF6='PM':'trimf',[0 0.2 0.3] +MF7='PB':'smf',[0.1 0.3] + +[Input2] +Name='ec' +Range=[-0.3 0.3] +NumMFs=7 +MF1='NB':'zmf',[-0.3 -0.1] +MF2='NM':'trimf',[-0.3 -0.2 0] +MF3='NS':'trimf',[-0.3 -0.1 0.1] +MF4='Z':'trimf',[-0.2 0 0.2] +MF5='PS':'trimf',[-0.1 0.1 0.3] +MF6='PM':'trimf',[0 0.2 0.3] +MF7='PB':'smf',[0.1 0.3] + +[Output1] +Name='kp' +Range=[-3 3] +NumMFs=7 +MF1='NB':'zmf',[-3 -1] +MF2='NM':'trimf',[-3 -2 -1] +MF3='NS':'trimf',[-2 -1 0] +MF4='Z':'trimf',[-1 0 1] +MF5='PS':'trimf',[0 1 2] +MF6='PM':'trimf',[1 2 3] +MF7='PB':'smf',[1 3] + +[Output2] +Name='ki' +Range=[-3 3] +NumMFs=7 +MF1='NB':'zmf',[-3 -1] +MF2='NM':'trimf',[-3 -2 -1] +MF3='NS':'trimf',[-2 -1 0] +MF4='Z':'trimf',[-1 0 1] +MF5='PS':'trimf',[0 1 2] +MF6='PM':'trimf',[1 2 3] +MF7='PB':'smf',[1 3] + +[Output3] +Name='kd' +Range=[-3 3] +NumMFs=7 +MF1='NB':'zmf',[-3 -1] +MF2='NM':'trimf',[-3 -2 -1] +MF3='NS':'trimf',[-2 -1 0] +MF4='Z':'trimf',[-1 0 1] +MF5='PS':'trimf',[0 1 2] +MF6='PM':'trimf',[1 2 3] +MF7='PB':'smf',[1 3] + +[Output4] +Name='lambda' +Range=[-0.3 0.3] +NumMFs=7 +MF1='NB':'zmf',[-0.3 -0.1] +MF2='NM':'trimf',[-0.3 -0.2 -0.1] +MF3='NS':'trimf',[-0.2 -0.1 0] +MF4='Z':'trimf',[-0.1 0 0.1] +MF5='PS':'trimf',[0 0.1 0.2] +MF6='PM':'trimf',[0.1 0.2 0.3] +MF7='PB':'smf',[0.1 0.3] + +[Output5] +Name='mu' +Range=[-0.3 0.3] +NumMFs=7 +MF1='NB':'zmf',[-0.3 -0.1] +MF2='NM':'trimf',[-0.3 -0.2 -0.1] +MF3='NS':'trimf',[-0.2 -0.1 0] +MF4='Z':'trimf',[-0.1 0 0.1] +MF5='PS':'trimf',[0 0.1 0.2] +MF6='PM':'trimf',[0.1 0.2 0.3] +MF7='PB':'smf',[0.1 0.3] + +[Rules] +1 1, 1 7 3 7 3 (1) : 1 +1 2, 1 7 5 7 5 (1) : 1 +1 3, 2 6 7 6 7 (1) : 1 +1 4, 2 6 7 6 7 (1) : 1 +1 5, 2 5 7 5 7 (1) : 1 +1 6, 4 4 6 4 6 (1) : 1 +1 7, 4 4 3 4 3 (1) : 1 +2 1, 1 7 5 7 5 (1) : 1 +2 2, 1 7 5 7 5 (1) : 1 +2 3, 2 6 7 6 7 (1) : 1 +2 4, 3 5 6 5 6 (1) : 1 +2 5, 3 5 6 5 6 (1) : 1 +2 6, 4 4 5 4 5 (1) : 1 +2 7, 5 4 4 4 4 (1) : 1 +3 1, 2 7 4 7 4 (1) : 1 +3 2, 2 6 5 6 5 (1) : 1 +3 3, 2 5 6 5 6 (1) : 1 +3 4, 3 5 6 5 6 (1) : 1 +3 5, 4 4 5 4 5 (1) : 1 +3 6, 5 3 5 3 5 (1) : 1 +3 7, 5 3 4 3 4 (1) : 1 +4 1, 2 6 4 6 4 (1) : 1 +4 2, 2 6 5 6 5 (1) : 1 +4 3, 3 5 5 5 5 (1) : 1 +4 4, 4 4 5 4 5 (1) : 1 +4 5, 5 3 5 3 5 (1) : 1 +4 6, 6 2 5 2 5 (1) : 1 +4 7, 6 2 4 2 4 (1) : 1 +5 1, 3 6 4 6 4 (1) : 1 +5 2, 3 5 4 5 4 (1) : 1 +5 3, 4 4 4 4 4 (1) : 1 +5 4, 5 3 4 3 4 (1) : 1 +5 5, 5 3 4 3 4 (1) : 1 +5 6, 6 2 4 2 4 (1) : 1 +5 7, 6 1 4 1 4 (1) : 1 +6 1, 3 4 1 4 1 (1) : 1 +6 2, 4 4 3 4 3 (1) : 1 +6 3, 5 3 3 3 3 (1) : 1 +6 4, 6 3 3 3 3 (1) : 1 +6 5, 6 2 3 2 3 (1) : 1 +6 6, 6 1 3 1 3 (1) : 1 +6 7, 7 1 1 1 1 (1) : 1 +7 1, 4 4 1 4 1 (1) : 1 +7 2, 4 4 2 4 2 (1) : 1 +7 3, 6 3 2 3 2 (1) : 1 +7 4, 6 2 2 2 2 (1) : 1 +7 5, 6 2 3 2 3 (1) : 1 +7 6, 7 1 3 1 3 (1) : 1 +7 7, 7 1 1 1 1 (1) : 1 diff --git a/FractionOrderSystem.prj b/FractionOrderSystem.prj new file mode 100644 index 0000000..92c6696 --- /dev/null +++ b/FractionOrderSystem.prj @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<MATLABProject xmlns="http://www.mathworks.com/MATLABProjectFile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"/> diff --git a/Order1D8System.slx b/Order1D8System.slx new file mode 100644 index 0000000..1847103 Binary files /dev/null and b/Order1D8System.slx differ diff --git a/Order2D2System.slx b/Order2D2System.slx new file mode 100644 index 0000000..249bf82 Binary files /dev/null and b/Order2D2System.slx differ diff --git a/Order2System.slx b/Order2System.slx new file mode 100644 index 0000000..753510a Binary files /dev/null and b/Order2System.slx differ diff --git a/eigOfLaplacianAndB.m b/eigOfLaplacianAndB.m new file mode 100644 index 0000000..02c260a --- /dev/null +++ b/eigOfLaplacianAndB.m @@ -0,0 +1,5 @@ +function e = eigOfLaplacianAndB(A,B) +G = graph(A); +L = laplacian(G); +e = eig(-(L+B)); +end \ No newline at end of file diff --git a/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/9k1RzOh7zpBXUjLNFUvoqUuG9kUd.xml b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/9k1RzOh7zpBXUjLNFUvoqUuG9kUd.xml new file mode 100644 index 0000000..efd4460 --- /dev/null +++ b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/9k1RzOh7zpBXUjLNFUvoqUuG9kUd.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Ref="FOTF Toolbox/Simulink" Type="Relative"/> \ No newline at end of file diff --git a/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/9k1RzOh7zpBXUjLNFUvoqUuG9kUp.xml b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/9k1RzOh7zpBXUjLNFUvoqUuG9kUp.xml new file mode 100644 index 0000000..04af174 --- /dev/null +++ b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/9k1RzOh7zpBXUjLNFUvoqUuG9kUp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="f212c8d2-faac-4d6d-be83-4b6b2852258c" type="Reference"/> \ No newline at end of file diff --git a/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/LhkizjxdCxVKQpPYj_suunWcPrUd.xml b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/LhkizjxdCxVKQpPYj_suunWcPrUd.xml new file mode 100644 index 0000000..5359b72 --- /dev/null +++ b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/LhkizjxdCxVKQpPYj_suunWcPrUd.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Ref="FOTF Toolbox" Type="Relative"/> \ No newline at end of file diff --git a/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/LhkizjxdCxVKQpPYj_suunWcPrUp.xml b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/LhkizjxdCxVKQpPYj_suunWcPrUp.xml new file mode 100644 index 0000000..2b0b929 --- /dev/null +++ b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/LhkizjxdCxVKQpPYj_suunWcPrUp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="300992b1-6bbc-4254-b2d1-408f55d95675" type="Reference"/> \ No newline at end of file diff --git a/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/wHOsv-7DUpZQCvTjWyWwA0y_zo8d.xml b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/wHOsv-7DUpZQCvTjWyWwA0y_zo8d.xml new file mode 100644 index 0000000..aee0cde --- /dev/null +++ b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/wHOsv-7DUpZQCvTjWyWwA0y_zo8d.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Ref="" Type="Relative"/> \ No newline at end of file diff --git a/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/wHOsv-7DUpZQCvTjWyWwA0y_zo8p.xml b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/wHOsv-7DUpZQCvTjWyWwA0y_zo8p.xml new file mode 100644 index 0000000..f83b394 --- /dev/null +++ b/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/wHOsv-7DUpZQCvTjWyWwA0y_zo8p.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="167c326b-de0b-419d-8f8d-b43e066fa22d" type="Reference"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml new file mode 100644 index 0000000..f679d8f --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Name="测试" ReadOnly="READ_ONLY"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml new file mode 100644 index 0000000..14fcc34 --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="test" type="Label"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml new file mode 100644 index 0000000..3a58db9 --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Name="其他" ReadOnly="READ_ONLY"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml new file mode 100644 index 0000000..9916b1e --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="other" type="Label"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml new file mode 100644 index 0000000..5a03cfa --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Name="便利" ReadOnly="READ_ONLY"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml new file mode 100644 index 0000000..23b0eab --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="convenience" type="Label"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml new file mode 100644 index 0000000..d2efda3 --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Name="无" ReadOnly="READ_ONLY"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml new file mode 100644 index 0000000..70b5b07 --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="none" type="Label"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml new file mode 100644 index 0000000..e3c73f2 --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Name="派生" ReadOnly="READ_ONLY"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml new file mode 100644 index 0000000..817277d --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="derived" type="Label"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml new file mode 100644 index 0000000..8f94f08 --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Name="设计" ReadOnly="READ_ONLY"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml new file mode 100644 index 0000000..15f4e1e --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="design" type="Label"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml new file mode 100644 index 0000000..12a992f --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Name="工件" ReadOnly="READ_ONLY"/> \ No newline at end of file diff --git a/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml new file mode 100644 index 0000000..1aed36c --- /dev/null +++ b/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="artifact" type="Label"/> \ No newline at end of file diff --git a/resources/project/Project.xml b/resources/project/Project.xml new file mode 100644 index 0000000..0232696 --- /dev/null +++ b/resources/project/Project.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info MetadataType="fixedPathV2"/> \ No newline at end of file diff --git a/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml b/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml new file mode 100644 index 0000000..764e8af --- /dev/null +++ b/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info DataType="None" Name="分类" ReadOnly="1" SingleValued="1"/> \ No newline at end of file diff --git a/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml b/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml new file mode 100644 index 0000000..d6808df --- /dev/null +++ b/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="FileClassCategory" type="Category"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/6hVPSbaSMw65ubeu6kAwuQ4qOz0d.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/6hVPSbaSMw65ubeu6kAwuQ4qOz0d.xml new file mode 100644 index 0000000..7a6326b --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/6hVPSbaSMw65ubeu6kAwuQ4qOz0d.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info> + <Category UUID="FileClassCategory"> + <Label UUID="design"/> + </Category> +</Info> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/6hVPSbaSMw65ubeu6kAwuQ4qOz0p.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/6hVPSbaSMw65ubeu6kAwuQ4qOz0p.xml new file mode 100644 index 0000000..e12409e --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/6hVPSbaSMw65ubeu6kAwuQ4qOz0p.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="Order1D8System.slx" type="File"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/OTCLL8epVyu99KeOTQnYrpZrMSwd.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/OTCLL8epVyu99KeOTQnYrpZrMSwd.xml new file mode 100644 index 0000000..7a6326b --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/OTCLL8epVyu99KeOTQnYrpZrMSwd.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info> + <Category UUID="FileClassCategory"> + <Label UUID="design"/> + </Category> +</Info> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/OTCLL8epVyu99KeOTQnYrpZrMSwp.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/OTCLL8epVyu99KeOTQnYrpZrMSwp.xml new file mode 100644 index 0000000..c1a685f --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/OTCLL8epVyu99KeOTQnYrpZrMSwp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="Coop3LeaderFollower2D2.slx" type="File"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/TMK4UzWHdRLhy_w-CHt9y11Q8XAd.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/TMK4UzWHdRLhy_w-CHt9y11Q8XAd.xml new file mode 100644 index 0000000..a75f7a8 --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/TMK4UzWHdRLhy_w-CHt9y11Q8XAd.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/TMK4UzWHdRLhy_w-CHt9y11Q8XAp.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/TMK4UzWHdRLhy_w-CHt9y11Q8XAp.xml new file mode 100644 index 0000000..e93d8f3 --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/TMK4UzWHdRLhy_w-CHt9y11Q8XAp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location=".gitignore" type="File"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/WuBo8ZbG_IzlyM4pm0aw7SU3J48d.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/WuBo8ZbG_IzlyM4pm0aw7SU3J48d.xml new file mode 100644 index 0000000..7a6326b --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/WuBo8ZbG_IzlyM4pm0aw7SU3J48d.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info> + <Category UUID="FileClassCategory"> + <Label UUID="design"/> + </Category> +</Info> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/WuBo8ZbG_IzlyM4pm0aw7SU3J48p.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/WuBo8ZbG_IzlyM4pm0aw7SU3J48p.xml new file mode 100644 index 0000000..4b7bad4 --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/WuBo8ZbG_IzlyM4pm0aw7SU3J48p.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="Coop3LeaderFollower1D8.slx" type="File"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/_W0Q1a1iZMCORGbnsJihTtFJKhkd.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/_W0Q1a1iZMCORGbnsJihTtFJKhkd.xml new file mode 100644 index 0000000..7a6326b --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/_W0Q1a1iZMCORGbnsJihTtFJKhkd.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info> + <Category UUID="FileClassCategory"> + <Label UUID="design"/> + </Category> +</Info> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/_W0Q1a1iZMCORGbnsJihTtFJKhkp.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/_W0Q1a1iZMCORGbnsJihTtFJKhkp.xml new file mode 100644 index 0000000..ba109c7 --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/_W0Q1a1iZMCORGbnsJihTtFJKhkp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="testFactionOde.m" type="File"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/bpJXs9NTHhO1zU2iplVPZqr4KhQd.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/bpJXs9NTHhO1zU2iplVPZqr4KhQd.xml new file mode 100644 index 0000000..7a6326b --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/bpJXs9NTHhO1zU2iplVPZqr4KhQd.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info> + <Category UUID="FileClassCategory"> + <Label UUID="design"/> + </Category> +</Info> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/bpJXs9NTHhO1zU2iplVPZqr4KhQp.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/bpJXs9NTHhO1zU2iplVPZqr4KhQp.xml new file mode 100644 index 0000000..ae5f8b0 --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/bpJXs9NTHhO1zU2iplVPZqr4KhQp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="Order2System.slx" type="File"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/m-cFgXWIVe9w2OpQoE6r12VnA2Md.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/m-cFgXWIVe9w2OpQoE6r12VnA2Md.xml new file mode 100644 index 0000000..7a6326b --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/m-cFgXWIVe9w2OpQoE6r12VnA2Md.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info> + <Category UUID="FileClassCategory"> + <Label UUID="design"/> + </Category> +</Info> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/m-cFgXWIVe9w2OpQoE6r12VnA2Mp.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/m-cFgXWIVe9w2OpQoE6r12VnA2Mp.xml new file mode 100644 index 0000000..c3b8a73 --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/m-cFgXWIVe9w2OpQoE6r12VnA2Mp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="Coop3LeaderFollower2.slx" type="File"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/mD79WtXG050p9qSz6jTBlHgjYrYd.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/mD79WtXG050p9qSz6jTBlHgjYrYd.xml new file mode 100644 index 0000000..7a6326b --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/mD79WtXG050p9qSz6jTBlHgjYrYd.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info> + <Category UUID="FileClassCategory"> + <Label UUID="design"/> + </Category> +</Info> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/mD79WtXG050p9qSz6jTBlHgjYrYp.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/mD79WtXG050p9qSz6jTBlHgjYrYp.xml new file mode 100644 index 0000000..faa65a4 --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/mD79WtXG050p9qSz6jTBlHgjYrYp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="eigOfLaplacianAndB.m" type="File"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/nlmRdkAQpBsqrq5D2YzEVl3Rumkd.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/nlmRdkAQpBsqrq5D2YzEVl3Rumkd.xml new file mode 100644 index 0000000..7a6326b --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/nlmRdkAQpBsqrq5D2YzEVl3Rumkd.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info> + <Category UUID="FileClassCategory"> + <Label UUID="design"/> + </Category> +</Info> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/nlmRdkAQpBsqrq5D2YzEVl3Rumkp.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/nlmRdkAQpBsqrq5D2YzEVl3Rumkp.xml new file mode 100644 index 0000000..0ec6387 --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/nlmRdkAQpBsqrq5D2YzEVl3Rumkp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="Order2D2System.slx" type="File"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/qD-kr16wmwlzR-nIg1IG_vvRrWkd.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/qD-kr16wmwlzR-nIg1IG_vvRrWkd.xml new file mode 100644 index 0000000..a75f7a8 --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/qD-kr16wmwlzR-nIg1IG_vvRrWkd.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/qD-kr16wmwlzR-nIg1IG_vvRrWkp.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/qD-kr16wmwlzR-nIg1IG_vvRrWkp.xml new file mode 100644 index 0000000..0eac8db --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/qD-kr16wmwlzR-nIg1IG_vvRrWkp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location=".gitattributes" type="File"/> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/tP_I7nRDqAI1KN29ZEbj7dn25lUd.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/tP_I7nRDqAI1KN29ZEbj7dn25lUd.xml new file mode 100644 index 0000000..7a6326b --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/tP_I7nRDqAI1KN29ZEbj7dn25lUd.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info> + <Category UUID="FileClassCategory"> + <Label UUID="design"/> + </Category> +</Info> \ No newline at end of file diff --git a/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/tP_I7nRDqAI1KN29ZEbj7dn25lUp.xml b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/tP_I7nRDqAI1KN29ZEbj7dn25lUp.xml new file mode 100644 index 0000000..5445e68 --- /dev/null +++ b/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/tP_I7nRDqAI1KN29ZEbj7dn25lUp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="testGraph.m" type="File"/> \ No newline at end of file diff --git a/resources/project/root/EEtUlUb-dLAdf0KpMVivaUlztwAp.xml b/resources/project/root/EEtUlUb-dLAdf0KpMVivaUlztwAp.xml new file mode 100644 index 0000000..c9d8bed --- /dev/null +++ b/resources/project/root/EEtUlUb-dLAdf0KpMVivaUlztwAp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="Root" type="ProjectPath"/> \ No newline at end of file diff --git a/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml b/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml new file mode 100644 index 0000000..e49b44d --- /dev/null +++ b/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info Name="FractionOrderSystem"/> \ No newline at end of file diff --git a/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml b/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml new file mode 100644 index 0000000..2516b91 --- /dev/null +++ b/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="ProjectData" type="Info"/> \ No newline at end of file diff --git a/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml b/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml new file mode 100644 index 0000000..f12944e --- /dev/null +++ b/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="Root" type="Categories"/> \ No newline at end of file diff --git a/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml b/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml new file mode 100644 index 0000000..67c6ed6 --- /dev/null +++ b/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info location="Root" type="Files"/> \ No newline at end of file diff --git a/resources/project/rootp.xml b/resources/project/rootp.xml new file mode 100644 index 0000000..a75f7a8 --- /dev/null +++ b/resources/project/rootp.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info/> \ No newline at end of file diff --git a/resources/project/uuid-f71d2f8b-bcab-4e87-9be5-0c1d25906e3e.xml b/resources/project/uuid-f71d2f8b-bcab-4e87-9be5-0c1d25906e3e.xml new file mode 100644 index 0000000..a75f7a8 --- /dev/null +++ b/resources/project/uuid-f71d2f8b-bcab-4e87-9be5-0c1d25906e3e.xml @@ -0,0 +1,2 @@ +<?xml version='1.0' encoding='UTF-8'?> +<Info/> \ No newline at end of file diff --git a/testFactionOde.m b/testFactionOde.m new file mode 100644 index 0000000..28def06 --- /dev/null +++ b/testFactionOde.m @@ -0,0 +1,7 @@ +alpha = 0.9; +a = [1 1]; +na = [1.8 0.9]; +t = 0:0.1:5; +u = ones(size(t)); +y = fode_sol(a,na,1,0,u,t); +plot(t,y ); \ No newline at end of file diff --git a/testGraph.m b/testGraph.m new file mode 100644 index 0000000..692b155 --- /dev/null +++ b/testGraph.m @@ -0,0 +1,10 @@ +%% +%简单用例验证只使用位置信息不稳定 +% A --> Leader <-- B +A= [0 1 1; 1 0 0; 1 0 0]; +A1 = [0 1 0; 1 0 1; 0 1 0]; +B = [0 0 0; -1 1 0; -1 0 1]; +e1 = eigOfLaplacianAndB(A,B); +e2 = eigOfLaplacianAndB(A1,B); +L = laplacian(graph(A)); +eig(L) \ No newline at end of file