Vous êtes sur la page 1sur 2

1 %% Sturm-Liouville eigenvalue problem solver including projections

2 % This script solves the classical Sturm-Liouville problem. This problem


3 % appears throughout applied mathematics and is similar to the traditional
4 % eigenvalue problem from linear algebra. However rather than a matrix we
5 % now have an operator and the variables are functions. We then project a
6 % function onto the basis formed by the eigenfunctions. The equations are:
7 %
8 % $$ \frac{d}{dx} (p(x) \frac{du}{dx}) + q(x) u(x) = -\lambda \sigma(x) u(x)$$
9 %
10 % $$ p(x) u''(x) + p'(x) u'(x) + q(x) u(x) = -\lambda \sigma(x) u(x) $$
11 %
12 % The inner product is $<u,v>=\int_{-1}^1 u(x) v(x) \sigma(x) dx$.
13 %%
14 clear all;close all
15 format long, format compact
16 %%
17 % Number of points and the derivative and integration material.
18 N=50;
19 [D,x]=cheb(N); D2=D^2; % Differentiation matrices.
20 [xi wt]=clencurt(N); % Integration coefficients.
21 %%
22 % Note the computational domain is [-1,1]
23 %%
24 % Define the various functions.
25 numdx=1e-8;
26 myp=@(x) 1+exp(-(x/0.2).^2);
27 mypx=@(x) (myp(x+numdx)-myp(x-numdx))/(2*numdx);
28 myq=@(x) x;
29 mysig=@(x) 1+0.5*sin(x*pi);
30 %%
31 % Build the operators.
32 myoplh=diag(myp(x))*D2+diag(mypx(x))*D+diag(myq(x));
33 myoprh=diag(mysig(x));
34 %%
35 % The boundary conditions are u=0 so just strip off the first and last
36 % row and column.
37 myoprh=myoprh(2:end-1,2:end-1);
38 myoplh=myoplh(2:end-1,2:end-1);
39 %%
40 % Solve the eigenvalue problem and sort the eigenvalues.
41 [myphis0 mylams0]=eig(myoplh,myoprh);
42 [mylams mylamsi]=sort(diag(mylams0),'descend');
43 %%
44 % Set the number of modes you wish to consider.
45 num_modes=20;
46 modesu=zeros(N+1,num_modes);
47 modesu(2:N,:)=myphis0(:,mylamsi(1:num_modes));
48 modese=zeros(size(modesu));
49 %% Calculate Modes
50 for k=1:num_modes
51 unow=modesu(:,k);
52 %%
53 % Normalize using the inner product.
54 normalizationu(k)=sqrt(sum(wt'.*unow.^2.*mysig(x)));
55 modesu(:,k)=unow/normalizationu(k);
56 %%
57 % Notice the way the Clenshaw Curtis weights come in.
58 end
59 %% Figure 1
60 figure(1)
61 clf
62 set(gcf,'DefaultLineLineWidth',2,'DefaultTextFontSize',12,...
63 'DefaultTextFontWeight','bold','DefaultAxesFontSize',12,...
64 'DefaultAxesFontWeight','bold');
65 plot(mylams(1:20),'bo')
66 xlabel('mode number')
67 ylabel('frequency')
68 grid on
69 %% Figure 2
70 figure(2)
71 clf
72 set(gcf,'DefaultLineLineWidth',2,'DefaultTextFontSize',12,...
73 'DefaultTextFontWeight','bold','DefaultAxesFontSize',12,...
74 'DefaultAxesFontWeight','bold');
75 plot(x,myp(x),'k-',x,myq(x),'b-',x,mysig(x),'r')
76 xlabel('x')
77 xlabel('Sturm Liouville functions')
78 legend('p(x)','q(x)','\sigma(x)')
79 %% Figure 3
80 figure(3)
81 clf
82 set(gcf,'DefaultLineLineWidth',2,'DefaultTextFontSize',12,...
83 'DefaultTextFontWeight','bold','DefaultAxesFontSize',12,...
84 'DefaultAxesFontWeight','bold');
85 for modei=1:6
86 subplot(6,1,modei)
87 plot(x,modesu(:,modei),'k-')
88 xlabel('x')
89 ylabel('e-funcs')
90 grid on
91 axis([-1 1 -2 2])
92 end
93 %% Projections
94 % Now for some projections. First choose the function to project. Anything
95 % that satisfies the BCs is OK.
96 f=sin(2*pi*x);
97 myapp=zeros(size(f));
98 for k=1:num_modes/2
99 phinow=modesu(:,k);
100 coeff(k)=sum(wt'.*phinow.*f.*mysig(x));
101 myapp=myapp+coeff(k)*phinow;
102 end
103 myapphalf=myapp;
104 for k=(num_modes/2+1):num_modes
105 phinow=modesu(:,k);
106 coeff(k)=sum(wt'.*phinow.*f.*mysig(x));
107 myapp=myapp+coeff(k)*phinow;
108 end
109 %% Figure 4
110 figure(4)
111 clf
112 set(gcf,'DefaultLineLineWidth',2,'DefaultTextFontSize',12,...
113 'DefaultTextFontWeight','bold','DefaultAxesFontSize',12,...
114 'DefaultAxesFontWeight','bold');
115 subplot(2,1,1)
116 plot(x,f,'k',x,myapp,'b',x,myapphalf,'r')
117 xlabel('x')
118 ylabel('f and its approximation')
119 grid on
120 title(['f and its approximation using ' int2str(num_modes) ' and ' int2str(num_modes/2)
' us'])
121 subplot(2,1,2)
122 plot(x,f-myapp,'b',x,f-myapphalf,'r')
123 legend('full approx','half approx')
124 grid on
125 xlabel('x')
126 ylabel('error')
127
128

Vous aimerez peut-être aussi