Advertisement
Guest User

wnum

a guest
Jan 24th, 2020
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.54 KB | None | 0 0
  1. clear all;
  2. close all;
  3. clc;
  4. %O co tu chodzi? Matlab ma zbiór rowziązywaczy układów równań
  5. %różniczkowych. Tzw funkcji ODE. Różnią się one trochę, jedne działają
  6. %wolniej a dokładniej, inne odwrotnie. My zajmiemy się ode45 i ode15s. Ta
  7. %pierwsza jest właśnie wolniejsza ale dokładniejsza, ta druga szybsza, ale
  8. %mniej dokładna. Taka funkcja ode zwraca nam dyskrętną dziedzinę czasu
  9. %którą sobie dobrała dla danego przypadku(bo jest na tyle mądra) oraz
  10. %oczywiście gotowe rozwiązanie.
  11.  
  12. tspan=[0 30*1e-3]; %Potrzebujemy przedziału czasowego
  13. u0=[0;1]; %I wartości początkowych dla naszej metody ode
  14.  
  15. [t_45,u_45]=ode45('odefun',tspan,u0); %A co to odefun? Wyjasniłem w m-pliku o tej nazwie.
  16.  
  17. %t_45 to nasza dziedzina czasu, a u_45 to macierz, która zawiera dwie kolumny tj. jedną i
  18. %druga funkcję której szukaliœmy czyli u1(t) i u2(t). Nazwy zmiennych dla
  19. %zachowania porządku.
  20.  
  21. [t_15s,u_15s]=ode15s('odefun',tspan,u0);
  22.  
  23. %No dobra, zatem mamy już nasze policzone rozwiązania przybliżone, a co z
  24. %dokładnym? No cóż, w przypadku układu równań sprawa nie jest taka prosta.
  25. %Jak spojrzymy na to jak każą nam policzyć u2 dokładnie, to można się
  26. %zagubić. Nie umiem szczególnie układów równań rózniczkowych, ale najwyrażniej
  27. %jakoś da się to zrobić, żeby wyliczyć stałe c1 i c2, od których nasze
  28. %rozwiązanie dokładne zależy. Można to zrobić przy pomocy wartości
  29. %własnych(Było coś takiego na algebrze) macierzy A. Co to macierz A?
  30. %Wspominałem w pliku z funkcją odefun że nasz układ możemy zapisać w
  31. %postaci du/dt=A*u+b. Pamiętamy metody rozwiązywania układów równań
  32. %liniowych za pomocą macierzy? Było na algebrze i pierwszej labce z wnum.
  33. %
  34. % Jeżeli mamy układ:
  35. % y1'=2y1+3y2 + 5
  36. % y2'=4y1+6y2 + 8
  37. % To nasza macierz A=[2,3;4,6], a b=[5;8].
  38. %
  39. %Trzeba więc doprowadzić nasz układ do takiej postaci, żeby widzieć wyraźnie
  40. %co stoi w obu równaniach przy u1 i u2, a po lewej stronie mieć tylko du1/dt
  41. %lub du2/dt. Całe szczęście, że proszą nas tylko o zajęcie się funkcją u2.
  42.  
  43. R1=1e3;
  44. R2=R1;
  45. C1=1e-8;
  46. C2=2e-6;
  47. E=2;
  48. %Nasza macierz A
  49. A=[-2/(R1*C1), 1/(R1*C1); 1/(R2*C2), -1/(R2*C2)];
  50.  
  51. wart_wl=eig(A); %Do liczenia takich wartoœci własnych mamy ładnš funkcję eig()
  52.  
  53. lam1=wart_wl(1);%Mamy nasze lambda1 i lambda2
  54. lam2=wart_wl(2);
  55.  
  56. c1=(lam2/(lam1-lam2)) * (E - u0(1)* (1+lam2*R2*C2)/(lam2*R2*C2)+ (u0(2)*1)/(lam2*R2*C2));
  57. c2= -E-c1+u0(2);
  58.  
  59. %No i mamy nasze rowzišzanie dokładne. Potrzebujemy dwóch wersji, żeby
  60. %póŸniej ładnie móc policzyć błędy. Tzn żeby wymiary macierzy się zgadzały.
  61. u2d_45=c1*exp(lam1*t_45) + c2*exp(lam2*t_45) + E;
  62. u2d_15s=c1*exp(lam1*t_15s) + c2*exp(lam2*t_15s) + E;
  63.  
  64. u2_45=u_45(:,2); % : znaczy "wszystko". Czyli bierzemy całš drugš kolumnę
  65. u2_15s=u_15s(:,2);
  66.  
  67. figure
  68. plot(t_45,u2d_45,'-g');
  69. hold on;
  70. grid on;
  71. plot(t_45,u2_45,'--r');
  72. legend('dokładne','wyliczone');
  73. title('ode45');
  74.  
  75. figure
  76. plot(t_15s,u2d_15s,'-g');
  77. hold on;
  78. grid on;
  79. plot(t_15s,u2_15s,'--r');
  80. legend('dokładne','wyliczone');
  81. title('ode15s');
  82.  
  83. %===========b)=======================
  84.  
  85.  
  86. %A jak policzyć błędy? Tak jak w zadaniu 1
  87. max_err1_45=max(abs(u2d_45-u2_45))
  88. max_err1_15s=max(abs(u2d_15s-u2_15s))
  89. %No i widzimy, że ode_15s generuje troszkę większy błšd
  90.  
  91. %Tutaj mamy zobaczyć, że ode jest mšdre i samo na bieżšco dobiera długoœć
  92. %kroku tak jak mu wygodnie.
  93. diff1=diff(t_45);%diff() liczy nam różnicę po kolei między 1 a 2, 2 a 3, 3 a 4 elementem
  94. diff2=diff(t_15s);
  95.  
  96. figure
  97. semilogy(t_45(1:length(diff1)),diff1)
  98. title('ode45');
  99. xlabel('czas');
  100. ylabel('długoœć kroku');
  101.  
  102. figure
  103. semilogy(t_15s(1:length(diff2)),diff2)
  104. title('ode15s');
  105. xlabel('czas');
  106. ylabel('długoœć kroku');
  107. %===========c)=======================
  108.  
  109.  
  110.  
  111. for N=1:6
  112. options=odeset('RelTol',1/(10^N));
  113. %Funkcjom ode możemy zadawać dodatkowe parametry w taki oto sposób
  114.  
  115. [t_45,u_45]=ode45('odefun',tspan,u0,options);
  116. [t_15s,u_15s]=ode15s('odefun',tspan,u0,options);
  117.  
  118. %Ode mogš zmieniac iloœć kroków czasowych, więc rozwišzania dokładne trzeba
  119. %policzyć na nowo dla danej dziedziny czasu, w celu póŸniejszego wyznaczenia
  120. %błędów.
  121.  
  122. u2d_45=c1*exp(lam1*t_45) + c2*exp(lam2*t_45) + E;
  123. u2d_15s=c1*exp(lam1*t_15s) + c2*exp(lam2*t_15s) + E;
  124.  
  125. max_err_45(N)=max(abs(u_45(:,2)-u2d_45));
  126. max_err_15s(N)=max(abs(u_15s(:,2)-u2d_15s));
  127.  
  128. t_len_45(N)=length(t_45);
  129. t_len_15s(N)=length(t_15s);
  130.  
  131. %Nie wiem jaki zamysł mieli autorzy, ale gołym okiem różnicy nie widzę.
  132. figure
  133. plot(t_45,u_45(:,2))
  134. str=sprintf("Ode45 dla RelTol= %1.0d",1/(10^N));
  135. title(str);
  136. figure
  137. plot(t_15s,u_15s(:,2))
  138. str=sprintf("Ode15s dla RelTol= %1.0d",1/(10^N));
  139. title(str);
  140. end
  141.  
  142. %Max błšd w zależnoœci od tolerancji
  143. figure
  144. semilogx([1e-1,1e-2,1e-3,1e-4,1e-5,1e-6],max_err_45)
  145. title('Max błšd od RelTol dla Ode45')
  146. xlabel('RelTol');
  147. ylabel('Max błšd')
  148.  
  149. figure
  150. semilogx([1e-1,1e-2,1e-3,1e-4,1e-5,1e-6],max_err_15s)
  151. title('Max błšd od RelTol dla Ode15s')
  152. xlabel('RelTol');
  153. ylabel('Max błšd')
  154.  
  155. %Liczba kroków w zależnoœci od tolerancji
  156. figure
  157. semilogx([1e-1,1e-2,1e-3,1e-4,1e-5,1e-6],t_len_45)
  158. title('Iloœć kroków od RelTol dla Ode45')
  159. xlabel('RelTol');
  160. ylabel('Iloœć kroków')
  161.  
  162. figure
  163. semilogx([1e-1,1e-2,1e-3,1e-4,1e-5,1e-6],t_len_15s)
  164. title('Iloœć kroków od RelTol dla Ode15s')
  165. xlabel('RelTol');
  166. ylabel('Iloœć kroków')
  167.  
  168. %=========d)============
  169.  
  170. %Metodami Eulera to bawiliœmy się już w zadaniu 1, ale teraz wyższa szkoła
  171. %jazdy, bo musimy za ich pomocš rozwišzać układ równań. Pamiętamy, że nasz
  172. %układ możemy zapisć w postaci du/dt=A*u+b gdzie A i b wyznaczyliœmy już wyżej:
  173.  
  174. A=[-2/(R1*C1), 1/(R1*C1); 1/(R2*C2), -1/(R2*C2)];
  175. b=[E/(R1*C1);0];
  176.  
  177.  
  178. %Euler otwarty (yn+1=yn+h*fn), gdzie fn=du/dt=A*u+b, a to już ładnie mamy
  179.  
  180. h=1e-6;
  181. t=0:h:30e-3;
  182. u0=[0;1];
  183. u_eul_o=u0;
  184. %Jedyna trudnoœć względem pojedyńczego równania to zapis, bo lecimy po
  185. %kolumnach macierzy, a nie elementach tablicy.
  186. for i=1:length(t)-1
  187. u_eul_o(:,i+1)=u_eul_o(:,i)+h*(A*u_eul_o(:,i)+b);
  188. end
  189. figure
  190. plot(t,u_eul_o(2,:));
  191. title('u2 - Euler Otwarty')
  192.  
  193. %Euler zamknięty (yn+1=yn+h*fn+1)
  194.  
  195. h=1e-6;
  196. t=0:h:30e-3;
  197. u0=[0;1];
  198. u_eul_z=u0;
  199.  
  200. %Tutaj analogicznie jak w eulerze zamkniętym, trzeba wyznaczyć
  201. %yn+1 z równania metody po podstawieniu, że fn+1=A*u(n+1)+b.
  202.  
  203. %Tu poprzednio był niedziałajšcy euler zamknięty, ale został naprawiony
  204.  
  205. %Kolega podrzucił działajšce rozwišzanie równania macierzowego, funkcję
  206. %eye(), która robi nam macierz jednostkowš oraz pomnożenie przez macierz
  207. %odwrotnš zamiast dzielenia. Sam bym na to nie wpadł
  208.  
  209. for i=1:length(t)-1
  210. %Tak było
  211. % u_eul_z(:,i+1)=(u_eul_z(:,i)+h*b)\(1-A*h);
  212. %A to już działa:
  213. u_eul_z(:,i+1)=inv((eye(2)-A.*h))*(u_eul_z(:,i)+h.*b);
  214. end
  215. figure
  216. plot(t,u_eul_z(2,:));
  217. title('u2 - Euler zamknięty')
  218.  
  219. %No to teraz trzebaby oba Eulery powrzucać w pętlę, pozliczać max_err w iteracjach,
  220. %tak jak wczeœniej, tj max_err=max(abs(u_dok-u)) i wykreœlić loglog(max_err,[1e-6,2e-6...10e-6])
  221. %Ale to już każdy raczej zrobi.
  222.  
  223. %=========e)========
  224. %Podmienić te R1,R2,C1,C2,E w tym pliku oraz odefun.m to nie problem ;)
  225.  
  226. %================================Ciekawostka==================================
  227.  
  228. %A jak ze stabilnoœciš eulera otwartego? W tym przypadku h*lambda musi należeć do [0,2],
  229. %wpisujšc komendę 2/eig(A) dostajemy granicznš długoœć kroku dla której
  230. %euler otwarty jest stabilny czyli ~0.98e-5. Wstawiajšc długoœć kroku np 1e-5
  231. %zobaczymy piękny efekt niestabilnoœci metody eulera :)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement