TANA81: Simuleringar med Matlab - Textsträngar och Texthantering. - Utskrifter till fil eller skärm. - Exempel: Slumptal och Simulering. - Exempel: Rörelseekvationerna. - Vanliga matematiska problem. Typeset by FoilTEX 1
Utskrift av resultat Oftast vill man inte bara skriva ut siffror utan även korta förklaringar om vad siffrorna betyder. För att göra detta finns några alternativ - Skapa en textsträng och skriv ut den till skärmen med disp. - Använd fprintf för att skriva till skärm eller fil. Typeset by FoilTEX 2
Textsträngar En sträng, eller en textrad, lagras i Matlab som en radvektor där varje element representerar ett tecken. Exempel Skapa en sträng som innehåller texten Jag vill vinna! genom att skriva >> str = Jag vill vinna! Man kan ändra vill till ska genom >> str(5:8)= ska ; Tecknet kallas sträng parentes. Detta påbörjar och avslutar strängar. Typeset by FoilTEX 3
Precis som för matriser kan vi sätta samman strängar. Exempel Skriver vi >> str1 = Hej ; >> str2 = igen ; % notera extra mellanslag. >> str = [ str1, str2 ]; så fås en sträng Hej igen. Detta är ofta praktiskt då man vill konstruera strängar som består av både text och siffror. Exempel För att konvertera siffror till strängar finns num2str använd denna för att skapa en sträng sin(2) = 0.9093. Typeset by FoilTEX 4
Exempel Vi vill undersöka konvergensen hos kvadratrotsiterationen, x k = 1 2 ( x k 1 + a ), k = 1,2,3,... x k 1 som konvergerar mot a. Skriv därför ett Matlab program som beräknar talföljden x k, för k = 1,2,...,20, och skriver ut k,x k, och x k a i varje steg. Typeset by FoilTEX 5
Programmet blir xk=1;a=3; for k=1:20 xk=(xk+a/xk)/2; str=[ k=,num2str(k), ger x_k=,num2str(xk)]; str=[str, och felet,num2str(abs(xk-sqrt(a)))]; disp(str) end; Kör vi programmet fås en utskrift k=1 ger x_k=2 och felet 0.26795 k=2 ger x_k=1.75 och felet 0.017949 k=3 ger x_k=1.7321 och felet 9.205e-05 k=4 ger x_k=1.7321 och felet 2.4459e-09 k=5 ger x_k=1.7321 och felet 0 Vi behöver ett sätt att styra exakt hur siffror skrivs ut! Typeset by FoilTEX 6
Utskrift av resultat För formatterade utskrifter används funktionen fprintf. Utskrift kommandot har formen >> fprintf( <destination>, format sträng, <variabellista> ) Formatsträngen består av både text och speciella styrtecken. Vill man skriva ut till skärmen gäller att destination är 1. Exempel Skriv ut en textsträng sin(2.3)=0.7436. Typeset by FoilTEX 7
Styrtecken är \n för nyradstecken, \t för tab, och för apostrof. Siffror kan skrivas ut på - %e eller %E för exponentform. - %f för vanlig decimalform. - %u eller %i för heltal. Hjälptexten är hyfsad (help fprintf). Typeset by FoilTEX 8
Exempel Skriver vi >> fprintf(1, Det gäller att exp(%6.3f)=%7.2e.\n,-7.6,exp(-7.6)); fås en utskrift Det gäller att exp(-7.600)=5.00e-04. Utskrift på exponentform är bra då små eller stora tal skall skrivas ut. Typeset by FoilTEX 9
Utskrifter till en textfil Innan vi kan läsa/skriva till en fil så måste den öppnas. Detta görs med kommandot >> fid = fopen( filnamn.tex, r ); där fid är en filidentifierare, och w betyder att vi skall skriva till filen. Altarnativ är r för läsning och a för att skriva till slutet av en existerande fil. Efter att vi skrivit färdigt måste filen stängas. Det görs med >> fclose( fid ); Typeset by FoilTEX 10
Exempel Vi behöver en tabell över funktionen f(x) = sin(x 2 ) för Nst jämnt utspridda värden mellan 0 och 2π. Tabellen skall skrivas till en fil sinus_tabell.txt och ha följande utseende *********************** * x * sin(x) * *********************** * 0.23124 * 0.229185 * *********************** Typeset by FoilTEX 11
Simulering av Tärningskast Fråga Antag att vi slår fem gånger med en tärning. Hur många sexor kan vi förvänta oss att få? Lösning Denna uppgift kan antigen lösas teoretiskt med resultat från sannolikhetslära. Alternativt kan vi simulera tärningskast och undersöka problemet genom datorexperiment. Hur skall ett Matlab program för att lösa uppgiften konstrueras? Typeset by FoilTEX 12
I Matlab finns ett stort antal funktioner för att generera olika typer av slumptal. Skriver vi >> x = rand() så fås ett slumptal x i intervallet [0,1]. Skriver vi istället >> A = rand(5,3) fås en matris A R 5 3, där elementen a ij blir slumptal från intervallet [0,1]. Typeset by FoilTEX 13
För att lösa simuleringsuppgiften behöver vi - En funktion TarningsKast som simulerar ett tärningskast. - En funktion AntalSexor som räknar antalet sexor efter fem kast. - Ett huvudprogram som simulerar ett stort antal kast och presenterar resultatet. Typeset by FoilTEX 14
Funktionen TarningsKast() blir: % Beräkna ett slumpmässigt heltal 1,2,..,6. % function [T]=TarningsKast() T=round( 6*rand(1) + 0.5 ); end Kommentar Nu får vi heltalen 1, 2,..., 6 med samma sannolikhet. Typeset by FoilTEX 15
Funktionen AntalSexor() blir: % Beräkna antalet sexor efter 5 kast. % function [Antalet]=AntalSexor() Antalet=0; for k=1:5 T=TarningsKast(); if T == 6 then Antalet=Antalet+1; end end; end Typeset by FoilTEX 16
Kör N = 10000 experiment med Ger resultatet N=10000; Resultat=zeros(6,1); // Utfall: 0,1,...,5 for k=1:n Antal=AntalSexor(); Resultat(Antal+1)=Resultat(Antal+1)+1; end; disp(100*resultat /N); 40.272 40.036 16.071 3.264 0.346 0.011 Kommentar Chansen att få 5st sexor är 100 (1/6) 5 = 0.013%. Chansen att få 4st sexor är 100 5(1/6) 4 (5/6) = 0.322% Typeset by FoilTEX 17
Begynnelsevärdesproblem Många problem från teknik och naturvetenskap kan formuleras som begynnelsevärdesproblem. Dvs dy = f(t,y(t)), t > 0, dt och y(0) = y 0. Exempel Låt y(t) vara lösningen till problemet: dy dt = ay, och y(0) = 1. Eftersom så får vi att d dt ( e at ) = ae at = ay(t), y(t) = e at. Typeset by FoilTEX 18
I Matlab finns funktionen ode45 för att beräkna lösningen till ett begynnelsevärdesproblem. Definiera högerledsfunktionen f(t,y(t). function [dy]=rhs( t, y ) a=4.2; dy=-a*y; end Välj ett antal t värden för vilka lösningen skall beräknas, använd ode och plotta. N=100;t=2*(0:N)/N; y0=1; [t,y]=ode45( rhs,t,y0 ); plot(t,y) % intervall 0<t<2 Typeset by FoilTEX 19
1 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0 0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2 Den numeriska lösningen y(t) (blå linje), för 0 < t < 2. Kommentar De flesta begynnelse problem kan inte lösas analytiskt! Numerisk lösning, med exempelvis Matlab, är enda möjligheten. Typeset by FoilTEX 20
Exempel: Var stannar vagnen? En järnvägsvagn med massa 1376kg rör sig med v = 2.1m/s mot en bromskloss bestående av en ideal fjäder med fjäderkonstant 1.91kN/m. v 0 =2.1m/s P 0 =0m P F =5m Frågor: Hur långt trycks fjädern in? Hur lång tid tar det innan vagnen vänt och passerat P 0 = 0 igen? Är lösningen realistisk? Typeset by FoilTEX 21
Matematisk Modell Målet med simuleringen är att beräkna vagnens position p(t) för t > 0. Vi behöver även beräkna vagnens hastighet v(t). Rörelseekvationerna är och dv dt dp dt = v(t), = a(t) = F(t)/m, där F(t) är den kraft som verkar på vagnen vid tiden t och m är vagnens massa. Vilka krafter verkar på vagnen? Typeset by FoilTEX 22
Antag att bromsklossen kan beskrivas som en ideal fjäder med fjäderkonstant K. Då gäller { K(p(t) PF ), p > P F(t) = F, 0, p P F. Vi får ett begynnelsevärdes problem: d dt ( p(t) v(t) ) = ( v(t) F(t)/m ), ( p(0) v(0) ) = ( 0 2.1 ). Analytisk lösning finns förmodligen? Problemet kan lösas numeriskt med exempelvis stegmetoden. Typeset by FoilTEX 23
Matematisk modell Inför en tillståndsvariabel, S(t) = och skriv problemet som ett system, d dt S(t) = ( p (t) v (t) ),= ( p(t) v(t) ), ( v(t) F(t)/m ),= f(t,s(t)), där kraften F(t) beror på positionen p(t). Detta är ett begynnelsevärdesproblem som kan lösas med ode45. Vi behöver en funktion Vagn som beräknar S (t) givet t och S(t). Typeset by FoilTEX 24
För att beräkna derivatan av tillstånds variabeln använder vi: function [ds]=vagn(t,s) m=1376;k=1910;pf=5.0; % fysikaliska parametrar p=s(1);v=s(2); if p>pf F=-K*(p-Pf); else F=0; end; ds=[ v ; F/m]; end % Tillståndet är S(t)=( p(t) v(t) )^T. Kommentar: Detta är en funktion ds = f(t, S(t)). Typeset by FoilTEX 25
Vi kan nu lösa begynnelsevärdes problemet med ode45 % Tillståndet är S(t)=(p(t) v(t))^t. Vi sätter % startvärden och väljer tidsinterval. t=0:0.1:8; S0=[ 0 ; 2.1 ]; % Lös problemet och plotta [t,s]=ode45( Vagn,t,S0); v=s(:,1);p=s(:,2); plot(t,v, b-,t,p, r-- ); xlabel( Tid t [s] );ylabel( p(t) (blå) v(t) (röd) ); Typeset by FoilTEX 26
7 6 5 4 3 2 1 0 1 2 3 0 1 2 3 4 5 6 7 8 Den numeriska lösningen för 0 < t < 8. Vi ser att vagnen vänder ungefär vid p(t = 3.7) = 6.782 m. Då är hastigheten v(3.7) = 0.0351. Eftersom inga förluster finns i systemet så måste vagnen röra sig med 2.1m/s för stora tider t. Vi får v(t = 8.0) = 2.0999971m/s. Typeset by FoilTEX 27
Är lösningen realistisk? Vad måste vi tänka på? - Antagandet om ideal fjäder är bra om fjädern trycks ihop högst 10 15%. Här trycks fjädern ihop 1.8m. - Inga förluster finns. Hur skall vi lägga in friktion i modellen? Hur kan vi använda den numeriska modellen? - Antag att fjäderkonstanten K är okänd och svår att mäta direkt. Vi kan då först göra ett experiment och sedan välja K i modellen så att simuleringen överensstämmer med experimentet. Detta kallas en indirekt mätning! Typeset by FoilTEX 28
Matlabfunktioner I Matlab finns ett flertal funktioner för att beräkna integraler, lösa ekvationer, hitta minumum till en funktion, etc. Gemensamt för dessa är att man skriver en Matlab funktion och sedan anger den som inparameter. - Lös f(x) = 0 med x=fzero( f, x0 ); - Beräkna b f(x) = 0 med I=quad( f, a, b ); a - Minimera f(x) på intervallet [a,b] med c=fminbnd( f, a, b ); Kommentar Hjälptext finns. Titta på help fzero. Oftast kräver det lite vana att läsa och förstå hjälptexten. Typeset by FoilTEX 29