c l c
Transkrypt
c l c
MOiPP Wykład 3 Matlab • Przykłady prostych metod obliczeniowych 1 Zliczanie warunkowe w tablicy 1-wymiarowej Ile w tablicy jest elementów dodatnich? M=-3:0.1:2 ile=0; %koniecznie inicjujemy zmienną! N=length(M) % funkcja length zwraca liczbę kolumn wektora for i=1:N % pętla if M(i)>0 % test warunku ile=ile+1; end end; disp(ile) 2 Zliczanie elementów dodatnich w tablicy dwuwymiarowej clear; clc a=rand(5,5)-0.5 %elementy dodatnie i ujemne iledod= 0; %inicjujemy zmienną for i= 1:1:5, for j = 1:1:5, if a(i , j)>0 iledod=iledod+1; end end end disp(iledod) 3 Sumowanie warunkowe (elementów dodatnich) w tablicy 1-wymiarowej M=-3:0.1:2 suma_d=0; N=length(M) for i=1:N if M(i)>0 suma_d=suma_d+M(i); end end; disp(suma_d) 4 Sumowanie warunkowe elementów tablicy 2-wymiarowej clear; clc a=rand(5,5)-0.5 suma_d= 0; suma_u=0; for i= 1:1:5, for j = 1:1:5, if a(i , j)>0 suma_d=suma_d+a(i,j); else suma_u=suma_u+a(i,j); end end end fprintf('suma dodatnich:%f\n',suma_d) disp('suma ujemnych:%f\n',suma_u) 5 Sumowanie warunkowe elementów tablicy 2-wymiarowej clear; clc a=rand(5,5)-0.5 suma_p= 0; for i= 1:1:5, for j = 1:1:5, if a(i , j)>=-0.2 && a(i , j)<=0.2 suma_p=suma_p+a(i,j); end end end fprintf('suma [-0.2, 0.2]:%f\n',suma_d) Można używać pojedynczy znak koniunkcji & 6 Sumowanie elementów przekątnej i przeciwprzekątnej clear; clc a=rand(5,5)-0.5 suma_p= 0; suma_pp= 0; for i= 1:1:5, suma_p=suma_p+a(i,i); suma_pp=suma_pp+a(i,6-i); end fprintf('suma elementów przekątnej:%f\n',suma_p) fprintf('suma elementów przeciwprzekątnej:%f\n',suma_pp) Rozwiązanie lepsze niż podwójna iteracja z warunkiem w==k Można używać także pojedynczy znak koniunkcji & 7 Obliczenia kinematyczne Ruch jednostajnie przyspieszony(opóźniony) v=v0+a*(t-t0) 8 Ruch jednostajnie przyspieszony Wykres v(t) – prędkość jest funkcją liniową, więc wystarczą dwa punkty dla wykresu t0=0, v0=0, tk=5,vk=20 %tworzymy dwa wektory t=[t0 tk] v=[v0 vk] plot(t, v, 'k') xlabel('t'), ylabel('v') 20 18 16 14 v 12 10 8 6 4 2 0 0 1 2 3 t 4 5 9 Ruch jednostajnie przyspieszony s(t) to parabola, więc potrzebujemy więcej punktów s(t)-czerwony v(t) - czarny 50 t0=0, v0=0, tk=5,vk=20 a=(vk-v0)/(tk-t0) % "gęsta" oś czasu t=t0 : 0.1 : tk s=v0*t+a*t.^2/2 plot(t, s,'r') hold on %zatrzymanie wykresu v=v0+a*(t-t0) plot(t, v, 'k') title('s(t)-czerwony v(t) - czarny') 45 40 35 30 25 20 15 10 5 0 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 10 5 Ruch jednostajnie opóźniony 40 s (t ) 30 20 10 0 0 0.5 1 1.5 2 t 2.5 3 3.5 4 0 0.5 1 1.5 2 t 2.5 3 3.5 4 20 15 v (t ) t0=0, v0=20, tk=4, vk=0 a=(vk-v0)/(tk-t0) t=t0 : 0.1 : tk; s=v0*t+a*t.^2/2; subplot(2,1,1),plot(t, s) xlabel('t'),ylabel('s(t)') v=v0+a*(t-t0); subplot(2,1,2),plot(t, v) xlabel('t'),ylabel('v(t)') 10 5 0 11 Wykorzystanie macierzy w ruchu złożonym – odcinki czasowe - jednostajnie przyspieszony, - jednostajny, - jednostajnie opóźniony, v(t) 25 t0=0, t1=t0+5, t2=t1+2*60, t3=t2+4 20 a1=4, a2=0, a3=-5 v0=0 15 v1=a1*(t1-t0)+v0 v2=a2*(t2-t1)+v1 10 v3=a3*(t3-t2)+v2 t=[t0 t1 t2 t3] %kolejne punkty czasowe5 v=[v0 v1 v2 v3] %odpowiednie prędkości 0 0 plot(t, v) title('v(t)') axis([0 140 0 25]) 20 40 60 80 100 120 12 140 … na marginesie … czasem wygodniejsza skala logarytmiczna [x,y] = fplot('1/sqrt(1+2e-7*x^2)',[1,1e6]); figure(1) plot(x,y) grid on figure(2) semilogx(x,y) %skala logarytmiczna dla osi x grid on semilogx plot Wykres w skali półlogarytmicznej osi x 1 1 0.9 0.9 0.8 0.8 0.7 0.7 0.6 0.6 0.5 0.5 0.4 0.4 0.3 0.3 0.2 0.2 0.1 0.1 0 0 1 2 3 4 5 6 7 8 9 10 0 0 10 1 10 2 10 3 10 4 10 5 10 5 x 10 13 6 10 Trochę inaczej tworzymy wykres przyspieszenia t0=0, t1=t0+5, t2=t1+2*60, t3=t2+4 a1=4, a2=0, a3=-5 t=[t0, t0, t1, t1, t2, t2, t3, t3] a=[0, a1, a1, a2, a2, a3, a3, 0] figure(2) plot(t,a), grid 4 3 2 1 0 -1 -2 -3 -4 -5 0 20 40 60 80 100 120 140 14 A jak narysować wykres s(t) ? Zadanie: Trzy przedziały czasowe: 1) t(0,10) v0=0 v1=60 2) t(10 20) v1=60 v2=60 3) t(20 30) v2=60 v3=0 15 clc,clear %dane t0=0;t1=10;t2=20; t3=30; v0=0; v1=60; v2=60; v3=0; %1-szy przedział T01=t0:0.1:t1; a01=(v1-v0)/(t1-t0); S01=a01*T01.^2/2; %2-gi przedział – tylko 2 punkty! a12=0; T12=[t1 t2]; S12=S01(length(S01))+v1*(T12-t1)+a12 *(T12-t1).^2/2; %3-ci przedział S(length(S)) – to ostatni element wektora a23=(v3-v2)/(t3-t2); T23=t2:0.1:t3; S23=S12(length(S12))+v2*(T23-t2)+a23*(T23-t2).^2/2 %scalamy wektory z przedziałów uwaga: dużymi literami nazwano T=[T01 T12 T23 ]; zmienne wektorowe, a małymi dane S=[S01 S12 S23]; plot(T,S) elementarne (skalarne) sk=S(length(S)) %końcowa droga hold on, plot([t1 t1],[S01(length(S01))-50 S01(length(S01))+50]) hold on, plot([t2 t2],[S12(length(S12))-50 S12(length(S12))+50]) ah=(v3-v2)/(t3-t2) sh=-v2^2/2/ah 16 1200 1000 800 600 400 200 0 0 5 10 15 20 25 30 .. a teraz bardziej "elegancki" kod…do samodzielnej analizy clc,clear %dane t=[0 10 20 30]; v=[0 60 60 0]; s0=0; N=100; %liczba podprzedziałów, na jakie dzielimy każdy przedział jazdy %====="pętla" dla 3-ch przedziałów for k=1:3 fprintf('Przedzial:%d\n',k) T(k,:)=t(k):(t(k+1)-t(k))/N:t(k+1); %podwektor czasu w wierszu k-tym a(k)=(v(k+1)-v(k))/(t(k+1)-t(k)); % przyspieszenie w k-tym przedziale % teraz podwektor drogi w k-tym wierszu S(k,:)=s0(k)+v(k)*(T(k,:)-t(k))+a(k)*(T(k,:)-t(k)).^2/2; %przechowanie ostatniej wartości drogi dla następnego przedziału s0(k+1)=S(k,N+1); fprintf('Przebyto w tym etapie drogę:%0.1f\n', s0(k+1)) end %koniec pętli %przygotowanie danych do wykresu T=reshape(T',1,3*(N+1)); % rekonfiguracja 3-wierszowej macierzy T w 1-wierszową S=reshape(S',1,3*(N+1)); % to samo dla macierzy S plot(T,S) %rysujemy wykres %całkowita przebyta droga- ostatni element tablicy S fprintf('Przebyto całkowitą drogę:%0.1f\n metrów', S(length(S))) 17 Zróżnicowanie metod obliczeniowych Zadanie: Obliczyć wartości drogi wykonanej przez ciało od prędkości początkowej V0=0, poruszającym się z przyspieszeniem a=4m/s2, w przedziale czasu t=[0, 5] s. Utworzyć wykres s(t). 18 Sposób 1: dwie tablice t=0 : 0.1 : 5 a=4 s=a*t.^2/2 plot(t,s) 19 Sposób 2: podział przedziału czasu i wykorzystanie iteracji a=0; b=5; n=50; h=(b-a)/n; for i=1:n+1 t(i)=a+(i-1)*h; s(i)=2*t(i)^2; end plot(t,s) 20 Sposób 3 Obliczenia przy pomocy tzw. funkcji anonimowej Składnia funkcji anonimowej: nazwa_funkcji=@( nazwa_funkcji=@(lista_argumentów =@(lista_argumentów)(wyrażenie) lista_argumentów)(wyrażenie) 21 Przykład 1 0.8 0.6 sinusoida=@(t)(sin(t)) fplot(sinusoida,[0,4*pi]) 0.4 0.2 0 -0.2 -0.4 -0.6 -0.8 Nasze zadanie a=4; t=0:0.1:5 f = @(t)(a*t.^2/2); s=f(t) plot(t, s) -1 0 2 4 6 8 10 12 50 45 40 35 30 25 20 15 10 5 0 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 22 Można tworzyć funkcję anonimową o wielu argumentach f=@(x,y)(sin(x)^2+cos(y)^2) wynik=f(pi/2, 0) f= @(x,y)(sin(x)^2+cos(y)^2) wynik = 2 23 Sposób 4 Tworzymy osobny m-plik funkcyjny o nazwie fs.m: function y = fs(t) y=2*t^2; Teraz możemy wykorzystać naszą funkcję z pliku: t=[0:0.5:5]; n=length(t); for i=1:n s (i)=fs(t(i)); end plot(t,s), grid 24 Aby wykorzystać naszą funkcję w poniższy sposób: t=[0:0.5:5]; s=fs(t); plot(t,s), grid argumentem funkcji jest tutaj wektor funkcja w m-pliku o nazwie fs.m musiałaby być zdefiniowana następująco: function y = fs(t) y=2*t.^2; bo elementowe podnoszenie do kwadratu 25 Zapis wielomianu w matematyce: w(x)=a0xn + a1xn-1 + a2xn-2 + ···+ aixn-i + ···+ an-2x2 + an-1x + an Matlab – zmiana indeksowania współczynników ponieważ w Matlabie indeksy macierzy zaczynają się od 1 26 Poznany przykład ilustrujący indeksowanie tablicy 5x4 + 4x2 – x + 2 = 0 Wektor współczynników: A= [5 0 1 -1 2] X=roots(A) %sprawdzenie S= A(1)*X(1)^4+ A(3)*X(1)^2+ A(4)*X(1) +A(5) %albo S=0; for k=1:5 S=S+A(k)*X(1)^(5-k); end disp(S) 27