1 function lam=ArgyrisSolver(h) 2 %%%方形区域 3 [node,elem] = squaremesh([0,1,0,1],h);hm=1/h; 4 showmesh(node,elem); 5 N = size(node,1); NT = size(elem,1); 6 %% Construct Data Structure 7 elem2dof = zeros(NT,21); 8 elem2dof(:,1:3) = elem; 9 elem2dof(:,4:6) = elem+N; 10 elem2dof(:,7:9) = elem+2*N; 11 elem2dof(:,10:12) = elem+3*N; 12 elem2dof(:,13:15) = elem+4*N; 13 elem2dof(:,16:18) = elem+5*N; 14 totalEdge = uint32(sort([elem(:,[2,3]); elem(:,[1,3]); elem(:,[1,2])],2)); 15 [edge,i2, j2] = myunique(totalEdge); 16 elem2edge = reshape(j2,NT,3); 17 elem2dof(:,19:21)=elem2edge+6*N; 18 NE=size(edge,1); Ndof = max(elem2dof(:)); 19 A = sparse(Ndof,Ndof); 20 B = sparse(Ndof,Ndof); 21 %% 数值求积节点 22 [points,weight]=nparray; 23 x=(points(:,1))'; y=(points(:,2))';numPoints=size(x,2); 24 weight=repmat(weight',NT,1); 25 %% 相邻单元外法向匹配 26 orient1=repmat(sign(elem(:,3)-elem(:,2)),1,numPoints); 27 orient2=repmat(sign(elem(:,3)-elem(:,1)),1,numPoints); 28 orient3=repmat(sign(elem(:,2)-elem(:,1)),1,numPoints); 29 %% 参考单元基函数的系数 30 % (0,0): f,dx,dy,dxx,dxy,dyy: 1st-6th 31 % (1,0): f,dx,dy,dxx,dxy,dyy: 7st-14th 32 % (0,1): f,dx,dy,dxx,dxy,dyy: 15st-18th 33 % (0.5,0): dn1:19th; (0,0.5): dn2:20th;(0.5,0.5): dn3:21th; 34 % coVaulues(21x21); coDxx,coDxy,coDyy (21x10); 35 [coVaulues,coDxx,coDxy,coDyy]=coefficients; 36 %% Pa:参考单元中第一个基函数(NTx21) 37 Pa=repmat(coVaulues(1,:),NT,1); 38 Pb=repmat(coVaulues(2,:),NT,1); 39 Pc=repmat(coVaulues(3,:),NT,1); 40 Pd=repmat(coVaulues(4,:),NT,1); 41 Pe=repmat(coVaulues(5,:),NT,1); 42 Pf=repmat(coVaulues(6,:),NT,1); 43 Pg=repmat(coVaulues(7,:),NT,1); 44 Ph=repmat(coVaulues(8,:),NT,1); 45 Pi=repmat(coVaulues(9,:),NT,1); 46 Pj=repmat(coVaulues(10,:),NT,1); 47 Pk=repmat(coVaulues(11,:),NT,1); 48 Pl=repmat(coVaulues(12,:),NT,1); 49 Pm=repmat(coVaulues(13,:),NT,1); 50 Pn=repmat(coVaulues(14,:),NT,1); 51 Po=repmat(coVaulues(15,:),NT,1); 52 Pp=repmat(coVaulues(16,:),NT,1); 53 Pq=repmat(coVaulues(17,:),NT,1); 54 Pr=repmat(coVaulues(18,:),NT,1); 55 Ps=repmat(coVaulues(19,:),NT,1); 56 Pt=repmat(coVaulues(20,:),NT,1); 57 Pu=repmat(coVaulues(21,:),NT,1); 58 %% Paxx:参考单元中第一个基函数(NTx10) 59 Paxx=repmat(coDxx(1,:),NT,1);Paxy=repmat(coDxy(1,:),NT,1);Payy=repmat(coDyy(1,:),NT,1); 60 Pbxx=repmat(coDxx(2,:),NT,1);Pbxy=repmat(coDxy(2,:),NT,1);Pbyy=repmat(coDyy(2,:),NT,1); 61 Pcxx=repmat(coDxx(3,:),NT,1);Pcxy=repmat(coDxy(3,:),NT,1);Pcyy=repmat(coDyy(3,:),NT,1); 62 Pdxx=repmat(coDxx(4,:),NT,1);Pdxy=repmat(coDxy(4,:),NT,1);Pdyy=repmat(coDyy(4,:),NT,1); 63 Pexx=repmat(coDxx(5,:),NT,1);Pexy=repmat(coDxy(5,:),NT,1);Peyy=repmat(coDyy(5,:),NT,1); 64 Pfxx=repmat(coDxx(6,:),NT,1);Pfxy=repmat(coDxy(6,:),NT,1);Pfyy=repmat(coDyy(6,:),NT,1); 65 Pgxx=repmat(coDxx(7,:),NT,1);Pgxy=repmat(coDxy(7,:),NT,1);Pgyy=repmat(coDyy(7,:),NT,1); 66 Phxx=repmat(coDxx(8,:),NT,1);Phxy=repmat(coDxy(8,:),NT,1);Phyy=repmat(coDyy(8,:),NT,1); 67 Pixx=repmat(coDxx(9,:),NT,1);Pixy=repmat(coDxy(9,:),NT,1);Piyy=repmat(coDyy(9,:),NT,1); 68 Pjxx=repmat(coDxx(10,:),NT,1);Pjxy=repmat(coDxy(10,:),NT,1);Pjyy=repmat(coDyy(10,:),NT,1); 69 Pkxx=repmat(coDxx(11,:),NT,1);Pkxy=repmat(coDxy(11,:),NT,1);Pkyy=repmat(coDyy(11,:),NT,1); 70 Plxx=repmat(coDxx(12,:),NT,1);Plxy=repmat(coDxy(12,:),NT,1);Plyy=repmat(coDyy(12,:),NT,1); 71 Pmxx=repmat(coDxx(13,:),NT,1);Pmxy=repmat(coDxy(13,:),NT,1);Pmyy=repmat(coDyy(13,:),NT,1); 72 Pnxx=repmat(coDxx(14,:),NT,1);Pnxy=repmat(coDxy(14,:),NT,1);Pnyy=repmat(coDyy(14,:),NT,1); 73 Poxx=repmat(coDxx(15,:),NT,1);Poxy=repmat(coDxy(15,:),NT,1);Poyy=repmat(coDyy(15,:),NT,1); 74 Ppxx=repmat(coDxx(16,:),NT,1);Ppxy=repmat(coDxy(16,:),NT,1);Ppyy=repmat(coDyy(16,:),NT,1); 75 Pqxx=repmat(coDxx(17,:),NT,1);Pqxy=repmat(coDxy(17,:),NT,1);Pqyy=repmat(coDyy(17,:),NT,1); 76 Prxx=repmat(coDxx(18,:),NT,1);Prxy=repmat(coDxy(18,:),NT,1);Pryy=repmat(coDyy(18,:),NT,1); 77 Psxx=repmat(coDxx(19,:),NT,1);Psxy=repmat(coDxy(19,:),NT,1);Psyy=repmat(coDyy(19,:),NT,1); 78 Ptxx=repmat(coDxx(20,:),NT,1);Ptxy=repmat(coDxy(20,:),NT,1);Ptyy=repmat(coDyy(20,:),NT,1); 79 Puxx=repmat(coDxx(21,:),NT,1);Puxy=repmat(coDxy(21,:),NT,1);Puyy=repmat(coDyy(21,:),NT,1); 80 %% 调用函数 transform 计算出: 81 % 单元面积 area (NTx1); 82 % Hessen矩阵逆中第一行与第三行h11 (NTx1) 83 % 变换矩阵 C 中的系数 Cdd (NTx1),其中 Caa,Cbb,Ccc均为1. 84 [area,h11,h12,h13,h31,h32,h33,... 85 Cdd,Ced,Cde,Cee,Cff,Cgf,Cfg,Cgg,Chh,Cih,Chi,Cii,... 86 Cjj,Ckj,Clj,Cjk,Ckk,Clk,Cjl,Ckl,Cll,... 87 Cmm,Cnm,Com,Cmn,Cnn,Con,Cmo,Cno,Coo,... 88 Cpp,Cqp,Crp,Cpq,Cqq,Crq,Cpr,Cqr,Crr,... 89 Cas,Cbs,Cds,Ces,Cfs,Cgs,Cjs,Cks,Cls,Cms,Cns,Cos,Css,... 90 Cat,Cct,Cdt,Cet,Cht,Cit,Cjt,Ckt,Clt,Cpt,Cqt,Crt,Ctt,... 91 Cbu,Ccu,Cfu,Cgu,Chu,Ciu,Cmu,Cnu,Cou,Cpu,Cqu,Cru,Cuu]=transform(node,elem); 92 %% 变换矩阵 C 中系数的规模:从 NTx1 到 NTx21 93 Caa=ones(NT,21);Cbb=ones(NT,21);Ccc=ones(NT,21);Cdd=repmat(Cdd,1,21); 94 Ced=repmat(Ced,1,21);Cde=repmat(Cde,1,21);Cee=repmat(Cee,1,21);Cff=repmat(Cff,1,21); 95 Cgf=repmat(Cgf,1,21);Cfg=repmat(Cfg,1,21);Cgg=repmat(Cgg,1,21);Chh=repmat(Chh,1,21); 96 Cih=repmat(Cih,1,21);Chi=repmat(Chi,1,21);Cii=repmat(Cii,1,21);Cjj=repmat(Cjj,1,21); 97 Ckj=repmat(Ckj,1,21);Clj=repmat(Clj,1,21);Cjk=repmat(Cjk,1,21);Ckk=repmat(Ckk,1,21); 98 Clk=repmat(Clk,1,21);Cjl=repmat(Cjl,1,21);Ckl=repmat(Ckl,1,21);Cll=repmat(Cll,1,21); 99 Cmm=repmat(Cmm,1,21);Cnm=repmat(Cnm,1,21);Com=repmat(Com,1,21);Cmn=repmat(Cmn,1,21); 100 Cnn=repmat(Cnn,1,21);Con=repmat(Con,1,21);Cmo=repmat(Cmo,1,21);Cno=repmat(Cno,1,21); 101 Coo=repmat(Coo,1,21);Cpp=repmat(Cpp,1,21);Cqp=repmat(Cqp,1,21);Crp=repmat(Crp,1,21); 102 Cpq=repmat(Cpq,1,21);Cqq=repmat(Cqq,1,21);Crq=repmat(Crq,1,21);Cpr=repmat(Cpr,1,21); 103 Cqr=repmat(Cqr,1,21);Crr=repmat(Crr,1,21);Cas=repmat(Cas,1,21);Cbs=repmat(Cbs,1,21); 104 Cds=repmat(Cds,1,21);Ces=repmat(Ces,1,21);Cfs=repmat(Cfs,1,21);Cgs=repmat(Cgs,1,21); 105 Cjs=repmat(Cjs,1,21);Cks=repmat(Cks,1,21);Cls=repmat(Cls,1,21);Cms=repmat(Cms,1,21); 106 Cns=repmat(Cns,1,21);Cos=repmat(Cos,1,21);Css=repmat(Css,1,21);Cat=repmat(Cat,1,21); 107 Cct=repmat(Cct,1,21);Cdt=repmat(Cdt,1,21);Cet=repmat(Cet,1,21);Cht=repmat(Cht,1,21); 108 Cit=repmat(Cit,1,21);Cjt=repmat(Cjt,1,21);Ckt=repmat(Ckt,1,21);Clt=repmat(Clt,1,21); 109 Cpt=repmat(Cpt,1,21);Cqt=repmat(Cqt,1,21);Crt=repmat(Crt,1,21);Ctt=repmat(Ctt,1,21); 110 Cbu=repmat(Cbu,1,21);Ccu=repmat(Ccu,1,21);Cfu=repmat(Cfu,1,21);Cgu=repmat(Cgu,1,21); 111 Chu=repmat(Chu,1,21);Ciu=repmat(Ciu,1,21);Cmu=repmat(Cmu,1,21);Cnu=repmat(Cnu,1,21); 112 Cou=repmat(Cou,1,21);Cpu=repmat(Cpu,1,21);Cqu=repmat(Cqu,1,21);Cru=repmat(Cru,1,21); 113 Cuu=repmat(Cuu,1,21); 114 %% 单项式 monomials0 和 monomials2 115 monomials0=[ones(1,numPoints);... %1.0 116 x;... %x[i] 117 y;... %y[i] 118 x.^2;... %x[i]*x[i] 119 x.*y;... %x[i]*y[i] 120 y.^2;... %y[i]*y[i] 121 x.^3;... %x[i]*x[i]*x[i] 122 x.^2.*y;... %x[i]*x[i]*y[i] 123 x.*y.^2;... %x[i]*y[i]*y[i] 124 y.^3;... %y[i]*y[i]*y[i] 125 x.^4;... %x[i]*x[i]*x[i]*x[i] 126 x.^3.*y;... %x[i]*x[i]*x[i]*y[i] 127 x.^2.*y.^2;... %x[i]*x[i]*y[i]*y[i] 128 x.*y.^3;... %x[i]*y[i]*y[i]*y[i] 129 y.^4;... %y[i]*y[i]*y[i]*y[i] 130 x.^5;... %x[i]*x[i]*x[i]*x[i]*x[i] 131 x.^4.*y;... %x[i]*x[i]*x[i]*x[i]*y[i] 132 x.^3.*y.^2;... %x[i]*x[i]*x[i]*y[i]*y[i] 133 x.^2.*y.^3;... %x[i]*x[i]*y[i]*y[i]*y[i] 134 x.*y.^4;... %x[i]*y[i]*y[i]*y[i]*y[i] 135 y.^5]; 136 137 monomials2=[ones(1,numPoints);... %1.0 138 x;... %x[i] 139 y;... %y[i] 140 x.^2;... %x[i]*x[i] 141 x.*y;... %x[i]*y[i] 142 y.^2;... %y[i]*y[i] 143 x.^3;... %x[i]*x[i]*x[i] 144 x.^2.*y;... %x[i]*x[i]*y[i] 145 x.*y.^2;... %x[i]*y[i]*y[i] 146 y.^3]; %y[i]*y[i]*y[i] 147 %% 基函数 M (NTxNUMx21) 148 M(:,:,1) = (Caa.*Pa + Cas.*Ps + Cat.*Pt)*monomials0;%1st function 149 M(:,:,2) = (Cbb.*Pb + Cbs.*Ps + Cbu.*Pu)*monomials0;%2nd function 150 M(:,:,3) = (Ccc.*Pc + Cct.*Pt + Ccu.*Pu)*monomials0;%3rd function 151 M(:,:,4) = (Cdd.*Pd + Cde.*Pe + Cds.*Ps + Cdt.*Pt)*monomials0;%1st dx 152 M(:,:,5) = (Cff.*Pf + Cfg.*Pg + Cfs.*Ps + Cfu.*Pu)*monomials0;%2nd dx 153 M(:,:,6) = (Chh.*Ph + Chi.*Pi + Cht.*Pt + Chu.*Pu)*monomials0;%3rd dx 154 M(:,:,7) = (Ced.*Pd + Cee.*Pe + Ces.*Ps + Cet.*Pt)*monomials0;%1st dy 155 M(:,:,8) = (Cgf.*Pf + Cgg.*Pg + Cgs.*Ps + Cgu.*Pu)*monomials0;%2nd dy 156 M(:,:,9) = (Cih.*Ph + Cii.*Pi + Cit.*Pt + Ciu.*Pu)*monomials0;%3rd dy 157 M(:,:,10) = (Cjj.*Pj + Cjk.*Pk + Cjl.*Pl + Cjs.*Ps + Cjt.*Pt)*monomials0;%1st dxx 158 M(:,:,11) = (Cmm.*Pm + Cmn.*Pn + Cmo.*Po + Cms.*Ps + Cmu.*Pu)*monomials0;%2nd dxx 159 M(:,:,12) = (Cpp.*Pp + Cpq.*Pq + Cpr.*Pr + Cpt.*Pt + Cpu.*Pu)*monomials0;%3rd dxx 160 M(:,:,13) = (Ckj.*Pj + Ckk.*Pk + Ckl.*Pl + Cks.*Ps + Ckt.*Pt)*monomials0;%1st dxy 161 M(:,:,14) = (Cnm.*Pm + Cnn.*Pn + Cno.*Po + Cns.*Ps + Cnu.*Pu)*monomials0;%2nd dxy 162 M(:,:,15) = (Cqp.*Pp + Cqq.*Pq + Cqr.*Pr + Cqt.*Pt + Cqu.*Pu)*monomials0;%3rd dxy 163 M(:,:,16) = (Clj.*Pj + Clk.*Pk + Cll.*Pl + Cls.*Ps + Clt.*Pt)*monomials0;%1st dyy 164 M(:,:,17) = (Com.*Pm + Con.*Pn + Coo.*Po + Cos.*Ps + Cou.*Pu)*monomials0;%2nd dyy 165 M(:,:,18) = (Crp.*Pp + Crq.*Pq + Crr.*Pr + Crt.*Pt + Cru.*Pu)*monomials0;%3rd dyy 166 M(:,:,19) = orient1.*((Cuu.*Pu)*monomials0); %edge=[2 3]的中点 167 M(:,:,20) = orient2.*((Ctt.*Pt)*monomials0);%edge=[1 3]的中点 168 M(:,:,21) = orient3.*((Css.*Ps)*monomials0); %edge=[1 2]的中点 169 %% 从 NTx1 到 NTx10 170 h11=repmat(h11,1,10);h12=repmat(h12,1,10);h13=repmat(h13,1,10); 171 h31=repmat(h31,1,10);h32=repmat(h32,1,10);h33=repmat(h33,1,10); 172 %% a 173 Maxx=h11.*Paxx+h12.*Paxy+h13.*Payy; 174 Mayy=h31.*Paxx+h32.*Paxy+h33.*Payy; 175 %% b 176 Mbxx=h11.*Pbxx+h12.*Pbxy+h13.*Pbyy; 177 Mbyy=h31.*Pbxx+h32.*Pbxy+h33.*Pbyy; 178 %% c 179 Mcxx=h11.*Pcxx+h12.*Pcxy+h13.*Pcyy; 180 Mcyy=h31.*Pcxx+h32.*Pcxy+h33.*Pcyy; 181 %% d 182 Mdxx=h11.*Pdxx+h12.*Pdxy+h13.*Pdyy; 183 Mdyy=h31.*Pdxx+h32.*Pdxy+h33.*Pdyy; 184 %% e 185 Mexx=h11.*Pexx+h12.*Pexy+h13.*Peyy; 186 Meyy=h31.*Pexx+h32.*Pexy+h33.*Peyy; 187 %% f 188 Mfxx=h11.*Pfxx+h12.*Pfxy+h13.*Pfyy; 189 Mfyy=h31.*Pfxx+h32.*Pfxy+h33.*Pfyy; 190 %% g 191 Mgxx=h11.*Pgxx+h12.*Pgxy+h13.*Pgyy; 192 Mgyy=h31.*Pgxx+h32.*Pgxy+h33.*Pgyy; 193 %% h 194 Mhxx=h11.*Phxx+h12.*Phxy+h13.*Phyy; 195 Mhyy=h31.*Phxx+h32.*Phxy+h33.*Phyy; 196 %% i 197 Mixx=h11.*Pixx+h12.*Pixy+h13.*Piyy; 198 Miyy=h31.*Pixx+h32.*Pixy+h33.*Piyy; 199 %% j 200 Mjxx=h11.*Pjxx+h12.*Pjxy+h13.*Pjyy; 201 Mjyy=h31.*Pjxx+h32.*Pjxy+h33.*Pjyy; 202 %% k 203 Mkxx=h11.*Pkxx+h12.*Pkxy+h13.*Pkyy; 204 Mkyy=h31.*Pkxx+h32.*Pkxy+h33.*Pkyy; 205 %% l 206 Mlxx=h11.*Plxx+h12.*Plxy+h13.*Plyy; 207 Mlyy=h31.*Plxx+h32.*Plxy+h33.*Plyy; 208 %% m 209 Mmxx=h11.*Pmxx+h12.*Pmxy+h13.*Pmyy; 210 Mmyy=h31.*Pmxx+h32.*Pmxy+h33.*Pmyy; 211 %% n 212 Mnxx=h11.*Pnxx+h12.*Pnxy+h13.*Pnyy; 213 Mnyy=h31.*Pnxx+h32.*Pnxy+h33.*Pnyy; 214 %% o 215 Moxx=h11.*Poxx+h12.*Poxy+h13.*Poyy; 216 Moyy=h31.*Poxx+h32.*Poxy+h33.*Poyy; 217 %% p 218 Mpxx=h11.*Ppxx+h12.*Ppxy+h13.*Ppyy; 219 Mpyy=h31.*Ppxx+h32.*Ppxy+h33.*Ppyy; 220 %% q 221 Mqxx=h11.*Pqxx+h12.*Pqxy+h13.*Pqyy; 222 Mqyy=h31.*Pqxx+h32.*Pqxy+h33.*Pqyy; 223 %% r 224 Mrxx=h11.*Prxx+h12.*Prxy+h13.*Pryy; 225 Mryy=h31.*Prxx+h32.*Prxy+h33.*Pryy; 226 %% s 227 Msxx=h11.*Psxx+h12.*Psxy+h13.*Psyy; 228 Msyy=h31.*Psxx+h32.*Psxy+h33.*Psyy; 229 %% t 230 Mtxx=h11.*Ptxx+h12.*Ptxy+h13.*Ptyy; 231 Mtyy=h31.*Ptxx+h32.*Ptxy+h33.*Ptyy; 232 %% u 233 Muxx=h11.*Puxx+h12.*Puxy+h13.*Puyy; 234 Muyy=h31.*Puxx+h32.*Puxy+h33.*Puyy; 235 %% 缩小矩阵规模 236 Caa=Caa(:,1:10);Cbb=Cbb(:,1:10);Ccc=Ccc(:,1:10);Cdd=Cdd(:,1:10); 237 Ced=Ced(:,1:10);Cde=Cde(:,1:10);Cee=Cee(:,1:10);Cff=Cff(:,1:10); 238 Cgf=Cgf(:,1:10);Cfg=Cfg(:,1:10);Cgg=Cgg(:,1:10);Chh=Chh(:,1:10); 239 Cih=Cih(:,1:10);Chi=Chi(:,1:10);Cii=Cii(:,1:10);Cjj=Cjj(:,1:10); 240 Ckj=Ckj(:,1:10);Clj=Clj(:,1:10);Cjk=Cjk(:,1:10);Ckk=Ckk(:,1:10); 241 Clk=Clk(:,1:10);Cjl=Cjl(:,1:10);Ckl=Ckl(:,1:10);Cll=Cll(:,1:10); 242 Cmm=Cmm(:,1:10);Cnm=Cnm(:,1:10);Com=Com(:,1:10);Cmn=Cmn(:,1:10); 243 Cnn=Cnn(:,1:10);Con=Con(:,1:10);Cmo=Cmo(:,1:10);Cno=Cno(:,1:10); 244 Coo=Coo(:,1:10);Cpp=Cpp(:,1:10);Cqp=Cqp(:,1:10);Crp=Crp(:,1:10); 245 Cpq=Cpq(:,1:10);Cqq=Cqq(:,1:10);Crq=Crq(:,1:10);Cpr=Cpr(:,1:10); 246 Cqr=Cqr(:,1:10);Crr=Crr(:,1:10);Crr=Crr(:,1:10);Cas=Cas(:,1:10); 247 Cbs=Cbs(:,1:10);Cds=Cds(:,1:10);Ces=Ces(:,1:10);Cfs=Cfs(:,1:10); 248 Cgs=Cgs(:,1:10);Cjs=Cjs(:,1:10);Cks=Cks(:,1:10);Cls=Cls(:,1:10); 249 Cms=Cms(:,1:10);Cns=Cns(:,1:10);Cos=Cos(:,1:10);Css=Css(:,1:10); 250 Cat=Cat(:,1:10);Cct=Cct(:,1:10);Cdt=Cdt(:,1:10);Cet=Cet(:,1:10); 251 Cht=Cht(:,1:10);Cit=Cit(:,1:10);Cjt=Cjt(:,1:10);Ckt=Ckt(:,1:10); 252 Clt=Clt(:,1:10);Cpt=Cpt(:,1:10);Cqt=Cqt(:,1:10);Crt=Crt(:,1:10); 253 Ctt=Ctt(:,1:10);Cbu=Cbu(:,1:10);Ccu=Ccu(:,1:10);Cfu=Cfu(:,1:10); 254 Cgu=Cgu(:,1:10);Chu=Chu(:,1:10);Ciu=Ciu(:,1:10);Cmu=Cmu(:,1:10); 255 Cnu=Cnu(:,1:10);Cou=Cou(:,1:10);Cpu=Cpu(:,1:10);Cqu=Cqu(:,1:10); 256 Cru=Cru(:,1:10);Cuu=Cuu(:,1:10); 257 %% 基函数 Mxx (NTxNUMx21) 258 Mxx(:,:,1) = (Caa.*Maxx + Cas.*Msxx + Cat.*Mtxx)*monomials2; 259 Mxx(:,:,2) = (Cbb.*Mbxx + Cbs.*Msxx + Cbu.*Muxx)*monomials2; 260 Mxx(:,:,3) = (Ccc.*Mcxx + Cct.*Mtxx + Ccu.*Muxx)*monomials2; 261 Mxx(:,:,4) = (Cdd.*Mdxx + Cde.*Mexx + Cds.*Msxx + Cdt.*Mtxx)*monomials2; 262 Mxx(:,:,5) = (Cff.*Mfxx + Cfg.*Mgxx + Cfs.*Msxx + Cfu.*Muxx)*monomials2; 263 Mxx(:,:,6) = (Chh.*Mhxx + Chi.*Mixx + Cht.*Mtxx + Chu.*Muxx)*monomials2; 264 Mxx(:,:,7) = (Ced.*Mdxx + Cee.*Mexx + Ces.*Msxx + Cet.*Mtxx)*monomials2; 265 Mxx(:,:,8) = (Cgf.*Mfxx + Cgg.*Mgxx + Cgs.*Msxx + Cgu.*Muxx)*monomials2; 266 Mxx(:,:,9) = (Cih.*Mhxx + Cii.*Mixx + Cit.*Mtxx + Ciu.*Muxx)*monomials2; 267 Mxx(:,:,10) = (Cjj.*Mjxx + Cjk.*Mkxx + Cjl.*Mlxx + Cjs.*Msxx + Cjt.*Mtxx)*monomials2; 268 Mxx(:,:,11) = (Cmm.*Mmxx + Cmn.*Mnxx + Cmo.*Moxx + Cms.*Msxx + Cmu.*Muxx)*monomials2; 269 Mxx(:,:,12) = (Cpp.*Mpxx + Cpq.*Mqxx + Cpr.*Mrxx + Cpt.*Mtxx + Cpu.*Muxx)*monomials2; 270 Mxx(:,:,13) = (Ckj.*Mjxx + Ckk.*Mkxx + Ckl.*Mlxx + Cks.*Msxx + Ckt.*Mtxx)*monomials2; 271 Mxx(:,:,14) = (Cnm.*Mmxx + Cnn.*Mnxx + Cno.*Moxx + Cns.*Msxx + Cnu.*Muxx)*monomials2; 272 Mxx(:,:,15) = (Cqp.*Mpxx + Cqq.*Mqxx + Cqr.*Mrxx + Cqt.*Mtxx + Cqu.*Muxx)*monomials2; 273 Mxx(:,:,16) = (Clj.*Mjxx + Clk.*Mkxx + Cll.*Mlxx + Cls.*Msxx + Clt.*Mtxx)*monomials2; 274 Mxx(:,:,17) = (Com.*Mmxx + Con.*Mnxx + Coo.*Moxx + Cos.*Msxx + Cou.*Muxx)*monomials2; 275 Mxx(:,:,18) = (Crp.*Mpxx + Crq.*Mqxx + Crr.*Mrxx + Crt.*Mtxx + Cru.*Muxx)*monomials2; 276 Mxx(:,:,19) = orient1.*((Cuu.*Muxx)*monomials2); 277 Mxx(:,:,20) = orient2.*((Ctt.*Mtxx)*monomials2); 278 Mxx(:,:,21) = orient3.*((Css.*Msxx)*monomials2); 279 %% 基函数 Myy (NTxNUMx21) 280 Myy(:,:,1) = (Caa.*Mayy + Cas.*Msyy + Cat.*Mtyy)*monomials2; 281 Myy(:,:,2) = (Cbb.*Mbyy + Cbs.*Msyy + Cbu.*Muyy)*monomials2; 282 Myy(:,:,3) = (Ccc.*Mcyy + Cct.*Mtyy + Ccu.*Muyy)*monomials2; 283 Myy(:,:,4) = (Cdd.*Mdyy + Cde.*Meyy + Cds.*Msyy + Cdt.*Mtyy)*monomials2; 284 Myy(:,:,5) = (Cff.*Mfyy + Cfg.*Mgyy + Cfs.*Msyy + Cfu.*Muyy)*monomials2; 285 Myy(:,:,6) = (Chh.*Mhyy + Chi.*Miyy + Cht.*Mtyy + Chu.*Muyy)*monomials2; 286 Myy(:,:,7) = (Ced.*Mdyy + Cee.*Meyy + Ces.*Msyy + Cet.*Mtyy)*monomials2; 287 Myy(:,:,8) = (Cgf.*Mfyy + Cgg.*Mgyy + Cgs.*Msyy + Cgu.*Muyy)*monomials2; 288 Myy(:,:,9) = (Cih.*Mhyy + Cii.*Miyy + Cit.*Mtyy + Ciu.*Muyy)*monomials2;%% 289 Myy(:,:,10) = (Cjj.*Mjyy + Cjk.*Mkyy + Cjl.*Mlyy + Cjs.*Msyy + Cjt.*Mtyy)*monomials2; 290 Myy(:,:,11) = (Cmm.*Mmyy + Cmn.*Mnyy + Cmo.*Moyy + Cms.*Msyy + Cmu.*Muyy)*monomials2; 291 Myy(:,:,12) = (Cpp.*Mpyy + Cpq.*Mqyy + Cpr.*Mryy + Cpt.*Mtyy + Cpu.*Muyy)*monomials2; 292 Myy(:,:,13) = (Ckj.*Mjyy + Ckk.*Mkyy + Ckl.*Mlyy + Cks.*Msyy + Ckt.*Mtyy)*monomials2; 293 Myy(:,:,14) = (Cnm.*Mmyy + Cnn.*Mnyy + Cno.*Moyy + Cns.*Msyy + Cnu.*Muyy)*monomials2; 294 Myy(:,:,15) = (Cqp.*Mpyy + Cqq.*Mqyy + Cqr.*Mryy + Cqt.*Mtyy + Cqu.*Muyy)*monomials2; 295 Myy(:,:,16) = (Clj.*Mjyy + Clk.*Mkyy + Cll.*Mlyy + Cls.*Msyy + Clt.*Mtyy)*monomials2; 296 Myy(:,:,17) = (Com.*Mmyy + Con.*Mnyy + Coo.*Moyy + Cos.*Msyy + Cou.*Muyy)*monomials2; 297 Myy(:,:,18) = (Crp.*Mpyy + Crq.*Mqyy + Crr.*Mryy + Crt.*Mtyy + Cru.*Muyy)*monomials2; 298 Myy(:,:,19) = orient1.*((Cuu.*Muyy)*monomials2);%单元外法向 299 Myy(:,:,20) = orient2.*((Ctt.*Mtyy)*monomials2);%单元外法向 300 Myy(:,:,21) = orient3.*((Css.*Msyy)*monomials2);%单元外法向 301 clear Caa Cbb Ccc Cdd Ced Cde Cee Cff Cgf Cfg Cgg Chh Cih Chi Cii 302 clear Cjj Ckj Clj Cjk Ckk Clk Cjl Ckl Cll 303 clear Cmm Cnm Com Cmn Cnn Con Cmo Cno Coo 304 clear Cpp Cqp Crp Cpq Cqq Crq Cpr Cqr Crr 305 clear Cas Cbs Cds Ces Cfs Cgs Cjs Cks Cls Cms Cns Cos Css 306 clear Cat Cct Cdt Cet Cht Cit Cjt Ckt Clt Cpt Cqt Crt Ctt 307 clear Cbu Ccu Cfu Cgu Chu Ciu Cmu Cnu Cou Cpu Cqu Cru Cuu 308 clear Pa Pb Pc Pd Pe Pf Pg Ph Pi Pj Pk Pl Pm Pn Po Pp Pq Pr Ps Pt Pu 309 clear Maxx Mbxx Mcxx Mdxx Mexx Mfxx Mgxx Mhxx Mixx Mjxx Mkxx Mlxx Mmxx Mnxx Moxx Mpxx Mqxx Mrxx Msxx Mtxx Muxx 310 clear Mayy Mbyy Mcyy Mdyy Meyy Mfyy Mgyy Mhyy Miyy Mjyy Mkyy Mlyy Mmyy Mnyy Moyy Mpyy Mqyy Mryy Msyy Mtyy Muyy 311 clear Paxx Pbxx Pcxx Pdxx Pexx Pfxx Pgxx Phxx Pixx Pjxx Pkxx Plxx Pmxx Pnxx Poxx Ppxx Pqxx Prxx Psxx Ptxx Puxx 312 clear Payy Pbyy Pcyy Pdyy Peyy Pfyy Pgyy Phyy Piyy Pjyy Pkyy Plyy Pmyy Pnyy Poyy Ppyy Pqyy Pryy Psyy Ptyy Puyy 313 clear Paxy Pbxy Pcxy Pdxy Pexy Pfxy Pgxy Phxy Pixy Pjxy Pkxy Plxy Pmxy Pnxy Poxy Ppxy Pqxy Prxy Psxy Ptxy Puxy 314 clear orient1 orient2 orient3 h11 h12 h13 h31 h32 h33 monomials0 monomials2 315 clear coVaulues coDx coDy coDxx coDxy coDyy 316 %% 组装刚度矩阵和质量矩阵 317 for i=1:21 318 for j=i:21 319 aij=sum(weight.*(Mxx(:,:,i).*Mxx(:,:,j)+Myy(:,:,i).*Myy(:,:,j)+... 320 Mxx(:,:,i).*Myy(:,:,j)+Myy(:,:,i).*Mxx(:,:,j)),2); 321 bij=sum(weight.*(M(:,:,i).*(M(:,:,j))),2); 322 aij=area.*aij; 323 bij=area.*bij; 324 if (j==i) 325 A=A+sparse(elem2dof(:,i),elem2dof(:,j),aij,Ndof,Ndof); 326 B=B+sparse(elem2dof(:,i),elem2dof(:,j),bij,Ndof,Ndof); 327 else 328 A=A+sparse([elem2dof(:,i),elem2dof(:,j)],[elem2dof(:,j),elem2dof(:,i)],[aij;aij],Ndof,Ndof); 329 B=B+sparse([elem2dof(:,i),elem2dof(:,j)],[elem2dof(:,j),elem2dof(:,i)],[bij;bij],Ndof,Ndof); 330 end 331 end 332 end 333 clear M Mxx Myy 334 %% 335 edget= [elem2dof(:,19);elem2dof(:,20);elem2dof(:,21)]; 336 edget=edget(i2,:); 337 i1(j2(3*NT:-1:1)) = 3*NT:-1:1; i1 = i1'; 338 %边界边 339 bdedge = edge((i1 == i2),:); 340 bdedget=edget(i1 ==i2,:); 341 % 342 isbdNode(1:N,1)=false; 343 isbdNode(bdedge)=true; 344 bdNode1=find(isbdNode); %findnode(node(bdNode1(:),:)); 345 %%% 四个角点 346 hmxy=[bdNode1(1);bdNode1(hm+1);bdNode1(3*hm);bdNode1(4*hm)];%findnode(node(hmxy(:),:)); 347 %%%平行于 y 轴的单元边 348 hmy=[bdNode1(2:hm);bdNode1(3*hm+1:4*hm-1);hmxy];% 349 findnode(node(hmy(:),:)); 350 %%%平行于 x 轴的单元边 351 hmx=[bdNode1(hm+2:3*hm-1);hmxy];% 352 %%%边界边中点 353 bdedget=bdedget-6*N; 354 isbdNode2(1:NE,1)=false; 355 isbdNode2(bdedget)=true; 356 bdNode2=6*N+find(isbdNode2);%findnode(nodep2(bdNode2(:),:)); 357 %%%平行于x轴的单元边:不删Dyy; 358 %%%平行于y轴的单元边:不删Dxx; 359 bd=[bdNode1;bdNode1+N;bdNode1+2*N;hmx+3*N;bdNode1+4*N;hmy+5*N;bdNode2]; 360 %bd=[bdNode1;hmy+N;hmx+2*N;hmx+3*N;hmy+4*N;bdNode1+5*N;bdNode2]; 361 A(bd,:)=[];A(:,bd)=[]; 362 B(bd,:)=[];B(:,bd)=[]; 363 lam=eigs(A,B,1,'sm'); 364 end
1 function [node,elem,varargout] = squaremesh(square,h) 2 %% SQUAREMESH uniform mesh of a square 3 % 4 % [node,elem] = squaremesh([x0,x1,y0,y1],h) generates a uniform mesh of the 5 % rectangle [x0,x1]*[y0,y1] with mesh size h. 6 % 7 % Example 8 % 9 % [node,elem] = squaremesh([0,1,0,1],0.2); 10 % showmesh(node,elem); 11 % findnode(node); 12 % findelem(node,elem); 13 % 14 % Copyright (C) Long Chen. See COPYRIGHT.txt for details. 15 16 %% Generate nodes 17 x0 = square(1); x1 = square(2); 18 y0 = square(3); y1 = square(4); 19 [x,y] = meshgrid(x0:h:x1,y0:h:y1); 20 node = [x(:),y(:)]; 21 % 22 % %% Generate elements 23 ni = size(x,1); % number of rows 24 N = size(node,1); 25 t2nidxMap = 1:N-ni; 26 topNode = ni:ni:N-ni; 27 t2nidxMap(topNode) = []; 28 k = (t2nidxMap)'; 29 elem = [k+ni k+ni+1 k; k+1 k k+ni+1]; 30 % 4 k+1 --- k+ni+1 3 31 % | | 32 % 1 k --- k+ni 2 33 34 % n = ceil((x1-x0)/h); 35 % h = (x1-x0)/n; 36 % [x,y] = meshgrid(x0:h:x1,y0:h:y1); 37 % node = [x(:),y(:)]; 38 % shiftnode(:,1) = node(:,1) - cos(pi/3)*node(:,2); 39 % shiftnode(:,2) = sin(pi/3)*node(:,2); 40 % elem = delaunayn(shiftnode); 41 % elem = fixorientation(node,elem); 42 % elem = label(node,elem); 43 end
1 function h = showmesh(node,elem,varargin) 2 %% SHOWMESH displays a triangular mesh in 2-D. 3 % 4 % showmesh(node,elem) displays a topological 2-dimensional mesh, 5 % including planar meshes and surface meshes. The mesh is given by node 6 % and elem matrices; see <a href="matlab:ifem('meshdoc')">meshdoc</a> for the mesh data structure: 7 % node and elem. 8 % 9 % showmesh(node,elem,viewangle) changes the display angle. The 10 % deault view angle on planar meshes is view(2) and view(3) for surface 11 % meshes. 12 % 13 % showmesh(node,elem,'param','value','param','value'...) allows 14 % additional patch param/value pairs to be used when displaying the 15 % mesh. For example, the default transparency parameter for a surface 16 % mesh is set to 0.75. You can overwrite this value by using the param 17 % pair ('FaceAlpha', value). The value has to be a number between 0 and 18 % 1. Other parameters include: 'Facecolor', 'Edgecolor' etc. These 19 % parameters are mostly used when displaying a surface mesh. 20 % 21 % To display a 3-dimensional mesh, use showmesh3 or showboundary3. 22 % 23 % Example: 24 % % A mesh for a L-shaped domain 25 % node = [1,0; 1,1; 0,1; -1,1; -1,0; -1,-1; 0,-1; 0,0]; 26 % elem = [1,2,8; 3,8,2; 8,3,5; 4,5,3; 7,8,6; 5,6,8]; 27 % figure(1) 28 % showmesh(node,elem); 29 % 30 % % A mesh for a unit sphere 31 % node = [1,0,0; 0,1,0; -1,0,0; 0,-1,0; 0,0,1; 0,0,-1]; 32 % elem = [6,1,2; 6,2,3; 6,3,4; 6,4,1; 5,1,4; 5,3,4; 5,3,2; 5,2,1]; 33 % for i = 1:3 34 % [node,elem] = uniformrefine(node,elem); 35 % end 36 % r = sqrt(node(:,1).^2 + node(:,2).^2 + node(:,3).^2); 37 % node = node./[r r r]; 38 % figure(2) 39 % subplot(1,2,1); 40 % showmesh(node,elem); 41 % subplot(1,2,2); 42 % showmesh(node,elem,'Facecolor','y','Facealpha',0.5); 43 % 44 % See also showmesh3, showsolution, showboundary3. 45 % 46 % Copyright (C) Long Chen. See COPYRIGHT.txt for details. 47 48 dim = size(node,2); 49 nv = size(elem,2); 50 if (dim==2) && (nv==3) % planar triangulation 51 h = trisurf(elem(:,1:3),node(:,1),node(:,2),zeros(size(node,1),1)); 52 view([0,-90]); axis equal; axis tight; axis off; 53 set(h,'facecolor','y','edgecolor','k','FaceAlpha',0.75); 54 end 55 if (dim==2) && (nv==4) % planar quadrilateration 56 h = patch('Faces', elem, 'Vertices', node); 57 set(h,'facecolor','y','edgecolor','k'); 58 view(2); axis equal; axis tight; axis off; 59 end 60 if (dim==3) 61 if size(elem,2) == 3 % surface meshes 62 h = trisurf(elem(:,1:3),node(:,1),node(:,2),node(:,3)); 63 set(h,'facecolor','y','edgecolor','k','FaceAlpha',0.75); 64 view(3); axis equal; axis off; axis tight; 65 elseif size(elem,3) == 4 66 h = showmesh3(node,elem,varargin); 67 end 68 end 69 if (nargin>2) && ~isempty(varargin) % set display property 70 if isnumeric(varargin{1}) 71 view(varargin{1}); 72 if nargin>3 73 set(h,varargin{2:end}); 74 end 75 else 76 set(h,varargin{1:end}); 77 end 78 end
1 function [sortA,i2,j] = myunique(A) 2 %% 3 % A multidimensional array 4 matlabversion = version; 5 if str2double(matlabversion(end-5:end-2)) > 2012 6 [sortA, i2, j] = unique(A,'rows','legacy'); %#ok<*ASGLU> 7 else 8 [sortA, i2, j] = unique(A,'rows'); 9 end
1 function [points,weight]=nparray 2 points = [0.333333333333333333333333333333, 0.333333333333333333333333333333;... 3 0.950275662924105565450352089520, 0.024862168537947217274823955239;... 4 0.024862168537947217274823955239, 0.950275662924105565450352089520;... 5 0.024862168537947217274823955239, 0.024862168537947217274823955239;... 6 0.171614914923835347556304795551, 0.414192542538082326221847602214;... 7 0.414192542538082326221847602214, 0.171614914923835347556304795551;... 8 0.414192542538082326221847602214, 0.414192542538082326221847602214;... 9 0.539412243677190440263092985511, 0.230293878161404779868453507244;... 10 0.230293878161404779868453507244, 0.539412243677190440263092985511;... 11 0.230293878161404779868453507244, 0.230293878161404779868453507244;... 12 0.772160036676532561750285570113, 0.113919981661733719124857214943;... 13 0.113919981661733719124857214943, 0.772160036676532561750285570113;... 14 0.113919981661733719124857214943, 0.113919981661733719124857214943;... 15 0.009085399949835353883572964740, 0.495457300025082323058213517632;... 16 0.495457300025082323058213517632, 0.009085399949835353883572964740;... 17 0.495457300025082323058213517632, 0.495457300025082323058213517632;... 18 0.062277290305886993497083640527, 0.468861354847056503251458179727;... 19 0.468861354847056503251458179727, 0.062277290305886993497083640527;... 20 0.468861354847056503251458179727, 0.468861354847056503251458179727;... 21 0.022076289653624405142446876931, 0.851306504174348550389457672223;... 22 0.022076289653624405142446876931, 0.126617206172027096933163647918;... 23 0.851306504174348550389457672223, 0.022076289653624405142446876931;... 24 0.851306504174348550389457672223, 0.126617206172027096933163647918;... 25 0.126617206172027096933163647918, 0.022076289653624405142446876931;... 26 0.126617206172027096933163647918, 0.851306504174348550389457672223;... 27 0.018620522802520968955913511549, 0.689441970728591295496647976487;... 28 0.018620522802520968955913511549, 0.291937506468887771754472382212;... 29 0.689441970728591295496647976487, 0.018620522802520968955913511549;... 30 0.689441970728591295496647976487, 0.291937506468887771754472382212;... 31 0.291937506468887771754472382212, 0.018620522802520968955913511549;... 32 0.291937506468887771754472382212, 0.689441970728591295496647976487;... 33 0.096506481292159228736516560903, 0.635867859433872768286976979827;... 34 0.096506481292159228736516560903, 0.267625659273967961282458816185;... 35 0.635867859433872768286976979827, 0.096506481292159228736516560903;... 36 0.635867859433872768286976979827, 0.267625659273967961282458816185;... 37 0.267625659273967961282458816185, 0.096506481292159228736516560903;... 38 0.267625659273967961282458816185, 0.635867859433872768286976979827]; 39 40 weight =[0.051739766065744133555179145422;... 41 0.008007799555564801597804123460;... 42 0.008007799555564801597804123460;... 43 0.008007799555564801597804123460;... 44 0.046868898981821644823226732071;... 45 0.046868898981821644823226732071;... 46 0.046868898981821644823226732071;... 47 0.046590940183976487960361770070;... 48 0.046590940183976487960361770070;... 49 0.046590940183976487960361770070;... 50 0.031016943313796381407646220131;... 51 0.031016943313796381407646220131;... 52 0.031016943313796381407646220131;... 53 0.010791612736631273623178240136;... 54 0.010791612736631273623178240136;... 55 0.010791612736631273623178240136;... 56 0.032195534242431618819414482205;... 57 0.032195534242431618819414482205;... 58 0.032195534242431618819414482205;... 59 0.015445834210701583817692900053;... 60 0.015445834210701583817692900053;... 61 0.015445834210701583817692900053;... 62 0.015445834210701583817692900053;... 63 0.015445834210701583817692900053;... 64 0.015445834210701583817692900053;... 65 0.017822989923178661888748319485;... 66 0.017822989923178661888748319485;... 67 0.017822989923178661888748319485;... 68 0.017822989923178661888748319485;... 69 0.017822989923178661888748319485;... 70 0.017822989923178661888748319485;... 71 0.037038683681384627918546472190;... 72 0.037038683681384627918546472190;... 73 0.037038683681384627918546472190;... 74 0.037038683681384627918546472190;... 75 0.037038683681384627918546472190;... 76 0.037038683681384627918546472190]*0.5;
1 function [coefficientsVaulues,coefficientsDxx,coefficientsDxy,coefficientsDyy]=coefficients 2 %% coefficients_values[21*21] 3 coefficientsVaulues = [... 4 1, 0, 0, 0, 0, 0, -10, 0, 0, -10, 15, 0, -30, 0, 15, -6, 0, 30,30, 0, -6;... 5 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, -15, 0, 15, 0, 0, 6, 0, -15,-15, 0, 0;... 6 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 15, 0, -15, 0, 0, -15, -15, 0, 6;... 7 0, 1, 0, 0, 0, 0, -6, 0, -11, 0, 8, 0, 10, 18, 0, -3, 0, 1,-10, -8, 0;... 8 0, 0, 1, 0, 0, 0, 0, -11, 0, -6, 0, 18, 10, 0, 8, 0, -8, -10,1, 0, -3;... 9 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 7, 0, -3.5, 0, 0, -3, 0, 3.5,3.5, 0, 0;... 10 0, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 14, 18.5, 0, 0, 0, -8, -18.5,-13.5, 0, 0;... 11 0, 0, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 18.5, 14, 0, 0, 0, -13.5,-18.5, -8, 0;... 12 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, -3.5, 0, 7, 0, 0, 3.5,3.5, 0, -3;... 13 0, 0, 0, 0.5, 0, 0, -1.5, 0, 0, 0, 1.5, 0, -1.5, 0, 0, -0.5, 0,1.5, 1, 0, 0;... 14 0, 0, 0, 0, 1, 0, 0, -4, -4, 0, 0, 5, 10, 5, 0, 0, -2, -6, -6,-2, 0;... 15 0, 0, 0, 0, 0, 0.5, 0, 0, 0, -1.5, 0, 0, -1.5, 0, 1.5, 0, 0, 1,1.5, 0, -0.5;... 16 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0, -1, 0, 0.25, 0, 0, 0.5, 0, -0.25,-0.25, 0, 0;... 17 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -3, -3.5, 0, 0, 0, 2, 3.5,2.5, 0, 0;... 18 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.25, 0, 0, 0, 0, -0.75,-1.25, 0, 0;... 19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.25, 0, 0, 0, 0, -1.25,-0.75, 0, 0;... 20 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -3.5, -3, 0, 0, 0, 2.5,3.5, 2, 0;... 21 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0.25, 0, -1, 0, 0, -0.25,-0.25, 0, 0.5;... 22 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, -32, -32, 0, 0, 0, 16, 32,16, 0, 0;... 23 0, 0, 0, 0, 0, 0, 0, 0, -16, 0, 0, 0, 32, 32, 0, 0, 0, -16,-32, -16, 0;... 24 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8*sqrt(2), 0, 0, 0, 0,-8*sqrt(2), -8*sqrt(2), 0, 0]; 25 %% coefficients_dxx[21*10] 26 coefficientsDxx=[0, -60, 0, 180, 0, -60, -120, 0, 180, 60;... 27 0, 60, 0, -180, 0, 30, 120, 0, -90, -30;... 28 0, 0, 0, 0, 0, 30, 0, 0, -90, -30;... 29 0, -36, 0, 96, 0, 20, -60, 0, 6, -20;... 30 0, 0, -22, 0, 108, 20, 0, -96, -60, 2;... 31 0, -24, 0, 84, 0, -7, -60, 0, 21, 7;... 32 0, 0, -10, 0, 84, 37, 0, -96, -111, -27;... 33 0, 0, 0, 0, 0, 37, 0, 0, -81, -37;... 34 0, 0, 0, 0, 0, -7, 0, 0, 21, 7;... 35 1, -9, 0, 18, 0, -3, -10, 0, 9, 2;... 36 0, 0, -8, 0, 30, 20, 0, -24, -36, -12;... 37 0, 0, 0, 0, 0, -3, 0, 0, 6, 3;... 38 0, 3, 0, -12, 0, 0.5, 10, 0, -1.5, -0.5;... 39 0, 0, 2, 0, -18, -7, 0, 24, 21, 5;... 40 0, 0, 0, 0, 0, 2.5, 0, 0, -4.5, -2.5;... 41 0, 0, 0, 0, 0, 2.5, 0, 0, -7.5, -1.5;... 42 0, 0, 0, 0, 0, -7, 0, 0, 15, 7;... 43 0, 0, 0, 0, 0, 0.5, 0, 0, -1.5, -0.5;... 44 0, 0, 32, 0, -192, -64, 0, 192, 192, 32;... 45 0, 0, 0, 0, 0, 64, 0, 0, -96, -64;... 46 0, 0, 0, 0, 0, 16*sqrt(2), 0, 0, -48*sqrt(2), -16*sqrt(2)]; 47 %% coefficients_dxy[21*10] 48 coefficientsDxy=[0, 0, 0, 0, -120, 0, 0, 180, 180, 0;... 49 0, 0, 0, 0, 60, 0, 0, -90, -90, 0;... 50 0, 0, 0, 0, 60, 0, 0, -90, -90, 0;... 51 0, 0, -22, 0, 40, 54, 0, 6, -60, -32;... 52 0, -22, 0, 54, 40, 0, -32, -60, 6, 0;... 53 0, 0, 0, 0, -14, 0, 0, 21, 21, 0;... 54 0, -10, 0, 42, 74, 0, -32, -111, -81, 0;... 55 0, 0, -10, 0, 74, 42, 0, -81, -111, -32;... 56 0, 0, 0, 0, -14, 0, 0, 21, 21, 0;... 57 0, 0, 0, 0, -6, 0, 0, 9, 6, 0;... 58 1, -8, -8, 15, 40, 15, -8, -36, -36, -8;... 59 0, 0, 0, 0, -6, 0, 0, 6, 9, 0;... 60 0, 0, 0, 0, 1, 0, 0, -1.5, -1.5, 0;... 61 0, 2, 0, -9, -14, 0, 8, 21, 15, 0;... 62 0, 0, 0, 0, 5, 0, 0, -4.5, -7.5, 0;... 63 0, 0, 0, 0, 5, 0, 0, -7.5, -4.5, 0;... 64 0, 0, 2, 0, -14, -9, 0, 15, 21, 8;... 65 0, 0, 0, 0, 1, 0, 0, -1.5, -1.5, 0;... 66 0, 32, 0, -96, -128, 0, 64, 192, 96, 0;... 67 0, 0, -32, 0, 128, 96, 0, -96, -192, -64;... 68 0, 0, 0, 0, 32*sqrt(2), 0, 0, -48*sqrt(2), -48*sqrt(2), 0]; 69 %% coefficients_dyy[21*10] 70 coefficientsDyy=[0, 0, -60, -60, 0, 180, 60, 180, 0, -120;... 71 0, 0, 0, 30, 0, 0, -30, -90, 0, 0;... 72 0, 0, 60, 30, 0, -180, -30, -90, 0, 120;... 73 0, -22, 0, 20, 108, 0, 2, -60, -96, 0;... 74 0, 0, -36, 20, 0, 96, -20, 6, 0, -60;... 75 0, 0, 0, -7, 0, 0, 7, 21, 0, 0;... 76 0, 0, 0, 37, 0, 0, -37, -81, 0, 0;... 77 0, -10, 0, 37, 84, 0, -27, -111, -96, 0;... 78 0, 0, -24, -7, 0, 84, 7, 21, 0, -60;... 79 0, 0, 0, -3, 0, 0, 3, 6, 0, 0;... 80 0, -8, 0, 20, 30, 0, -12, -36, -24, 0;... 81 1, 0, -9, -3, 0, 18, 2, 9, 0, -10;... 82 0, 0, 0, 0.5, 0, 0, -0.5, -1.5, 0, 0;... 83 0, 0, 0, -7, 0, 0, 7, 15, 0, 0;... 84 0, 0, 0, 2.5, 0, 0, -1.5, -7.5, 0, 0;... 85 0, 0, 0, 2.5, 0, 0, -2.5, -4.5, 0, 0;... 86 0, 2, 0, -7, -18, 0, 5, 21, 24, 0;... 87 0, 0, 3, 0.5, 0, -12, -0.5, -1.5, 0, 10;... 88 0, 0, 0, -64, 0, 0, 64, 96, 0, 0;... 89 0, -32, 0, 64, 192, 0, -32, -192, -192, 0;... 90 0, 0, 0, 16*sqrt(2), 0, 0, -16*sqrt(2), -48*sqrt(2), 0, 0]; 91 end
1 function [area,h11,h12,h13,h31,h32,h33,... 2 Cdd,Ced,Cde,Cee,Cff,Cgf,Cfg,Cgg,Chh,Cih,Chi,Cii,... 3 Cjj,Ckj,Clj,Cjk,Ckk,Clk,Cjl,Ckl,Cll,... 4 Cmm,Cnm,Com,Cmn,Cnn,Con,Cmo,Cno,Coo,... 5 Cpp,Cqp,Crp,Cpq,Cqq,Crq,Cpr,Cqr,Crr,... 6 Cas,Cbs,Cds,Ces,Cfs,Cgs,Cjs,Cks,Cls,Cms,Cns,Cos,Css,... 7 Cat,Cct,Cdt,Cet,Cht,Cit,Cjt,Ckt,Clt,Cpt,Cqt,Crt,Ctt,... 8 Cbu,Ccu,Cfu,Cgu,Chu,Ciu,Cmu,Cnu,Cou,Cpu,Cqu,Cru,Cuu]=transform(node,elem) 9 x0=node(elem(:,1),1); 10 x1=node(elem(:,2),1); 11 x2=node(elem(:,3),1); 12 y0=node(elem(:,1),2); 13 y1=node(elem(:,2),2); 14 y2=node(elem(:,3),2); 15 %% ./.* fill B. .*./ 16 B00 = -x0 + x1;%b11 17 B01 = -x0 + x2;%b12 18 B10 = -y0 + y1;%b21 19 B11 = -y0 + y2;%b22 20 area=(-x0 + x1).*( -y0 + y2)-(-x0 + x2).*(-y0 + y1); 21 % b11=area.*B11; 22 % b12=-area.*B01; 23 % b21=-area.*B10; 24 % b22=area.*B00; 25 area=abs(area); 26 %% 27 t=(B00.*B11-B01.*B10).*(B00.*B11-B01.*B10); 28 h11=B11.*B11./t; 29 h12=-2*B10.*B11./t; 30 h13=B10.*B10./t; 31 h31=B01.*B01./t; 32 h32=-2*B00.*B01./t; 33 h33=B00.*B00./t; 34 %% ./.* fill b. .*./ 35 % b[ORDER(0,0,2,1)] = x0; 36 % b[ORDER(1,0,2,1)] = y0; 37 38 %% ./.* v values .*./ 39 v00 = -x0 + x1; 40 v01 = -x0 + x2; 41 v02 = -x1 + x2; 42 v10 = -y0 + y1; 43 v11 = -y0 + y2; 44 v12 = -y1 + y2; 45 46 %% ./.* w values .*./ 47 w00 = v00.*v00; 48 w10 = v01.*v01; 49 w20 = v02.*v02; 50 w01 = 2.*v10.*v00; 51 w11 = 2.*v11.*v01; 52 w21 = 2.*v12.*v02; 53 w02 = v10.*v10; 54 w12 = v11.*v11; 55 w22 = v12.*v12; 56 57 %% ./.* Manually folded constants. .*./ 58 norm0 = sqrt(w00 + w02); 59 norm1 = sqrt(w10 + w12); 60 norm2 = sqrt(w20 + w22); 61 norm0squared = norm0.*norm0; 62 norm1squared = norm1.*norm1; 63 norm2squared = norm2.*norm2; 64 C_constant0 = (B00.*v02 + B01.*v02 + B10.*v12 + B11.*v12); 65 C_constant1 = (B00.*v01 + B10.*v11); 66 C_constant2 = (B01.*v00 + B11.*v10); 67 %% ./.* fill C. Note that this is the transpose of the usual definition. .*./ 68 Caa = 1; 69 Cbb = 1; 70 Ccc = 1; 71 %% ./.* row 4 .*./ 72 Cdd = B00; 73 Ced = B10; 74 %% ./.* row 5 .*./ 75 Cde = B01; 76 Cee = B11; 77 %% ./.* row 6 .*./ 78 Cff = B00; 79 Cgf = B10; 80 %% ./.* row 7 .*./ 81 Cfg = B01; 82 Cgg = B11; 83 %% ./.* row 8 .*./ 84 Chh = B00; 85 Cih = B10; 86 %% ./.* row 9 .*./ 87 Chi = B01; 88 Cii = B11; 89 %% ./.* row 10 .*./ 90 Cjj = B00.*B00; 91 Ckj = 2.*B00.*B10; 92 Clj = B10.*B10; 93 %% ./.* row 11 .*./ 94 Cjk = B00.*B01; 95 Ckk = B00.*B11 + B01.*B10; 96 Clk = B10.*B11; 97 %% ./.* row 12 .*./ 98 Cjl = B01.*B01; 99 Ckl = 2.*B01.*B11; 100 Cll = B11.*B11; 101 %% ./.* row 13 .*./ 102 Cmm = B00.*B00; 103 Cnm = 2.*B00.*B10; 104 Com = B10.*B10; 105 %% ./.* row 14 .*./ 106 Cmn = B00.*B01; 107 Cnn = B00.*B11 + B01.*B10; 108 Con = B10.*B11; 109 %% ./.* row 15 .*./ 110 Cmo = B01.*B01; 111 Cno = 2.*B01.*B11; 112 Coo = B11.*B11; 113 %% ./.* row 16 .*./ 114 Cpp = B00.*B00; 115 Cqp = 2.*B00.*B10; 116 Crp = B10.*B10; 117 118 %% ./.* row 17 .*./ 119 Cpq = B00.*B01; 120 Cqq = B00.*B11 + B01.*B10; 121 Crq = B10.*B11; 122 123 %% ./.* row 18 .*./ 124 Cpr = B01.*B01; 125 Cqr = 2.*B01.*B11; 126 Crr = B11.*B11; 127 128 %% ./.* row 19 .*./ 129 Cas = -15.0./8.0.*C_constant2./norm0squared; 130 Cbs = 15.0./8.0.*C_constant2./norm0squared; 131 Cds = -7.0./16.0.*C_constant2.*v00./norm0squared; 132 Ces = -7.0./16.0.*C_constant2.*v10./norm0squared; 133 Cfs = -7.0./16.0.*C_constant2.*v00./norm0squared; 134 Cgs = -7.0./16.0.*C_constant2.*v10./norm0squared; 135 Cjs = -1.0./32.0.*C_constant2.*w00./norm0squared; 136 Cks = -1.0./32.0.*C_constant2.*w01./norm0squared; 137 Cls = -1.0./32.0.*C_constant2.*w02./norm0squared; 138 Cms = 1.0./32.0.*C_constant2.*w00./norm0squared; 139 Cns = 1.0./32.0.*C_constant2.*w01./norm0squared; 140 Cos = 1.0./32.0.*C_constant2.*w02./norm0squared; 141 Css = -(B01.*v10 - B11.*v00)./norm0; 142 143 %% ./.* row 20 .*./ t 144 Cat = 15.0./8.0.*C_constant1./norm1squared;%1 145 Cct = -15.0./8.0.*C_constant1./norm1squared;%3 146 Cdt = 7.0./16.0.*C_constant1.*v01./norm1squared;%4 147 Cet = 7.0./16.0.*C_constant1.*v11./norm1squared;%5 148 Cht = 7.0./16.0.*C_constant1.*v01./norm1squared;%8 149 Cit = 7.0./16.0.*C_constant1.*v11./norm1squared;%9 150 Cjt = 1.0./32.0.*C_constant1.*w10./norm1squared;%10 151 Ckt = 1.0./32.0.*C_constant1.*w11./norm1squared;%11 152 Clt = 1.0./32.0.*C_constant1.*w12./norm1squared;%12 153 Cpt = -1.0./32.0.*C_constant1.*w10./norm1squared; 154 Cqt = -1.0./32.0.*C_constant1.*w11./norm1squared; 155 Crt = -1.0./32.0.*C_constant1.*w12./norm1squared; 156 Ctt = (B00.*v11 - B10.*v01)./norm1; 157 158 %% ./.* row 21 .*./ u 159 Cbu = 15.0./16.0.*C_constant0.*sqrt(2)./norm2squared; 160 Ccu = -15.0./16.0.*C_constant0.*sqrt(2)./norm2squared; 161 Cfu = 7.0./32.0.*C_constant0.*sqrt(2).*v02./norm2squared; 162 Cgu = 7.0./32.0.*C_constant0.*sqrt(2).*v12./norm2squared; 163 Chu = 7.0./32.0.*C_constant0.*sqrt(2).*v02./norm2squared; 164 Ciu = 7.0./32.0.*C_constant0.*sqrt(2).*v12./norm2squared; 165 Cmu = 1.0./64.0.*C_constant0.*sqrt(2).*w20./norm2squared; 166 Cnu = 1.0./64.0.*C_constant0.*sqrt(2).*w21./norm2squared; 167 Cou = 1.0./64.0.*C_constant0.*sqrt(2).*w22./norm2squared; 168 Cpu = -1.0./64.0.*C_constant0.*sqrt(2).*w20./norm2squared; 169 Cqu = -1.0./64.0.*C_constant0.*sqrt(2).*w21./norm2squared; 170 Cru = -1.0./64.0.*C_constant0.*sqrt(2).*w22./norm2squared; 171 Cuu = 0.5.*(B00.*v12 + B01.*v12 - B10.*v02 - B11.*v02).*sqrt(2)./norm2;
1 function varargout = eigs(varargin) 2 %EIGS Find a few eigenvalues and eigenvectors of a matrix 3 % D = EIGS(A) returns a vector of A's 6 largest magnitude eigenvalues. 4 % A must be square and should be large and sparse. 5 % 6 % [V,D] = EIGS(A) returns a diagonal matrix D of A's 6 largest magnitude 7 % eigenvalues and a matrix V whose columns are the corresponding 8 % eigenvectors. 9 % 10 % [V,D,FLAG] = EIGS(A) also returns a convergence flag. If FLAG is 0 then 11 % all the eigenvalues converged; otherwise not all converged. 12 % 13 % EIGS(A,B) solves the generalized eigenvalue problem A*V == B*V*D. B must be 14 % the same size as A. EIGS(A,[],...) indicates the standard eigenvalue problem 15 % A*V == V*D. 16 % 17 % EIGS(A,K) and EIGS(A,B,K) return the K largest magnitude eigenvalues. 18 % 19 % EIGS(A,K,SIGMA) and EIGS(A,B,K,SIGMA) return K eigenvalues. If SIGMA is: 20 % 'LM' or 'SM' - Largest or Smallest Magnitude 21 % For real symmetric problems, SIGMA may also be: 22 % 'LA' or 'SA' - Largest or Smallest Algebraic 23 % 'BE' - Both Ends, one more from high end if K is odd 24 % For nonsymmetric or complex problems, SIGMA may also be: 25 % 'LR' or 'SR' - Largest or Smallest Real part 26 % 'LI' or 'SI' - Largest or Smallest Imaginary part 27 % If SIGMA is a real or complex scalar including 0, EIGS finds the 28 % eigenvalues closest to SIGMA. 29 % 30 % EIGS(A,K,SIGMA,OPTS) and EIGS(A,B,K,SIGMA,OPTS) specify options: 31 % OPTS.issym: symmetry of A or A-SIGMA*B represented by AFUN [{false} | 32 % true] 33 % OPTS.isreal: complexity of A or A-SIGMA*B represented by AFUN [false | {true}] 34 % OPTS.tol: convergence: Ritz estimate residual <= tol*NORM(A) [scalar | {eps}] 35 % OPTS.maxit: maximum number of iterations [integer | {300}] 36 % OPTS.p: number of Lanczos vectors: K+1<p<=N [integer | {2K}] 37 % OPTS.v0: starting vector [N-by-1 vector | {randomly generated}] 38 % OPTS.disp: diagnostic information display level [{0} | 1 | 2] 39 % OPTS.cholB: B is actually its Cholesky factor CHOL(B) [{false} | true] 40 % OPTS.permB: sparse B is actually CHOL(B(permB,permB)) [permB | {1:N}] 41 % Use CHOL(B) instead of B when SIGMA is a string other than 'SM'. 42 % 43 % EIGS(AFUN,N) accepts the function AFUN instead of the matrix A. AFUN is 44 % a function handle and Y = AFUN(X) should return 45 % A*X if SIGMA is unspecified, or a string other than 'SM' 46 % A\X if SIGMA is 0 or 'SM' 47 % (A-SIGMA*I)\X if SIGMA is a nonzero scalar (standard problem) 48 % (A-SIGMA*B)\X if SIGMA is a nonzero scalar (generalized problem) 49 % N is the size of A. The matrix A, A-SIGMA*I or A-SIGMA*B represented by 50 % AFUN is assumed to be real and nonsymmetric unless specified otherwise 51 % by OPTS.isreal and OPTS.issym. In all these EIGS syntaxes, EIGS(A,...) 52 % may be replaced by EIGS(AFUN,N,...). 53 % 54 % Example: 55 % A = delsq(numgrid('C',15)); d1 = eigs(A,5,'SM'); 56 % 57 % Equivalently, if dnRk is the following one-line function: 58 % %----------------------------% 59 % function y = dnRk(x,R,k) 60 % y = (delsq(numgrid(R,k))) \ x; 61 % %----------------------------% 62 % 63 % n = size(A,1); opts.issym = 1; 64 % d2 = eigs(@(x)dnRk(x,'C',15),n,5,'SM',opts); 65 % 66 % See also EIG, SVDS, FUNCTION_HANDLE. 67 68 % Copyright 1984-2013 The MathWorks, Inc. 69 70 % EIGS provides the reverse communication interface to ARPACK library 71 % routines. EIGS attempts to provide an interface for as many different 72 % algorithms as possible. The reverse communication interfaces are 73 % documented in the ARPACK Users' Guide, ISBN 0-89871-407-9. 74 75 cputms = zeros(5,1); 76 t0 = cputime; % start timing pre-processing 77 78 % Process inputs and do error-checking 79 if (nargout > 3) 80 error(message('MATLAB:eigs:TooManyOutputs')); 81 end 82 83 % Platform dependent integer type 84 if strfind(computer, '64') 85 intconvert = @(arraytoconvert) int64(arraytoconvert); 86 inttype = 'int64'; 87 else 88 intconvert = @(arraytoconvert) int32(arraytoconvert); 89 inttype = 'int32'; 90 end 91 92 % Error check inputs and derive some information from them 93 [A,Amatrix,isrealprob,issymA,n,B,classAB,k,eigs_sigma,whch, ... 94 sigma,tol,maxit,p,info,eigs_display,cholB,permB,resid,useeig, ... 95 afunNargs,style,mode,Afactors,Bfactors] = ... 96 checkInputs(varargin{:}); 97 98 % Now have enough information to do early return on cases EIGS does not 99 % handle. For these cases, use the full EIG code. 100 if useeig 101 fullEig(nargout); 102 return 103 end 104 105 if ~isempty(Afactors) 106 L = Afactors.L; Afactors.L = []; 107 U = Afactors.U; Afactors.U = []; 108 pp = Afactors.pp; Afactors.pp = []; 109 qq = Afactors.qq; Afactors.qq = []; 110 dgAsB = Afactors.dgAsB; Afactors.dgAsB = []; 111 clear Afactors; 112 end 113 114 if ~isempty(Bfactors) 115 BisHpd = Bfactors.BisHpd; 116 if BisHpd 117 RB = Bfactors.RB; Bfactors.RB = []; 118 RBT = Bfactors.RBT; Bfactors.RBT = []; 119 permB = Bfactors.permB; Bfactors.permB = []; 120 else 121 LB = Bfactors.LB; Bfactors.LB = []; 122 UB = Bfactors.UB; Bfactors.UB = []; 123 ppB = Bfactors.ppB; Bfactors.ppB = []; 124 qqB = Bfactors.qqB; Bfactors.qqB = []; 125 dgB = Bfactors.dgB; Bfactors.dgB = []; 126 end 127 clear Bfactors; 128 end 129 130 if isempty(B) 131 if mode ~= 3 132 % OP = A 133 applyOP = @(v)Amtimes(v); 134 else 135 % OP = (A-\sigma*I)^{-1} 136 applyOP = @(v)AminusSigmaBsolve(v); 137 end 138 else 139 if mode ~= 3 140 if BisHpd == true 141 % OP = L^{-1}AL^{-T} (B = LL^T) 142 applyOP = @(v)RBTsolve(Amtimes(RBsolve(v))); 143 else 144 % OP = U^{-1}L^{-1}A (B = LU) 145 applyOP = @(v)Bsolve(Amtimes(v)); 146 end 147 else 148 % OP = (A-\sigma*B)^{-1}B 149 applyOP = @(v)AminusSigmaBsolve(Bmtimes(v)); 150 end 151 end 152 applyM = @(v) v; 153 if strcmp(style,'G') && ~isempty(B) && BisHpd == true 154 applyM = @(v) Bmtimes(v); 155 end 156 157 % Allocate outputs and ARPACK work variables 158 if isrealprob 159 if issymA % real and symmetric 160 if strcmp(classAB,'single') 161 aupdfun = 'ssaupd'; 162 eupdfun = 'sseupd'; 163 else 164 aupdfun = 'dsaupd'; 165 eupdfun = 'dseupd'; 166 end 167 lworkl = intconvert(p*(p+8)); 168 else % real but not symmetric 169 if strcmp(classAB,'single') 170 aupdfun = 'snaupd'; 171 eupdfun = 'sneupd'; 172 else 173 aupdfun = 'dnaupd'; 174 eupdfun = 'dneupd'; 175 end 176 lworkl = intconvert(3*p*(p+2)); 177 workev = zeros(3*p,1,classAB); 178 end 179 v = zeros(n,p,classAB); 180 workd = zeros(n,3,classAB); 181 workl = zeros(lworkl,1,classAB); 182 else % complex 183 if strcmp(classAB,'single') 184 aupdfun = 'cnaupd'; 185 eupdfun = 'cneupd'; 186 else 187 aupdfun = 'znaupd'; 188 eupdfun = 'zneupd'; 189 end 190 zv = zeros(2*n*p,1,classAB); 191 workd = complex(zeros(n,3,classAB)); 192 zworkd = zeros(2*numel(workd),1,classAB); 193 lworkl = intconvert(2*(3*p^2+5*p)); 194 workl = zeros(lworkl,1,classAB); 195 workev = zeros(2*2*p,1,classAB); 196 rwork = zeros(p,1,classAB); 197 end 198 ldv = intconvert(n); 199 ipntr = zeros(15,1,inttype); 200 ido = intconvert(0); % reverse communication parameter, initial value 201 if strcmp(style,'S') || mode == 1 202 bmat = 'I'; % standard eigenvalue problem 203 else 204 bmat = 'G'; % generalized eigenvalue problem 205 end 206 nev = intconvert(k); % number of eigenvalues requested 207 ncv = intconvert(p); % number of Lanczos vectors 208 iparam = zeros(11,1,inttype); 209 % iparam(1) = ishift = 1 ensures we are never asked to handle ido=3 210 iparam([1 3 7]) = [1 maxit mode]; 211 select = zeros(p,1,inttype); 212 213 % To Do: Remove this error when ARPACKC supports singles 214 if strcmp(classAB,'single') 215 error(message('MATLAB:eigs:single')); 216 end 217 218 % The ARPACK routines return to EIGS many times per each iteration but we 219 % only want to display the Ritz values once per iteration (if opts.disp>0). 220 % Keep track of whether we've displayed this iteration yet in eigs_iter. 221 eigs_iter = 0; 222 223 cputms(1) = cputime - t0; % end timing pre-processing 224 225 % Iterate until ARPACK's reverse communication parameter ido says to stop 226 while (ido ~= 99) 227 228 t0 = cputime; % start timing ARPACK calls **aupd 229 230 if isrealprob 231 [ido, info] = arpackc( aupdfun, ido, bmat, intconvert(n), whch, ... 232 nev, tol, resid, ncv, v, ldv, iparam, ipntr, workd, workl, ... 233 lworkl, info ); 234 else 235 % The FORTRAN ARPACK routine expects the complex input zworkd to have 236 % real and imaginary parts interleaved, but the OP about to be 237 % applied to workd expects it in MATLAB's complex representation with 238 % separate real and imaginary parts. Thus we need both. 239 zworkd(1:2:end-1) = real(workd); 240 zworkd(2:2:end) = imag(workd); 241 [ido, info] = arpackc( aupdfun, ido, bmat, intconvert(n), whch, ... 242 nev, tol, resid, ncv, zv, ldv, iparam, ipntr, zworkd, workl, ... 243 lworkl, rwork, info ); 244 workd = reshape(complex(zworkd(1:2:end-1),zworkd(2:2:end)),[n,3]); 245 end 246 247 if (info < 0) 248 error(message('MATLAB:eigs:ARPACKroutineError', aupdfun, full(double(info)))); 249 end 250 251 cputms(2) = cputms(2) + (cputime-t0); % end timing ARPACK calls **aupd 252 t0 = cputime; % start timing MATLAB OP(X) 253 254 % Compute which columns of workd ipntr references 255 cols = checkIpntr; 256 257 % The ARPACK reverse communication parameter ido tells EIGS what to do 258 259 switch ido 260 case -1 261 workd(:,cols(2)) = applyOP(workd(:,cols(1))); 262 case 1 263 workd(:,cols(3)) = applyM(workd(:,cols(1))); 264 workd(:,cols(2)) = applyOP(workd(:,cols(1))); 265 case 2 266 workd(:,cols(2)) = applyM(workd(:,cols(1))); 267 case 99 268 % ARPACK has converged 269 otherwise 270 error(message('MATLAB:eigs:UnknownIdo')); 271 end 272 273 cputms(3) = cputms(3) + (cputime-t0); % end timing MATLAB OP(X) 274 275 if eigs_display 276 displayRitzValues; 277 end 278 279 end % while (ido ~= 99) 280 281 t0 = cputime; % start timing post-processing 282 283 if (nargout >= 2) 284 rvec = intconvert(true); % compute eigenvectors 285 else 286 rvec = intconvert(false); % do not compute eigenvectors 287 end 288 289 if isrealprob 290 if issymA 291 [d, info] = arpackc( eupdfun, rvec, 'A', select, v, ldv, sigma, ... 292 bmat, intconvert(n), whch, nev, tol, resid, ncv, v, ldv, ... 293 iparam, ipntr, workd, workl, lworkl, info ); 294 v(:,k+1:end) = []; 295 converged = ~isnan(d); 296 if strcmp(whch,'LM') || strcmp(whch,'LA') 297 d(converged) = flipud(d(converged)); 298 if (rvec == 1) 299 v(:,converged) = fliplr(v(:,converged)); 300 end 301 end 302 if ((strcmp(whch,'SM') || strcmp(whch,'SA')) && (rvec == 0)) 303 d(converged) = flipud(d(converged)); 304 end 305 else 306 % If sigma is complex, isrealprob=true and we use [c,z]neupd. 307 % So use sigmar=sigma and sigmai=0 here in dneupd. 308 [d, info] = arpackc( eupdfun, rvec, 'A', select, v, ldv, ... 309 sigma, 0, workev, bmat, intconvert(n), whch, nev, tol, resid, ... 310 ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, info ); 311 if rvec 312 d(k+1) = []; 313 cplxd = find(imag(d) ~= 0 & ~isnan(imag(d))); 314 % complex conjugate pairs of eigenvalues occur together 315 cplxd = cplxd(1:2:end); 316 v(:,[cplxd cplxd+1]) = [complex(v(:,cplxd),v(:,cplxd+1)) ... 317 complex(v(:,cplxd),-v(:,cplxd+1))]; 318 v(:,k+1:end) = []; 319 else 320 converged = ~isnan(d); 321 if all(converged) 322 d = d(k+1:-1:2); 323 else 324 d(k+1) = []; 325 d(converged) = flipud(d(converged)); 326 end 327 end 328 end 329 else 330 zsigma = [real(sigma); imag(sigma)]; 331 [zd, info] = arpackc( eupdfun, rvec, 'A', select, zv, ldv, zsigma, ... 332 workev, bmat, intconvert(n), whch, nev, tol, resid, ncv, zv, ... 333 ldv, iparam, ipntr, zworkd, workl, lworkl, rwork, info ); 334 if issymA 335 d = zd(1:2:end-1); 336 else 337 d = complex(zd(1:2:end-1),zd(2:2:end)); 338 end 339 d(k+1) = []; 340 v = reshape(complex(zv(1:2:end-1),zv(2:2:end)),[n p]); 341 v(:,k+1:end) = []; 342 if ~rvec 343 converged = ~isnan(d); 344 if ~all(converged) 345 d(converged) = flipud(d(converged)); 346 end 347 end 348 end 349 350 flag = processEUPDinfo(nargout<3); 351 352 if ~isempty(B) 353 d = d/scaleB; 354 if BisHpd && nargout >= 2 355 if mode ~= 3 356 v = RBsolve(v); 357 end 358 for ii = 1:k 359 vn = scaleB*(v(:,ii)'*(Bmtimes(v(:,ii)))); 360 v(:,ii) = v(:,ii)/sqrt(vn); 361 end 362 end 363 end 364 365 % Assign outputs. 366 if nargout <= 1 367 varargout{1} = d; 368 else 369 varargout{1} = v; 370 varargout{2} = diag(d); 371 end 372 if nargout >= 3 373 varargout{3} = flag; 374 end 375 376 cputms(4) = cputime-t0; % end timing post-processing 377 378 cputms(5) = sum(cputms(1:4)); % total time 379 380 if (eigs_display == 2) 381 printTimings; 382 end 383 384 %-------------------------------------------------------------------------% 385 % Nested functions 386 %-------------------------------------------------------------------------% 387 388 % checkInputs error checks the inputs to EIGS and also derives some 389 % variables from them: 390 % A may be a matrix or a function applying OP. 391 % Amatrix is true if A is a matrix, false if A is a function. 392 % isrealprob is true if all of A, B and sigma are real, false otherwise. 393 % issymA is true if A is symmetric, false otherwise. 394 % n is the size of (square) A and B. 395 % B is [] for the standard problem. Otherwise it may be one of B, CHOL(B) 396 % or CHOL(B(permB,permB)). 397 % classAB is single if either A or B is single, otherwise double. 398 % k is the number of eigenvalues to be computed. 399 % eigs_sigma is the value for sigma passed in by the user, 'LM' if it was 400 % unspecified. eigs_sigma may be either a string or a scalar value. 401 % whch is the ARPACK string corresponding to eigs_sigma and mode. 402 % sigma is the ARPACK scalar corresponding to eigs_sigma and mode. 403 % tol is the convergence tolerance. 404 % maxit is the maximum number of iterations. 405 % p is the number of Lanczos vectors. 406 % info is the start value, initialized to 1 or 0 to indicate whether to use 407 % resid as the start vector or not. 408 % eigs_display is true if Ritz values should be displayed, false otherwise. 409 % cholB is true if CHOL(B) was passed in instead of B, false otherwise. 410 % permB may be [], otherwise it is the permutation in CHOL(B(permB,permB)). 411 % resid is the start vector if specified and info=1, otherwise all zero. 412 % useeig is true if we need to use EIG instead of ARPACK, otherwise false. 413 % afunNargs is the range of EIGS' varargin that are to be passed as 414 % trailing parameters to the function as in afun(X,P1,P2,...). 415 function [A,Amatrix,isrealprob,issymA,n,B,classAB,k, ... 416 eigs_sigma,whch,sigma,tol,maxit,p,info,eigs_display,cholB,... 417 permB,resid,useeig,afunNargs,style,mode,Afactors,Bfactors] = checkInputs(varargin) 418 % Process inputs and do error-checking 419 420 % Process the input A or the inputs AFUN and N 421 % Start to derive some qualities (real, symmetric) about the problem 422 if isfloat(varargin{1}) 423 A = varargin{1}; 424 Amatrix = true; 425 else 426 % By checking the function A with fcnchk, we can now use direct 427 % function evaluation on the result, without resorting to feval 428 [A,notFunc] = fcnchk(varargin{1}); 429 Amatrix = false; 430 if ~isempty(notFunc) 431 error(message('MATLAB:eigs:NonDoubleOrFunction')); 432 end 433 end 434 isrealprob = true; 435 issymA = false; 436 if Amatrix 437 isrealprob = isreal(A); 438 issymA = ishermitian(A); 439 [m,n] = size(A); 440 if (m ~= n) 441 error(message('MATLAB:eigs:NonSquareMatrixOrFunction')); 442 end 443 else 444 n = varargin{2}; 445 if ~isscalar(n) || ~isreal(n) || (n<0) || ~isfinite(n) 446 error(message('MATLAB:eigs:NonPosIntSize')); 447 end 448 if issparse(n) 449 n = full(n); 450 end 451 if (round(n) ~= n) 452 warning(message('MATLAB:eigs:RoundNonIntSize')); 453 n = round(n); 454 end 455 end 456 457 % Process the input B and derive the class of the problem. 458 % Is B present in the eigs call or not? 459 Bpresent = true; 460 if (nargin < (3-Amatrix)) 461 B = []; 462 Bpresent = false; 463 else 464 % Is the next input B or K? 465 B = varargin{3-Amatrix}; 466 if ~isempty(B) % allow eigs(A,[],k,sigma,opts); 467 if isscalar(B) 468 if n ~= 1 469 % this input is really K and B is not specified 470 B = []; 471 Bpresent = false; 472 else 473 % This input could be B or K. 474 % If A is scalar, then the only valid value for k is 1. 475 % So if this input is scalar, let it be B, namely 476 % eigs(4,2,...) assumes A=4, B=2, NOT A=4, k=2 477 if ~isnumeric(B) 478 error(message('MATLAB:eigs:BsizeMismatchA')); 479 end 480 % Unless, of course, the scalar is 1, in which case 481 % assume the that it is meant to be K. 482 if (B == 1) && ((Amatrix && nargin <= 3) || ... 483 (~Amatrix && nargin <= 4)) 484 B = []; 485 Bpresent = false; 486 elseif ~isfloat(B) 487 error(message('MATLAB:eigs:BsizeMismatchA')); 488 end 489 end 490 else 491 % B is a not a scalar. 492 if ~isfloat(B) || ~isequal(size(B),[n,n]) 493 error(message('MATLAB:eigs:BsizeMismatchA')); 494 end 495 isrealprob = isrealprob && isreal(B); 496 end 497 end 498 end 499 % ARPACK can only handle homogeneous inputs 500 if Amatrix 501 classAB = superiorfloat(A,B); 502 A = cast(A,classAB); 503 B = cast(B,classAB); 504 else 505 if ~isempty(B) 506 classAB = class(B); 507 else 508 classAB = 'double'; 509 end 510 end 511 512 % argOffset tells us where to get the eigs inputs K, SIGMA and OPTS. 513 % If A is really the function afun, then it also helps us find the 514 % trailing parameters in eigs(afun,n,[B],k,sigma,opts,P1,P2,...) 515 % Values of argOffset: 516 % 0: Amatrix is false and Bpresent is true: 517 % eigs(afun,n,B,k,sigma,opts,P1,P2,...) 518 % 1: Amatrix and Bpresent are both true, or both false 519 % eigs(A,B,k,sigma,opts) 520 % eigs(afun,n,k,sigma,opts,P1,P2,...) 521 % 2: Amatrix is true and Bpresent is false: 522 % eigs(A,k,sigma,opts) 523 argOffset = Amatrix + ~Bpresent; 524 525 if Amatrix && ((nargin - Bpresent)>4) 526 error(message('MATLAB:eigs:TooManyInputs')); 527 end 528 529 % Process the input K. 530 if (nargin < (4-argOffset)) 531 k = min(n,6); 532 else 533 k = varargin{4-argOffset}; 534 if ~isnumeric(k) || ~isscalar(k) || ~isreal(k) || (k>n) || ... 535 (k<0) || ~isfinite(k) 536 error(message('MATLAB:eigs:NonIntegerEigQty')); 537 end 538 if issparse(k) 539 k = full(k); 540 end 541 if (round(k) ~= k) 542 warning(message('MATLAB:eigs:RoundNonIntegerEigQty')); 543 k = round(k); 544 end 545 end 546 547 % Process the input SIGMA and derive ARPACK values whch and sigma. 548 % eigs_sigma is the value documented in the help as "SIGMA" that is 549 % passed in to EIGS. eigs_sigma may be either a scalar, including 0, 550 % or a string, including 'SM'. 551 % In ARPACK, eigs_sigma corresponds to two variables: 552 % 1. which, called "whch" to avoid conflict with MATLAB's function 553 % 2. sigma 554 % whch is always a string. sigma is always a scalar. 555 % Valid combinations are shown below. Note eigs_sigma = 0/'SM' has 556 % the same sigma/whch values as eigs_sigma='LM' (default) so these 557 % must be distinguished by the mode. 558 % eigs_sigma = 'SM' or 0 => sigma = 0, whch = 'LM' (mode=3) 559 % eigs_sigma is a string not 'SM' => sigma = 0, whch = eigs_sigma (mode=1) 560 % eigs_sigma is any scalar => sigma = eigs_sigma, whch = 'LM' 561 % (mode=1) 562 if (nargin < (5-argOffset)) 563 % default: eigs 'LM' => ARPACK which='LM', sigma=0 564 eigs_sigma = 'LM'; 565 whch = 'LM'; 566 sigma = 0; 567 else 568 eigs_sigma = varargin{5-argOffset}; 569 if ischar(eigs_sigma) 570 % eigs(string) => ARPACK which=string, sigma=0 571 if ~isequal(size(eigs_sigma),[1,2]) 572 error(message('MATLAB:eigs:EigenvalueRangeNotValid')); 573 end 574 eigs_sigma = upper(eigs_sigma); 575 if strcmp(eigs_sigma,'SM') 576 % eigs('SM') => ARPACK which='LM', sigma=0 577 whch = 'LM'; 578 else 579 % eigs(string), where string~='SM' => ARPACK which=string, sigma=0 580 whch = eigs_sigma; 581 end 582 sigma = zeros(classAB); 583 else 584 % eigs(scalar) => ARPACK which='LM', sigma=scalar 585 if ~isfloat(eigs_sigma) || ~isscalar(eigs_sigma) 586 error(message('MATLAB:eigs:EigenvalueShiftNonScalar')); 587 end 588 sigma = eigs_sigma; 589 if issparse(sigma) 590 sigma = full(sigma); 591 end 592 sigma = cast(sigma,classAB); 593 isrealprob = isrealprob && isreal(sigma); 594 whch = 'LM'; 595 end 596 end 597 598 % Process the input OPTS and derive some ARPACK values. 599 % ARPACK's minimum tolerance is eps/2 ([S/D]LAMCH's EPS) 600 tol = eps(classAB); 601 maxit = []; 602 p = []; 603 % Always use resid as the start vector, whether it is OPTS.v0 or 604 % randomly generated within eigs. We default resid to empty here. 605 % If the user does not initialize it, we provide a random residual 606 % below. 607 info = intconvert(1); 608 resid = []; 609 eigs_display = 0; 610 cholB = false; % do we have B or its Cholesky factor? 611 permB = []; % if cholB, is it chol(B), or chol(B(permB,permB))? 612 if (nargin >= (6-argOffset)) 613 opts = varargin{6-argOffset}; 614 if ~isa(opts,'struct') 615 error(message('MATLAB:eigs:OptionsNotStructure')); 616 end 617 if isfield(opts,'issym') && ~Amatrix 618 issymA = opts.issym; 619 if (issymA ~= false) && (issymA ~= true) 620 error(message('MATLAB:eigs:InvalidOptsIssym')); 621 end 622 end 623 if isfield(opts,'isreal') && ~Amatrix 624 if (opts.isreal ~= false) && (opts.isreal ~= true) 625 error(message('MATLAB:eigs:InvalidOptsIsreal')); 626 end 627 isrealprob = isrealprob && opts.isreal; 628 end 629 if ~isempty(B) && (isfield(opts,'cholB') || isfield(opts,'permB')) 630 if isfield(opts,'cholB') 631 cholB = opts.cholB; 632 if (cholB ~= false) && (cholB ~= true) 633 error(message('MATLAB:eigs:InvalidOptsCholB')); 634 end 635 if isfield(opts,'permB') 636 if issparse(B) && cholB 637 permB = opts.permB; 638 if ~isvector(permB) || ~isequal(sort(permB(:)),(1:n)') 639 error(message('MATLAB:eigs:InvalidOptsPermB')); 640 end 641 else 642 warning(message('MATLAB:eigs:IgnoredOptionPermB')); 643 end 644 end 645 end 646 end 647 if isfield(opts,'tol') 648 if ~isfloat(tol) || ~isscalar(opts.tol) || ~isreal(opts.tol) || (opts.tol<=0) 649 error(message('MATLAB:eigs:InvalidOptsTol')); 650 end 651 tol = cast(full(opts.tol),classAB); 652 end 653 if isfield(opts,'p') 654 p = opts.p; 655 if ~isnumeric(p) || ~isscalar(p) || ~isreal(p) || (p<=0) || (p>n) 656 error(message('MATLAB:eigs:InvalidOptsP')); 657 end 658 if issparse(p) 659 p = full(p); 660 end 661 if (round(p) ~= p) 662 warning(message('MATLAB:eigs:NonIntegerVecQty')); 663 p = round(p); 664 end 665 end 666 if isfield(opts,'maxit') 667 maxit = opts.maxit; 668 if ~isnumeric(maxit) || ~isscalar(maxit) || ~isreal(maxit) ... 669 || (maxit<=0) || ~isfinite(maxit) 670 error(message('MATLAB:eigs:OptsMaxitNotPosInt')); 671 end 672 if issparse(maxit) 673 maxit = full(maxit); 674 end 675 if (round(maxit) ~= maxit) 676 warning(message('MATLAB:eigs:NonIntegerIterationQty')); 677 maxit = round(maxit); 678 end 679 end 680 if isfield(opts,'v0') 681 if ~isfloat(opts.v0) || ~isequal(size(opts.v0),[n,1]) 682 error(message('MATLAB:eigs:WrongSizeOptsV0')); 683 end 684 if isrealprob 685 if ~isreal(opts.v0) 686 error(message('MATLAB:eigs:NotRealOptsV0')); 687 end 688 resid(1:n,1) = full(opts.v0); 689 else 690 resid(2:2:2*n,1) = full(imag(opts.v0)); 691 resid(1:2:(2*n-1),1) = full(real(opts.v0)); 692 end 693 end 694 if isfield(opts,'disp') 695 eigs_display = opts.disp; 696 if ~isnumeric(eigs_display) || ~isscalar(eigs_display) || ... 697 ~isreal(eigs_display) || (eigs_display<0) 698 error(message('MATLAB:eigs:NonIntegerDiagnosticLevel')); 699 end 700 if (round(eigs_display) ~= eigs_display) 701 warning(message('MATLAB:eigs:RoundNonIntDiagnosticLevel')); 702 eigs_display = round(eigs_display); 703 end 704 end 705 end 706 if (isempty(resid)) 707 if isrealprob 708 resid = cast(rand(n,1),classAB); 709 else 710 resid = cast(rand(2*n,1),classAB); 711 end 712 end 713 714 afunNargs = zeros(1,0); 715 if ~Amatrix 716 % The trailing parameters for afun start at varargin{7-argOffset} 717 % in eigs(afun,n,[B],k,sigma,opts,P1,P2,...). If there are no 718 % trailing parameters in eigs, then afunNargs is a 1-by-0 empty 719 % and no trailing parameters are passed to afun(x) 720 afunNargs = 7-argOffset:nargin; 721 end 722 723 % Now that OPTS has been processed, do final error checking and 724 % assign ARPACK variables 725 726 % Extra check on input B 727 if ~isempty(B) 728 % B must be symmetric (Hermitian) positive (semi-)definite 729 if cholB 730 if ~isequal(triu(B),B) 731 error(message('MATLAB:eigs:BNotChol')); 732 end 733 end 734 end 735 736 style = 'S'; 737 if strcmp(eigs_sigma,'SM') || isscalar(eigs_sigma) || ~isempty(B) 738 style = 'G'; 739 end 740 741 if ~isempty(B) 742 scaleB = norm(B,'fro')/sqrt(n); 743 scaleB = 2^(floor(log2(scaleB+1))); 744 B = B/scaleB; 745 if cholB 746 scaleB = scaleB^2; 747 end 748 if isscalar(eigs_sigma) 749 sigma = scaleB*eigs_sigma; 750 end 751 end 752 753 754 if strcmp(eigs_sigma,'SM') || ~ischar(eigs_sigma) 755 % eigs(A,B,k,scalarSigma) or eigs(A,B,k,'SM'), B may be [] 756 % Note: sigma must be real for [s,d]saupd and [s,d]naupd 757 % If sigma is complex, even if A and B are both real, we use 758 % [c,z]naupd. 759 % This means that mode=3 in [s,d]naupd, which has 760 % OP = real(inv(A - sigma*M)*M) and B = M 761 % reduces to the same OP as [s,d]saupd and [c,z]naupd. 762 % A*x = lambda*M*x, M symmetric (positive) semi-definite 763 % => OP = inv(A - sigma*M)*M and B = M 764 % => shift-and-invert mode 765 mode = 3; 766 elseif strcmp(style,'S') 767 % eigs(A,k,stringSigma) or eigs(A,[],k,stringSigma), 768 % stringSigma~='SM' 769 % A*x = lambda*x 770 % => OP = A and B = I 771 mode = 1; 772 else 773 % eigs(A,B,k,stringSigma), stringSigma~='SM' 774 % A*x = lambda*B*x 775 % => OP = inv(B)*A and use standard inner product. 776 mode = 1; 777 end 778 779 BisHpd = false; 780 if cholB || (~isempty(B) && ishermitian(B)) 781 % The reordering permutation permB is [] unless B is sparse 782 [RB,RBT,permB,BisHpd] = CHOLfactorB; 783 if mode == 3 && ~cholB 784 RB = []; RBT = []; permB = []; 785 end 786 end 787 788 qqB = []; 789 if BisHpd == false && (mode == 1 || mode == 2) 790 [LB,UB,ppB,qqB,dgB] = LUfactorB; 791 end 792 793 Bfactors = []; 794 if ~isempty(B) 795 if BisHpd == true 796 Bfactors = struct('RB',RB,'RBT',RBT,'permB',permB,'BisHpd',BisHpd); 797 elseif (mode == 1 || mode == 2) 798 Bfactors = struct('LB',LB,'UB',UB,'ppB',ppB,'qqB',qqB,'dgB',dgB,'BisHpd',BisHpd); 799 end 800 end 801 802 Afactors = []; 803 qq = []; 804 if (mode == 3) && Amatrix % need lu(A-sigma*B) 805 % The reordering permutation permAsB is [] unless A-sigma*B is sparse 806 [L,U,pp,qq,dgAsB] = LUfactorAminusSigmaB; 807 Afactors = struct('L',L,'U',U,'pp',pp,'qq',qq,'dgAsB',dgAsB); 808 end % if (mode == 3) && Amatrix 809 810 % under these conditions, OP must be unsymmetric 811 % note that OP = inv(A-\sigma*B)*B IS symmetric if A is symmetric 812 % and B-inner product is used! 813 if ~isempty(B) && (BisHpd == false || (strcmp(style,'S') && mode == 3)) 814 issymA = false; 815 end 816 % Extra check on input K 817 % We fall back on using the full EIG code if K is too large. 818 useeig = false; 819 if (k == 0) 820 useeig = true; 821 end 822 if isrealprob && issymA 823 if (k > n-1) 824 if (n >= 6) 825 warning(message('MATLAB:eigs:TooManyRequestedEigsForRealSym')); 826 end 827 useeig = true; 828 end 829 else 830 if (k > n-2) 831 if (n >= 7) 832 warning(message('MATLAB:eigs:TooManyRequestedEigsForComplexNonsym')); 833 end 834 useeig = true; 835 end 836 end 837 838 % Extra check on input SIGMA 839 if issymA && ~isreal(sigma) 840 warning(message('MATLAB:eigs:ComplexShiftForHermitianProblem')); 841 end 842 843 if isrealprob && issymA 844 if strcmp(whch,'LR') 845 whch = 'LA'; 846 warning(message('MATLAB:eigs:SigmaChangedToLA')); 847 end 848 if strcmp(whch,'SR') 849 whch = 'SA'; 850 warning(message('MATLAB:eigs:SigmaChangedToSA')); 851 end 852 if ~ismember(whch,{'LM', 'SM', 'LA', 'SA', 'BE'}) 853 error(message('MATLAB:eigs:EigenvalueRangeNotValid')); 854 end 855 else 856 if strcmp(whch,'BE') 857 warning(message('MATLAB:eigs:SigmaChangedToLM')); 858 whch = 'LM'; 859 end 860 if ~ismember(whch,{'LM', 'SM', 'LR', 'SR', 'LI', 'SI'}) 861 error(message('MATLAB:eigs:EigenvalueRangeNotValid')); 862 end 863 end 864 865 % The remainder of the error checking does not apply for the large 866 % values of K that force us to use full EIG instead of ARPACK. 867 if useeig 868 return 869 end 870 871 % Extra check on input OPTS.p 872 if isempty(p) 873 if isrealprob && ~issymA 874 p = min(max(2*k+1,20),n); 875 else 876 p = min(max(2*k,20),n); 877 end 878 else 879 if isrealprob && issymA 880 if (p <= k) 881 error(message('MATLAB:eigs:InvalidOptsPforRealSymProb')); 882 end 883 else 884 if (p <= k+1) 885 error(message('MATLAB:eigs:InvalidOptsPforComplexOrNonSymProb')); 886 end 887 end 888 end 889 890 % Extra check on input OPTS.maxit 891 if isempty(maxit) 892 maxit = max(300,ceil(2*n/max(p,1))); 893 end 894 895 896 % Nested functions in checkInputs 897 %-------------------------------------------------------------------------% 898 function [RB,RBT,ppB,BisHpd] = CHOLfactorB 899 % permB may be [] (from checkInputs) if the problem is not sparse 900 % or if it was not passed in as opts.permB 901 ppB = permB; 902 if cholB 903 % CHOL(B) was passed in as B 904 RB = B; 905 RBT = B'; 906 BisHpd = true; 907 else 908 % CHOL(B) was not passed into EIGS 909 if ~isempty(B) 910 % Algorithm requires CHOL(B) to be computed 911 if issparse(B) 912 [RB,idxB,ppB] = chol(B,'vector'); 913 else 914 [RB,idxB] = chol(B); 915 end 916 if mode == 3 917 RB = []; ppB = []; 918 end 919 RBT = RB'; 920 if (idxB == 0) 921 BisHpd = true; 922 elseif mode == 3 && isreal(B) 923 % LDL decomposition is only for 'SM' eigenvalues of the 924 % pair (A,B) where B is Hermitian positive 925 % semi-definite; in this case, as ARPACK users' guide 926 % suggests, one should still use B-(semi)inner product 927 [~,DB,~] = ldl(B,'vector'); 928 BisHpd = checkTridiagForHSD(diag(DB), diag(DB,1)); 929 else 930 BisHpd = false; 931 end 932 end 933 end 934 if ~isempty(B) && issparse(B) 935 tmp = speye(length(B)); 936 ppB = tmp(ppB,1:length(B)); 937 end 938 end % CHOLfactorB 939 %-------------------------------------------------------------------------% 940 function [LB,UB,ppB,qqB,dgB] = LUfactorB 941 % LU factor B, including a reordering perm if it is sparse 942 if issparse(B) 943 [LB,UB,ppB,qqB,dgB] = lu(B); 944 else 945 [LB,UB,ppB] = lu(B,'vector'); 946 qqB = []; dgB = []; 947 end 948 % Warn if lu(B) is ill-conditioned 949 dUB = diag(UB); 950 if any(dUB == 0) || any(diag(LB) == 0) 951 error(message('MATLAB:eigs:SingularB')); 952 end 953 rcondestUB = full(min(abs(dUB)) / max(abs(dUB))); 954 if (rcondestUB < eps) 955 warning(message('MATLAB:eigs:IllConditionedB', sprintf('%f',rcondestUB))); 956 end 957 end % LUfactorB 958 959 %-------------------------------------------------------------------------% 960 function [L,U,pp,qq,dgAsB] = LUfactorAminusSigmaB 961 % LU factor A-sigma*B, including a reordering perm if it is sparse 962 if sigma == 0 963 AsB = A; 964 elseif isempty(B) 965 if issparse(A) 966 AsB = A - sigma * speye(n); 967 else 968 AsB = A - sigma * eye(n); 969 end 970 else 971 if cholB 972 if issparse(B) 973 AsB = A - sigma * checkInputBmtimes(speye(n)); 974 else 975 AsB = A - sigma * checkInputBmtimes(eye(n)); 976 end 977 else 978 AsB = A - sigma * B; 979 end 980 end 981 if issparse(AsB) 982 [L,U,pp,qq,dgAsB] = lu(AsB); 983 else 984 [L,U,pp] = lu(AsB,'vector'); 985 qq = []; dgAsB = []; 986 end 987 % Warn if lu(A-sigma*B) is ill-conditioned 988 % => sigma is close to an exact eigenvalue of (A,B) 989 dU = diag(U); 990 if any(dU == 0) || any(diag(L) == 0) 991 error(message('MATLAB:eigs:AminusBSingular')); 992 end 993 rcondestU = full(min(abs(dU)) / max(abs(dU))); 994 if (rcondestU < eps) 995 warning(message('MATLAB:eigs:SigmaNearExactEig',sprintf('%f',rcondestU))); 996 end 997 end % LUfactorAminusSigmaB 998 999 %-------------------------------------------------------------------------% 1000 function v = checkInputBmtimes(u) 1001 % Matrix-vector multiply v = B*u 1002 if cholB % use B's cholesky factor and its transpose 1003 if ~isempty(permB) 1004 v = permB'*(RBT * (RB * (permB*u))); 1005 else 1006 v = RBT * (RB * u); 1007 end 1008 else 1009 v = B * u; 1010 end 1011 end 1012 1013 end % checkInputs 1014 1015 %-------------------------------------------------------------------------% 1016 function fullEig(nOutputs) 1017 % Use EIG(FULL(A)) or EIG(FULL(A),FULL(B)) instead of ARPACK 1018 if ~isempty(B) 1019 B = Bmtimes(eye(n)); 1020 B = full(B*scaleB); 1021 end 1022 if isfloat(A) 1023 if issparse(A); 1024 A = full(A); 1025 end 1026 else 1027 % A is specified by a function. 1028 % Form the matrix A by applying the function. 1029 if ischar(eigs_sigma) && ~strcmp(eigs_sigma,'SM') 1030 % A is a function multiplying A*x 1031 AA = eye(n); 1032 for i = 1:n 1033 AA(:,i) = A(AA(:,i),varargin{afunNargs}); 1034 end 1035 A = AA; 1036 else 1037 if (isfloat(eigs_sigma) && eigs_sigma == 0) || strcmp(eigs_sigma,'SM') 1038 % A is a function solving A\x 1039 invA = eye(n); 1040 for i = 1:n 1041 invA(:,i) = A(invA(:,i),varargin{afunNargs}); 1042 end 1043 A = eye(n) / invA; 1044 else 1045 % A is a function solving (A-sigma*B)\x 1046 % B may be [], indicating the identity matrix 1047 % U = (A-sigma*B)\sigma*B 1048 % => (A-sigma*B)*U = sigma*B 1049 % => A*U = sigma*B(U + eye(n)) 1050 % => A = sigma*B(U + eye(n)) / U 1051 if isempty(B) 1052 sB = eigs_sigma*eye(n); 1053 else 1054 sB = eigs_sigma*B; 1055 end 1056 U = zeros(n,n); 1057 for i = 1:n 1058 U(:,i) = A(sB(:,i),varargin{afunNargs}); 1059 end 1060 A = sB*(U+eye(n)) / U; 1061 end 1062 end 1063 end 1064 1065 if isempty(B) 1066 eigInputs = {A}; 1067 else 1068 eigInputs = {A,B}; 1069 end 1070 % Now with full floating point matrices A and B, use EIG: 1071 if (nOutputs <= 1) 1072 d = eig(eigInputs{:}); 1073 else 1074 [V,D] = eig(eigInputs{:}); 1075 d = diag(D); 1076 end 1077 1078 % Grab the eigenvalues we want, based on sigma 1079 firstKindices = 1:k; 1080 lastKindices = n:-1:n-k+1; 1081 if ischar(eigs_sigma) 1082 switch eigs_sigma 1083 case 'LM' 1084 [~,ind] = sort(abs(d)); 1085 range = lastKindices; 1086 case 'SM' 1087 [~,ind] = sort(abs(d)); 1088 range = firstKindices; 1089 case 'LA' 1090 [~,ind] = sort(d); 1091 range = lastKindices; 1092 case 'SA' 1093 [~,ind] = sort(d); 1094 range = firstKindices; 1095 case 'LR' 1096 [~,ind] = sort(abs(real(d))); 1097 range = lastKindices; 1098 case 'SR' 1099 [~,ind] = sort(abs(real(d))); 1100 range = firstKindices; 1101 case 'LI' 1102 [~,ind] = sort(abs(imag(d))); 1103 range = lastKindices; 1104 case 'SI' 1105 [~,ind] = sort(abs(imag(d))); 1106 range = firstKindices; 1107 case 'BE' 1108 [~,ind] = sort(abs(d)); 1109 range = [1:floor(k/2), n-ceil(k/2)+1:n]; 1110 end 1111 else 1112 % sigma is a scalar 1113 [~,ind] = sort(abs(d-eigs_sigma)); 1114 range = 1:k; 1115 end 1116 1117 if (nOutputs <= 1) 1118 varargout{1} = d(ind(range)); 1119 else 1120 varargout{1} = V(:,ind(range)); 1121 varargout{2} = D(ind(range),ind(range)); 1122 if (nOutputs == 3) 1123 % flag indicates "convergence" 1124 varargout{3} = 0; 1125 end 1126 end 1127 1128 end % FULLEIG 1129 1130 1131 %-------------------------------------------------------------------------% 1132 function cols = checkIpntr 1133 % Check that ipntr returned from ARPACK refers to the start of a 1134 % column of workd. 1135 if ido == 1 1136 inds = double(ipntr(1:3)); 1137 else 1138 inds = double(ipntr(1:2)); 1139 end 1140 rows = mod(inds-1,n)+1; 1141 cols = (inds-rows)/n+1; 1142 if ~all(rows==1) 1143 error(message('MATLAB:eigs:ipntrMismatchWorkdColumn', n)); 1144 end 1145 end % checkIpntr 1146 1147 %-------------------------------------------------------------------------% 1148 function v = Amtimes(u) 1149 % Matrix-vector multiply v = A*u 1150 if Amatrix 1151 v = A * u; 1152 else % A is a function 1153 v = A(u,varargin{afunNargs}); 1154 if isrealprob && ~isreal(v) 1155 error(message('MATLAB:eigs:complexFunction')); 1156 end 1157 end 1158 end 1159 1160 %-------------------------------------------------------------------------% 1161 function v = Bmtimes(u) 1162 % Matrix-vector multiply v = B*u 1163 if cholB % use B's cholesky factor and its transpose 1164 if ~isempty(permB) 1165 v = permB'*(RBT * (RB * (permB*u))); 1166 else 1167 v = RBT * (RB * u); 1168 end 1169 else 1170 v = B * u; 1171 end 1172 end 1173 1174 %-------------------------------------------------------------------------% 1175 function v = RBsolve(u) 1176 % Solve v = RB\u for v 1177 if issparse(B) 1178 if ~isempty(permB) 1179 v = permB'*(RB \ u); 1180 else 1181 v = RB \ u; 1182 end 1183 else 1184 RBopts.UT = true; 1185 v = linsolve(RB,u,RBopts); 1186 end 1187 end 1188 1189 %-------------------------------------------------------------------------% 1190 function v = RBTsolve(u) 1191 % Solve v = RB'\u for v 1192 if issparse(B) 1193 if ~isempty(permB) 1194 v = RBT \ (permB*u); 1195 else 1196 v = RBT \ u; 1197 end 1198 else 1199 RBTopts.LT = true; 1200 v = linsolve(RBT,u,RBTopts); 1201 end 1202 end 1203 1204 %-------------------------------------------------------------------------% 1205 function v = AminusSigmaBsolve(u) 1206 % Solve v = (A-sigma*B)\u for v 1207 if Amatrix 1208 if ~isempty(dgAsB) 1209 % use LU reordering permAsB 1210 v = qq*(U \ (L \ (pp*(dgAsB\u)))); 1211 else 1212 v = U \ (L \ u(pp)); 1213 end 1214 else % A is a function 1215 v = A(u,varargin{afunNargs}); 1216 if isrealprob && ~isreal(v) 1217 error(message('MATLAB:eigs:complexFunction')); 1218 end 1219 end 1220 end % AminusSigmaBsolve 1221 %-------------------------------------------------------------------------% 1222 function v = Bsolve(u) 1223 % Solve v = (A-sigma*B)\u for v 1224 if ~isempty(dgB) 1225 % use LU reordering permAsB 1226 v = qqB*(UB \ (LB \ (ppB*(dgB\u)))); 1227 else 1228 v = UB \ (LB \ u(ppB)); 1229 end 1230 end % AminusSigmaBsolve 1231 1232 %-------------------------------------------------------------------------% 1233 function displayRitzValues 1234 % Display a few Ritz values at the current iteration 1235 iter = double(ipntr(15)); 1236 if (iter > eigs_iter) && (ido ~= 99) 1237 eigs_iter = iter; 1238 ds = getString(message('MATLAB:eigs:RitzValuesDisplayHeader',iter,p,p)); 1239 disp(ds) 1240 if isrealprob 1241 if issymA 1242 dispvec = workl(double(ipntr(6))+(0:p-1)); 1243 if strcmp(whch,'BE') 1244 % roughly k Large eigenvalues and k Small eigenvalues 1245 disp(dispvec(max(end-2*k+1,1):end)) 1246 else 1247 % k eigenvalues 1248 disp(dispvec(max(end-k+1,1):end)) 1249 end 1250 else 1251 dispvec = complex(workl(double(ipntr(6))+(0:p-1)), ... 1252 workl(double(ipntr(7))+(0:p-1))); 1253 % k+1 eigenvalues (keep complex conjugate pairs together) 1254 disp(dispvec(max(end-k,1):end)) 1255 end 1256 else 1257 dispvec = complex(workl(2*double(ipntr(6))-1+(0:2:2*(p-1))), ... 1258 workl(2*double(ipntr(6))+(0:2:2*(p-1)))); 1259 disp(dispvec(max(end-k+1,1):end)) 1260 end 1261 end 1262 end 1263 1264 %-------------------------------------------------------------------------% 1265 function flag = processEUPDinfo(warnNonConvergence) 1266 % Process the info flag returned by the ARPACK routine **eupd 1267 if (info ~= 0) 1268 switch double(info) 1269 case 2 1270 ss = sum(select); 1271 if (ss < k) 1272 error(message('MATLAB:eigs:ARPACKroutineError02ssLTk',eupdfun,ss,double(iparam(5)),k)); 1273 else 1274 error(message('MATLAB:eigs:ARPACKroutineError02', eupdfun, k)); 1275 end 1276 case 1 1277 error(message('MATLAB:eigs:ARPACKroutineError01', eupdfun)); 1278 case -14 1279 error(message('MATLAB:eigs:ARPACKroutineErrorMinus14', eupdfun, aupdfun)); 1280 otherwise 1281 error(message('MATLAB:eigs:ARPACKroutineError', eupdfun, full(info))); 1282 end 1283 end 1284 nconv = double(iparam(5)); 1285 flag = double(nconv < k); 1286 if (flag && warnNonConvergence) 1287 if (nconv == 0) 1288 warning(message('MATLAB:eigs:NoEigsConverged', k)); 1289 else 1290 warning(message('MATLAB:eigs:NotAllEigsConverged', nconv, k)); 1291 end 1292 end 1293 end % processEUPDinfo 1294 1295 %-------------------------------------------------------------------------% 1296 function printTimings 1297 % Print the time taken for each major stage of the EIGS algorithm 1298 if (mode == 1) 1299 innerstr = getString(message('MATLAB:eigs:PrintTimingsComputeAX',sprintf('%f',cputms(3)))); 1300 elseif (mode == 3) 1301 if isempty(B) 1302 innerstr = getString(message('MATLAB:eigs:PrintTimingsSolveASIGMAI',sprintf('%f',cputms(3)))); 1303 else 1304 innerstr = getString(message('MATLAB:eigs:PrintTimingsSolveASIGMAB',sprintf('%f',cputms(3)))); 1305 end 1306 end 1307 if ((mode == 3) && (Amatrix)) 1308 if isempty(B) 1309 prepstr = getString(message('MATLAB:eigs:PrintTimingsPreproSigmaI',sprintf('%f',cputms(1)))); 1310 else 1311 prepstr = getString(message('MATLAB:eigs:PrintTimingsPreproSigmaB',sprintf('%f',cputms(1)))); 1312 end 1313 else 1314 prepstr = getString(message('MATLAB:eigs:PrintTimingsPreprocessing',sprintf('%f',cputms(1)))); 1315 end 1316 sstr = getString(message('MATLAB:eigs:PrintTimingsCPUTimingResults')); 1317 postpstr = getString(message('MATLAB:eigs:PrintTimingsPostprocessing',sprintf('%f',cputms(4)))); 1318 totalstr = getString(message('MATLAB:eigs:PrintTimingsTotal',sprintf('%f',cputms(5)))); 1319 ds = sprintf(['\n' sstr '\n' ... 1320 prepstr ... 1321 'IRAM/IRLM: %f\n' ... 1322 innerstr ... 1323 postpstr... 1324 '***************************************************\n' ... 1325 totalstr ... 1326 sstr '\n'], ... 1327 cputms(2)); 1328 disp(ds) 1329 end % printTimings 1330 1331 %-------------------------------------------------------------------------% 1332 % End of nested functions 1333 %-------------------------------------------------------------------------% 1334 1335 end % EIGS 1336 1337 %-------------------------------------------------------------------------% 1338 % Subfunctions 1339 %-------------------------------------------------------------------------% 1340 function BisHpd = checkTridiagForHSD(alpha, beta) 1341 % CHECKTRIDIAGFORHSD 1342 % Uses Sturm sequence on alpha (diagonal) and beta (superdiagonal) to 1343 % determine if the matrix diag(alpha,0) + diag(beta,1) + diag(beta,-1) is 1344 % Positive Semi-definite. 1345 n = length(alpha); 1346 BisHpd = true; 1347 d = alpha(1); 1348 if d < 0 1349 BisHpd = false; 1350 return; 1351 end 1352 for k = 1:(n-1) 1353 if d == 0 1354 d = eps*(abs(beta(k))+eps); 1355 end 1356 d = alpha(k+1) - beta(k)*(beta(k)/d); 1357 if d < 0 1358 BisHpd = false; 1359 return; 1360 end 1361 end 1362 end % checkTridiagForHSD 1363 %-------------------------------------------------------------------------% 1364 % End of subfunctions 1365 %-------------------------------------------------------------------------%