Department of Physics Umeå University 18 november 2014 MATLAB Guide Marina Wallin Martin Hansson Per Sundholm
INNEHÅLL 1 Innehåll 1 Introduktion till MATLAB 3 1.1 Vad är MATLAB och varför använder vi det?........... 3 1.2 En första bekantskap med MATLAB................ 4 1.3 Hjälp.................................. 7 1.4 Enkla MATLAB operationer.................... 9 1.4.1 Matematiska funktioner................... 9 1.4.2 Vektorer............................ 10 1.4.3 Logiska uttryck........................ 11 1.5 Enkla script i MATLAB....................... 12 1.5.1 If, For, While......................... 13 1.6 Bilder i MATLAB.......................... 14 1.7 Regressionsanalys........................... 19 1.7.1 Linjäranpassning....................... 19 1.7.2 Konfidensintervall...................... 20 1.7.3 Polynomanpassning..................... 21 1.7.4 Linjärisering av potensfunktion............... 22 1.7.5 Värdering av resultat.................... 22 2 Programmering med MATLAB 24 2.1 Introduktion till vektorer och matriser............... 24 2.1.1 Vektorer i MATLAB..................... 24 2.1.2 Matriser i MATLAB..................... 27 2.1.3 Vektor- och matrisoperationer................ 29 2.2 Mer om loopar............................ 32 2.3 Script i MATLAB.......................... 34 2.4 Läsa in data i MATLAB....................... 35 3 Matematisk analys med MATLAB 38 3.1 Funktioner och derivator....................... 38 3.2 Eulers metod............................. 40 3.3 MATLAB:s ode-lösare........................ 42 3.4 Numerisk integrallösning....................... 43 3.4.1 Riemannsumman....................... 43 3.4.2 Trapetsregeln......................... 44 3.4.3 Simpsons regel........................ 46 3.4.4 MATLAB:s numeriska integralräknare........... 47 3.5 Symbolhantering i MATLAB.................... 48 4 Linjära system i MATLAB 49 4.1 Vektorer och matriser........................ 49 4.2 Matrisoperationer........................... 49 4.2.1 Matrisaddition och subtraktion............... 50 4.2.2 Matrismultiplikation..................... 50 4.2.3 Transponering av matriser i MATLAB........... 51 4.2.4 Matrisinvers i MATLAB................... 52 4.3 Linjär algebra i MATLAB...................... 52 4.3.1 Determinanter i MATLAB................. 52 4.3.2 Lösning av linjära system i MATLAB........... 53
INNEHÅLL 2 4.3.3 Egenvärden och egensystem i MATLAB.......... 56 5 Statistik i MATLAB 59 5.1 Slumpvariabler och fördelningar i MATLAB............ 59 5.1.1 Slumptalsgenerering..................... 59 5.1.2 Slumpfördelningar...................... 60 5.2 Sammanfattande statistik...................... 61 5.2.1 Skattningar av väntevärde och spridningsmått...... 61 5.2.2 Statistiska plottar...................... 63 5.3 Statistiska test och konfidensintervall................ 67 5.3.1 Normalitetstest........................ 67 5.3.2 Test med normalfördelningsantagande........... 68 5.3.3 Exempel............................ 68 5.3.4 ANOVA............................ 71 5.3.5 Oparametriska test...................... 72 5.3.6 Konfidensintervall...................... 72 5.4 Programspråket R.......................... 73 6 Klassisk mekanik med MATLAB 74 6.1 Newtons rörelseekvationer med numeriska metoder........ 74 6.1.1 Rörelse i en dimension.................... 74 6.1.2 Rörelse i flera dimensioner.................. 77 6.2 Verlet-integration........................... 78 6.2.1 Velocity-Verlet........................ 79 A Appendix: Rapportskrivning med Matlab 81 A.1 Bilder i MATLAB.......................... 81 A.1.1 Plot-kommandot....................... 81 A.1.2 Sub-plottar.......................... 82 A.1.3 Symboler........................... 83 A.2 MATLAB med andra program................... 84 A.2.1 MATLAB2tikZ........................ 84 A.2.2 MATLAB med COMSOL.................. 85 A.3 Feluppskattningar.......................... 86 B Appendix: Vanliga fel 87 B.1 Dimensionsfel............................. 87 B.2 Indexeringsfel............................. 88 B.3 Syntaxfel............................... 89 B.4 Övriga fel............................... 90 B.5 Felsökning i MATLAB........................ 91 B.5.1 Felsökning i MATLAB.................... 91 C Appendix: Tips och Trix 93 C.1 Småtips att alltid följa........................ 93 C.2 Publish................................ 95 C.3 Multi-dimensionella matriser.................... 96 C.4 Cell-arrayer.............................. 97 C.5 Struct................................. 98
1 INTRODUKTION TILL MATLAB 3 1 Introduktion till MATLAB Något man som Teknisk fysiker kommer att använda genom hela sin utbildning och förmodligen även i det riktiga livet är MATLAB, se figur 1. MATLAB är ett programspråk från företaget MathWorks som används av många civilingenjörer. Den här handboken är skriven av studenter på Teknisk fysik för att hjälpa er och göra den första bekantskapen med MATLAB enklare. För är det något man kan vara säker på så är det att man inte kan fuska sig igenom MATLABmomenten i kurserna. Det kommer att återkomma i stort sett i varenda kurs och en bra relation till MATLAB kommer därmed hjälpa avsevärt. MATLAB kommer ibland vara ens värsta fiende och man kommer känna att man inte har tid att lära sig det, då man måste räkna uppgifter och göra teoretiska labbar hela tiden. Ett tips är att ta er tiden till att lära er MATLAB ordentligt så ni vet när och hur man bör använda det. Ni kommer tjäna på det i längden. Figur 1: MATLABs logga. Det här är som sagt en handbok som är till för att hjälpa er. Vi påstår inte på något sätt att den är världsbäst, men vi tror ändå att den är bättre än att inte ha någonting alls. Ett tips är att samtidigt som ni läser detta dokument, se till att testa att göra samma exempel som vi gör för bättre förståelse. Kom ihåg att det alltid finns äldrekursare i datasalen som kan hjälpa er då ni kör fast. Lycka till! 1.1 Vad är MATLAB och varför använder vi det? Namnet MATLAB kommer från matrix laboratory och syftar till programmets förmåga att hantera matriser. MATLAB är ett högnivåspråk som lämpar sig för matematiska och tekniska beräkningar, vilket vi som civilingenjörer sysslar en hel del med. I MATLAB kan man skriva algoritmer, beräkna matematiska uttryck, analysera data, visualisera resultat och mycket, mycket mer. I detta kapitel kommer vi börja med att förklara hur man kan använda MATLAB på ett enkelt sätt för att sedan öka svårighetsgraden i senare kapitel.
1 INTRODUKTION TILL MATLAB 4 Om ni någonsin tvivlar på MATLABs styrka kan ni alltid testa att skriva why i kommandofönstret. MATLAB kommer då ge er svar på tal. 1.2 En första bekantskap med MATLAB När man öppnar MATLAB kommer det se ut ungefär som i figur 2. Notera att man själv kan flytta och arrangera om som man själv vill. Det betyder att bilden inte alltid stämmer exakt men oftast ser det ut som i figur 2. Längst upp i fönstret finns flikar och ikoner som underlättar arbetet. Det stora fönstret i mitten kallas för kommandofönstret, Command window, och det är där man skriver in vad man vill göra. Figur 2: Det här är ett exempel på hur MATLAB ser ut då man startar det. Symbolen >> kallas för MATLAB-prompten och indikerar att man kan skriva. Om vi till exempel skriver >> 12 + 3*(4 5) + 10/5 och trycker enter kommer MATLAB att svara >> 11 vilket är precis det vi vill. MATLAB har räknat ut vårt tal och sparat det i en variabel som heter ans. Ibland kan det vara skönt att MATLAB skriver ut vad den gör så man vet att allting blir rätt, men med för många utskrifter blir det snabbt oöverskådligt. Då använder man sig av ett semikolon efter uttrycket, >> 35*12 100; vilket gör att ans får värdet 320 men det skrivs inte ut i kommandofönstret. Om man skriver in
1 INTRODUKTION TILL MATLAB 5 >> a = 4; >> b = 3; >> a+b i kommandofönstret kommer MATLAB se ut som i figur 3. Figur 3: Så här kan MATLAB se ut då man utfört en del kommandon. Som man ser har bilden förändrats genom att det tillkommit nya saker. Längst ner till höger har vi en ruta som kallas kommandohistorik, Command History, där man ser vilka kommandon som senast gjorts. Längst upp till höger finns en ruta som heter arbetsyta,workspace, där alla aktuella variabler sparas tillsammans med deras värde. Där a för tillfället är 4, b är 3 och ans är 7. ans är en temporär variabel, vilket betyder att variabeln bara kommer sparas tills en ny uträkning görs och den gamla uträkningen inte längre är aktuell. Om man skriver in >> a b kommer ans byta värde till 1. Om man vill spara olika variabler en längre tid måste man själv ge dem egna namn. Detta görs genom att skriva tex >> sum = a+b >> diff = a b vilket sparar 7 i variabeln sum och 1 i variabeln diff. Beskrivande variabelnamn gör koden enklare att förstå för utomstående. Om man vill spara många värden i samma variabel kan man göra det genom att skapa en lista av tal: >> numbers = [1 2 3 4 5] Detta kallas även för en vektor och kommer förklaras ytterligare i avsnitt 2.1.
1 INTRODUKTION TILL MATLAB 6 Nu har vi endast skrivit kortare rader men när man gör många uträkningar på samma gång kan det vara bra att spara det på något sätt. I MATLAB görs detta genom att skapa en M-fil. Det kan man antingen göra genom att klicka New Script i huvudpanelen eller skriva edit i kommandofönstret. Då öppnas en editor där man kan skriva sin kod. För att köra klickar man på den gröna triangeln eller genom att skriva in m-filens namn i kommandofönstret. Till exempel kan vi skriva >> edit hej då skapas en M-fil med namnet hej.m och en editor öppnas. Editorn är som ett tomt textblad där man kan man skriva exakt samma sak som vi skrivit tidigare men M-filen kommer sparas så att man kan fortsätta en annan dag. Det man skrivit i kommandofönstret kommer raderas när man stänger ner MATLAB. I figur 4 ser man hur MATLAB ser ut efter att vi skapat en M-fil. M-filen hej.m ligger i en ruta till vänster där alla filer i samma mapp sparas. Sökvägen till den mappen kan man se under huvudpanelen. Mer om M-filer och dess fördelar kan man läsa i kapitel 1.5 som handlar om enkla script i MATLAB. Figur 4: Så här kan MATLAB se ut då man skapat en m-fil och utfört en del kommandon. Resultaten man får från koden i sin M-fil kommer hamna i editorn. T.ex. om man skriver one = 1 i M-filen, kommer MATLAB svara >> one = 1 i editorn.
1 INTRODUKTION TILL MATLAB 7 1.3 Hjälp Det kommer alltid finnas tillfällen då man inte är helt säker på hur man ska skriva för att MATLAB ska göra som man vill. Det man då kan göra är att använda sig av olika hjälpfunktioner som är inbyggda i MATLAB eller använda internet. Det första och kanske enklaste kommandot man ska prova är kommandot help. Man skriver helt enkelt >> help sqrt och får då fram en kortare text om hur man använder kommandot sqrt, se figur 5. Figur 5: En hjälpande text om sqrt som MATLAB returnerar efter kommandot help sqrt. Om man behöver mer dokumentation om kommandot eller inte är helt säker på vad kommandot heter kan man använda sig av >> doc plot som öppnar ett nytt fönster med dokumentation om kommandot plot, se figur 6. Fördelen med detta sätt är att man längst upp på sidan kan söka efter kommandon och få olika förslag om man inte är helt säker på vad man söker efter.
1 INTRODUKTION TILL MATLAB 8 Figur 6: Ett nytt fönster i MATLAB med dokumentation om kommandot plot. Ett tredje alternativ som man kan testa är >> demo matlab då får man upp ett bibliotek med kortare exempel och guider med exempelkod till MATLAB, se figur 7.
1 INTRODUKTION TILL MATLAB 9 Figur 7: Inbyggda exempel och guider till MATLAB. Om man inte riktigt vet vad man ska söka på är det såklart alltid enklast att leta på internet, där Google har många svar. En otroligt bra sida är mathworks.se, där man kan hitta väldigt mycket bra exempel och förklaringar som MathWorks, MATLABs skapare, själva skrivit. 1.4 Enkla MATLAB operationer Nu när vi har lärt känna MATLAB lite är det dags att gå vidare. Vi kommer i detta avsnitt gå igenom en del enkla MATLAB operationer som kan vara bra att ha koll på för att kunna skriva mindre program i MATLAB. 1.4.1 Matematiska funktioner I MATLAB går det att anropa alla de matematiska funktioner som man brukar hitta i en avancerad miniräknare. Nedan, i tabell 1, följer ett par kommandon som är lämpliga att kunna samt deras översättning till matematisk notation. Tabell 1: Matematiska funktioner och hur man skriver dem i MATLAB. MATLAB Matematisk motsvarighet exp(x) e x sin(x),cos(x), tan(x) sin(x), cos(x), tan(x) asin(x),acos(x), atan(x) arcsin(x), arccos(x), arctan(x) log(x), log10(x) sqrt(x) ln(x), log 10 (x) x abs(x) x Det går alltså att beräkna exempelvis 4 med MATLAB genom att skriva
1 INTRODUKTION TILL MATLAB 10 >> sqrt(4) 2 1.4.2 Vektorer Begreppet vektorer kommer förklaras tydligare i senare kurser, just nu kan ni tänka på en vektor som en lista med tal. För att skapa en vektor i MATLAB kan man använda sig av klammeroperatorn [ ]. Med den kan man spara flera värden till samma variabel. numbers=[ 4 8 15 16 23 42 ] Ett annat väldigt användbart verktyg är kolonoperatorn. Skriver man x=0:2:10 i MATLAB kommer en lista skapas som börjar på 0, har ett avstånd på 2 mellan talen och slutar med 10. >> x=0:2:10 x = 0 2 4 6 8 10 När man skapar vektorer är det ibland ovärderligt att snabbt kunna ta reda på längden av den. Längden av en vektor är hur många tal som är sparad i vektorn. Det kan man göra genom att skriva: >> length(x) 6 Vanliga tal är i grund och botten vektorer med längden 1. Att hantera vektorerna som skapats är enkelt. För att plocka fram till exempel det tredje elementet ur en vektor skriver man >> x(3) 4 och för att ändra specifika element ur en vektor skriver man >> numbers(3)=100 numbers = 4 8 100 16 23 42 Det går att addera och subtrahera vektorer med andra vektorer med samma längd, men det går inte att multiplicera, upphöja eller dividera. För att göra det måste man sätta en punkt framför räknesymbolen. Genom att skriva en punkt framför operatorn berättar man för MATLAB att man vill utföra operationen elementvis. Om man inte skriver det kommer MATLAB utföra matrisoperationer, vilket förklaras mer ingående i avsnitt 2.1.3. Nedan följer två exempel: >> numbers x 4 6 96 10 15 32 >> x.*2 0 4 8 12 16 20 Som man ser har det första talet i x subtraherats från det första talet i numbers, det andra från det andra, osv. Det går också att använda de matematiska funktioner som vi nämnt tidigare på vektorer:
1 INTRODUKTION TILL MATLAB 11 >> x=0:2:10 x = 0 2 4 6 8 10 >> sqrt(x) 0 1.4142 2.0000 2.4495 2.8284 3.1623 Här har vi alltså tagit roten ur vektorn x. Svaret har blivit avrundat vid den fjärde decimalen. Om vi skulle vilja se fler decimaler kan vi skriva >> format long >> sqrt(x) 0 1.414213562373095 2.000000000000000 2.449489742783178 2.828427124746190 3.162277660168380 För att byta tillbaka skriver man format short. Det finns flera olika format att välja mellan. 1.4.3 Logiska uttryck I MATLAB går det att undersöka diverse logiska samband som likheter och olikheter. I tabell 2 finns exempel på logiska operatorer som MATLAB kan hantera. Tabell 2: Logiska uttryck. MATLAB Förklaring >, < Större än, mindre än >=, <= Större/mindre än eller lika med == Lika med = Inte lika med & Logiskt och Logiskt eller Att använda logiska operatorer fungerar som att använda vilket annat räknesätt som helst. Skillnaden är att resultatet antingen blir 0 eller 1, där 0 står för falskt och 1 står för sant. För att exemplifiera följer några olikheter nedan: >> 1<2 1 >> 1>2 0 >> 5<10 & 5>8 0 >> 5<10 5>8 1 Det tredje exemplet returnerar falskt eftersom 5 inte är både mindre än 10 och större än 8. I det fjärde exemplet returneras sant eftersom 5 är mindre än 10. Ett logiskt och innebär att båda villkoren måste vara uppfyllda medans logiskt eller innebär att endast de ena villkoret måste vara uppfyllt. Det går även att använda logiska uttryck på vektorer >> x=0:2:10 x = 0 2 4 6 8 10 >> x<=4 1 1 1 0 0 0
1 INTRODUKTION TILL MATLAB 12 Om man använder logiska uttryck på vektorer returneras flera olika svar eftersom talen jämförs var för sig. De tre första talen i vektorn x är större eller lika med 4 och därför returneras en etta på dessa positioner. 1.5 Enkla script i MATLAB Vi har i kapitel 1.2 sett hur man skapar och öppnar en M-fil. Låt oss nu skrida till verket och skriva vårt första script. Ett script är ett dokument som kör koden rad för rad, precis på samma sätt som om vi hade skrivit rad för rad i kommandofönstret. Men nu skriver vi klart hela koden och kör allt när vi är färdiga. På detta sätt kan vi spara allt vi skriver i ett dokument. Säg att vi vill beräkna arean av ett rätblock, d.v.s. en tegelstensformad geometrisk kropp med sidolängderna 1, 2 och 3 cm. Då kommer vi ha två sidor med arean 1 2, två med arean 1 3 och två med arean 2 3, och totalarean kommer bli summan av dessa, alltså 22 cm 2. Denna beräkning går alldeles utmärkt att utföra i MATLAB genom att skriva a=1; b=2; c=3; area=2*(a*b + a*c + b*c) och spara uträkningen som ett script med namnet rarea1.m. Testkör filen genom att sedan skriva rarea1 i MATLABs kommandoprompt. >> rarea1 area = 22 Ett annat sätt att åstadkomma samma sak är att göra rätblocksarean till en funktion av sidolängderna a, b och c. I MATLAB kan man skriva funktioner med hjälp av M-filer. Variabler som skapas inuti sådana funktioner är lokala och tas automatiskt bort när funktionen avslutas. För att definiera en funktion skapar vi en ny M-fil med samma namn som funktionen vi tänker skriva. Det är viktigt att ha samma namn på funktionen och M-filen annars kommer MATLAB inte att hitta funktionen. Funktioner börjar med kommandot function som utgör ett funktionshuvud som beskriver vilka parametrar funktionen tar och vilka returvärden den ger tillbaka. Funktionen avslutas med kommandot end. Nedan följer samma exempel som tidigare men den här gången är rätblocksarean en funktion, med sidolängderna som inparametrar: function area=rarea2(a,b,c) area=2*(a*b + a*c + b*c); end Testkör funktionen genom att skriva: >>area = rarea2(1,2,3) area = 22 Det är viktigt att man skickar in parametrarna i rätt ordning, i detta fall har vi a = 1, b = 2 och c = 3. Prova också att köra rarea2(1,1,1) som räknar ut arean av en kub med sidolängden 1 cm. Fördelen med funktioner är alltså
1 INTRODUKTION TILL MATLAB 13 att man kan skicka in olika parametrar till funktionen. I det här fallet är det sidolängderna. Förklaringar till filen rarea2 Rad 1. Första raden i M-filen ovan deklarerar att en funktion ska skapas med namnet rarea2. Funktionen anropas med tre argument och kommer att returnera värdet på area. I M-filen har dessa namnet a, b och c men när funktionen anropas från MATLAB kan dessa vara vad som helst. Rad 2. Beräkningen av rätblocksarean utförs och resultatet tilldelas namnet area. Det är samma area som förekom i funktionsdeklarationen på rad ett. Detta är det sista som görs i M-filen och det är det värde som area har just nu som kommer att returneras av funktionen. Notera att area bara är ett namn och kan bytas ut mot vilket annat godtagbart namn som helst bara det förekommer både i funktionsdeklarationen på rad ett och på sista raden. Rad 3. Kommandot end avslutar funktionen. 1.5.1 If, For, While Ibland kan det vara väldigt användbart att kunna upprepa eller sätta något slags villkor på när en slinga kod ska utföras. Därför finns kontrollstrukturerna if, for och while implementerade i MATLAB. Med dessa kan man på ett snabbt och enkelt sätt göra program som inte varit möjligt med en miniräknare. If Om vi skriver if följt av ett logiskt uttryck, kommer koden inramad av if och end att utföras om villkoret uppfylls. Om man önskar kan man lägga till ett else i satsen. Då kommer det efter else att utföras om det logiska uttrycket inte är uppfyllt. Nedan följer ett exempel: if A==5 disp('sant, A = 5'); else disp('falskt, A inte = 5'); end Om A är lika med 5 kommer Sant, A = 5 att skrivas ut. Om A är något helt annat kommer Falskt, A inte = 5 att skrivas ut. For Med en for-loop kan man få kommandoraderna i slingan att upprepas ett önskat antal gånger. Det som sker inom slingan kan varieras med hjälp av en räknare, n i exemplet nedan, vars värde ändras en gång varje varv. for n=1:10 n2=nˆ2; sprintf('%d i kvadrat aer lika med %d',n,n2) end I denna kodsnutt är n först 1 och kvadraten räknas ut till 1. Nästa varv är n lika med 2 och kvadraten räknas ut till 4, osv. Sista gången kommer n vara lika med 10 och kvadraten lika med 100.
1 INTRODUKTION TILL MATLAB 14 While Om vi skriver while följt av ett logiskt uttryck, så kommer koden inramad av while och end upprepas så länge det logiska uttrycket är uppfyllt. Nedan följer ett exempel: i=1; s=0; while(s<20) s=s+i i=i+1; end Först är s mindre än 20 och vi går in i loopen. Där ändras s till 1 och variabeln i ökas på till 2. s ändras sedan till 3, 6, 10, 15 och slutligen 21. Loopen avslutas då s är 21 och alltså inte längre mindre än 20, vilket sker då i är lika med 7. 1.6 Bilder i MATLAB För att kunna analysera och presentera sitt mätdata ordentligt kan det vara bra att visulisera det. MATLAB har ett omfattande plot-kommando till detta ändamål som kommer att introduceras här. Plottar och grafer är ett sätt att visualisera ett förhållandet mellan två mängder av tal genom att sätta ut punkter i ett koordinatsystem som beskriver detta förhållande. För att kunna plotta sina mätvärden måste vi först skapa två listor, vi döper dem till x och y. x=[0 1 2 3 4 5 6 7 8 9 10]; y=[1 3 5 7 9 11 13 15 17 19 21]; För att sedan plotta dessa skriver vi plot(x,y) och resultatet kan vi se i figur 8 nedan. För att kunna plotta två listor mot varandra på det här sättet måste vektorerna ha samma längd.
1 INTRODUKTION TILL MATLAB 15 Figur 8: Listan y plottad mot listan x. Som vi ser i figuren så drar MATLAB automatisk linjer mellan mätpunkterna. För att bara plotta punkterna så skriver vi plot(x,y,'ro') och resultat blir enligt figur 9.
1 INTRODUKTION TILL MATLAB 16 Figur 9: Listan y plottad mot listan x som punktvärden. Där o specificerar att mätpunkterna ska visualiseras med en ring och r bestämmer färgen på plotten. Om man vill visualisera mätpunkterna och samtidigt ha linjer mellan dessa så skriver man den sista biten som 'ro '. Använd gärna hjälpfunktionen för fler alternativ om hur man kan ändra utseendet på sin plot. För att göra sina plottar i MATLAB ännu tydligare bör man inkludera titel och axelnamn i sina plottar. Genom att addera raderna nedan utökar vi vårt tidigare exempel: plot(x,y,'ro ') title('titel') xlabel('x axelns namn') ylabel('y axelns namn') Där xlabel namnger den horisontella axeln och ylabel den vertikala. Detta ger oss figur 10 nedan.
1 INTRODUKTION TILL MATLAB 17 Figur 10: Figur med titel och namn på axlarna. Ibland så vill man plotta två grafer samtidigt, antingen i samma fönster eller i två separata. För att göra det behöver vi två nya listor, vi döper dessa till f och g. f=[0 1 2 3 4 5 6 7 8 9 10]; g=[0 3 4 5 8 11 12 13 16 19 20]; För att plotta dem i samma fönster använder vi kommandot hold on: plot(x,y,'ro ') hold on plot(f,g,'gx') title('titel') xlabel('x axelns namn') ylabel('y axelns namn') legend('1:a plottens namn','2:a plottens namn') Funktionen legend() beskriver vad varje kurva representerar som man kan se i figur 11.
1 INTRODUKTION TILL MATLAB 18 Figur 11: Figur med två olika grafer plottade i samma fönster tillsammans med en förklarande ruta. Avslutningsvis vill vi nu plotta de två listorna i var sitt fönster, detta görs genom att specificera det som: figure(1) plot(x,y,'ro ') title('titel1') xlabel('x axelns namn') ylabel('y axelns namn') figure(2) plot(f,g,'gx') title('titel2') xlabel('x axelns namn') ylabel('y axelns namn') Detta ger de två figurerna i figur 12.
1 INTRODUKTION TILL MATLAB 19 Figur 12: Två olika figurer skapade i samma MATLAB-script. Ett avslutande tips är att MATLAB som standard sparar sina figurer som.fig-filer vilket vissa program inte helt stödjer. Använd hellre de vanligare formaten.jpg eller.png när man sparar sina figurer. 1.7 Regressionsanalys När man gör en statistisk undersökning, det skulle kunna vara t.ex. att man har mätt ett tryck i en gas med avseende på temperaturen eller spänningen över ett motstånd med avseende på strömmen, så vill man att dessa mätvärden ska följa någon exakt matematiskt funktion så att man kan testa sina teorier. Tyvärr är detta sällan fallet, mätvärdena hamnar oftast lite i oordning och man måste göra det bästa av situationen, eller som det också kallas regressionsanalys. Det innebär att man använder olika matematiska hjälpmedel för att anpassa sina mätvärden till just en matematisk funktion så att man kan testa sina teorier. 1.7.1 Linjäranpassning En vanlig anpassning är en linjär funktion, alltså en funktion på formen y = kx + m. Ett exempel där man använder linjär regression är Hookes lag som beskriver kraften i en fjäder med avseende på förskjutningen från jämviktsläget som F = Kx, där K är fjäderkonstanten och x är förskjutningen. Det finns många sätt att göra detta i MATLAB, ett av dem är att använda funktionen polyfit(x,y). Säg att vi har en mätserie för kraften hos en fjäder, F, mot dess förskjutning, x. För att linjäranpassa dessa värden skriver vi p = polyfit(x,f,1) Vi får då tillbaka en lista innehållande värdena för linjäranpassningen. Vi återfår dessa genom att skriva k=p(1) och m=p(2). I vårt exempel står k för fjäderkonstanten i Hookes lag och m ligger nära 0. För att kunna visualisera vår linjäranpassning använder vi funktionen polyval(p,x) som skapar en lista med värden för linjäranpassningen skapad av polyfit(x,y). Koden för detta skulle kunna se ut som nedan och det resulterar i figur 13. Notera att linjäranpassningen ibland ligger ovanför mätpunkterna och ibland under. F=[0 0.49 0.98 1.47 1.96 2.45 2.94 3.43 3.92 4.41]; x=[0 0.016 0.037 0.066 0.092 0.116 0.143 0.154 0.176 0.188];
1 INTRODUKTION TILL MATLAB 20 p=polyfit(x,f,1); F lfit=polyval(p,x) plot(x,f,'rx'); hold on plot(x,f lfit) title('hookes lag') xlabel('forskjutning') ylabel('kraft') legend('matdata','linjaranpassning') Figur 13: Mätdata plottat tillsammans med dess linjäranpassning. 1.7.2 Konfidensintervall Ett konfidensintervall anger det intervall omkring medelvärdet inom vilket det sanna värdet finns med en viss sannolikhet. De vanligaste sannolikhetsnivåerna är 95% och 99%. För detta ändamål måste vi först göra en linjäranpassning som i avsnitt 1.7.1 men nu skapar vi även parametern S som innehåller feluppskattningar m.m. [p S]=polyfit(x,F,1); För att skapa konfidensintervallet använder vi funktionen polyconf(p,x,s,alpha). Den skapar samma lista som funktionen polyval(p,x) samt en lista med konfidensintervall för varje punkt. Vilken sannolikhetsnivå man vill ha bestäms av 1 alpha t.ex. alpha=0.05 ger en 95-procentig nivå. Vi utvecklar exemplet i avsnitt 1.7.1 med ett 95-procentig konfidensintervall och resultatet kan ses i figur 14. F=[0 0.49 0.98 1.47 1.96 2.45 2.94 3.43 3.92 4.41];
1 INTRODUKTION TILL MATLAB 21 x=[0 0.016 0.037 0.066 0.092 0.116 0.143 0.154 0.176 0.188]; [p S]=polyfit(x,F,1); [F lfit delta] = polyconf(p,x,s,0.05); plot(x,f,'rx'); hold on plot(x,f lfit) plot(x,f lfit+delta,'r ') plot(x,f lfit delta,'r ') title('hookes lag') xlabel('forskjutning') ylabel('kraft') legend('matdata','linjaranpassning','konfidensintervall') Figur 14: Mätdata plottat tillsammans med dess linjäranpassning och ett 95- procentigt konfidensintervall. 1.7.3 Polynomanpassning Ibland följer sina mätvärden inte någon rät linje utan de har något mer komplicerat samband. Då kan man använda sig utav ett polynom av högre ordning t.ex. y = a 1 x 3 + a 2 x 2 + a 3 x + a 4 som är ett polynom av ordning 3. För att göra en anpassning av högre ordning gör vi som i avsitt 1.7.1 med skillnaden p=polyfit(x,y,n) där n är ordningen på polynomet som man vill anpassa med. I vårt exempel skulle vi sätta n = 3. Det vi får tillbaka från p=polyfit(x,y,n) är värdena på konstanterna som ska stå före varje variabel (a 1, a 2, a 3 och a 4 ovan). Vi hittar dessa genom att skriva: a1=p(1) a2=p(2) a3=p(3)
1 INTRODUKTION TILL MATLAB 22.. o.s.v. 1.7.4 Linjärisering av potensfunktion Ibland vet man inte vilken ordning sitt polynom har och då är det användbart att använda logaritmfunktioner. Säg att vi vill undersöka ett objekts bakomlagda sträcka, s, under fritt fall. Vi har gjort flera mätningar av objektets position efter olika tider t och vi vet att sträckan beskrivs som s = at b där a och b är konstanter. Detta ger att vi kan räkna ut g, tyngdaccelerationen, ur sambandet s = 1 2 g t2. För att lösa ut dessa konstanter börjar vi med att logaritmera funktionerna. s=[0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45]; t=[0.009 0.04 0.096 0.175 0.278 0.404 0.556 0.728 0.926]; lns=log(s); lnt=log(t); Här är funktionen log() den naturliga logaritmen. Vi får nu ett uttryck på formen ln(s) = ln(a) + b ln(t). Nu gör vi en linjäranpassning på våra logaritmerade värden som i avsnitt 1.7.1 och får ut att våra värden blir: Vi får då alltså ln(a) = 1.63 = a = e 1.63 5.10 b = 2.11 2. s = 5.10 t 2 = s = 1 10.2 t2 2 Det vill säga att g = 10.2 enligt detta experiment. 1.7.5 Värdering av resultat Efter att man har gjort sina mätningar och fått sina resultat ska man bestämma osäkerheten i resultaten. Det är viktigt för att det ger ett mått på hur korrekt och tillförlitliga de är. Ett vanligt osäkerhetsmått vid en linjäranpassning är R 2 som visar hur bra sin anpassningen är. Det är ett värde mellan 0 och 1 och ju närmare 1 det är desto bättre är anpassningen. Tyvärr är detta värde lite krånligt att ta fram i MATLAB så vi beskriver hur vi tar fram det utan att lägga för stor vikt vid att förklara nya begrepp. Vi fortsätter kolla på exemplet i avsnitt 1.7.1. För att få fram R 2 -värdet så måste vi beräkna s.k. residualer som sparas i variablen Fresid: Fresid=F F lfit; Sedan behöver vi räkna ut summan av residualerna i kvadrat samt summan av mätvärdena i kvadrat. Det sistnämnda gör vi med hjälp av variansen genom kommandot var:
1 INTRODUKTION TILL MATLAB 23 SSresid = sum(fresid.ˆ2); SStotal = (length(f) 1)*var(F); Vi finner sedan värdet R 2 genom r sqr = 1 SSresid/SStotal; I vårt exempel får vi r sqr=0.9998. Ett annat osäkerhetsmått vid linjäranpassning är adj.r 2. Det är alltid mindre än eller lika med R 2 -värdet och ger en mer pålitlig uppskattning av hur bra linjäranpassningen är. Vi skapar den genom rsq adj = 1 SSresid/SStotal * (length(f) 1)/(length(F) length(p)) Om man tyckte att denna del var lite komplicerad kan man vara lugn, det krävs nämligen betydligt mer kött på benen för att förstå allt detta fullt ut. Om man vill läsa mer om R 2 finns det en bra Wikipedia-artikel som heter Coefficient of determination som kan vara värd att kolla igenom för lite fördjupning.
2 PROGRAMMERING MED MATLAB 24 2 Programmering med MATLAB Att programmera i MATLAB har många fördelar. För det första är det relativt enkelt att implementera sin kod, men det är också bra för att man kan hantera stora mängder data då MATLABs specialitet är matriser. När man programmerar är det viktigt, oberoende av vilket språk man sitter i, att man förstår problemet innan man kastar sig på datorn för att skriva massa kod. Tänk efter vad det är som ska lösas och dela upp problemet i mindre småproblem. Då kan man lösa ett delproblem i taget och kontinuerligt testa om den delen fungerar innan man går vidare till nästa. För att testa om koden fungerar som man har tänkt sig kan man bland annat använda sig av utskrifter, som man sen tar bort, för att se om variablerna har samma värde som man tänkt sig. Andra bra tips är att kommentera sina koder och att indentera, det gör det lättare både för dig och eventuell hjälp att förstå koden. Fler programmeringstips finns under appendix C Tips och Trix. I det här kapitlet kommer vi avancera till att använda MATLAB för att programmera. Det gör vi genom att först prata mer om vektorer, för att sedan introducera matriser, titta på lite mer avancerade loopar och script samt hur man läser in data till MATLAB. 2.1 Introduktion till vektorer och matriser I introduktionskapitlet beskrevs vektorer som en lista av tal och begrepp som klammeroperatorn och kolonoperatorn introducerades. I det här kapitlet kommer vi tydligare förklara vad en vektor och en matris är, hur man kan skapa dem och hur de fungerar. 2.1.1 Vektorer i MATLAB Det finns två olika sorters vektorer, radvektorer och kolumnvektorer. Väldigt logiskt så har radvektorn sina tal sparade som en rad och kolumnvektorn som en kolumn. Skillnaden mellan dess sätt att spara sina vektorer är viktigt i linjär algebra för att matematiken ska stämma, mer om det kommer i kapitlet 4 Linjära system med MATLAB. Just nu räcker det att vi vet att det finns olika sorters vektorer. För att skapa en radvektor, med namnet row, skriver vi: row = [1 2 3 4 5] row = 1 2 3 4 5 Man kan även skapa en radvektor genom att sätta ett komma mellan siffrorna: row = [1, 2, 3, 4, 5]; För att skapa en kolumnvektor separerar man siffrorna med semikolon: column = [1; 2; 3; 4; 5] column =
2 PROGRAMMERING MED MATLAB 25 1 2 3 4 5 Om man råkar skapa en radvektor när man egentligen vill ha en kolumnvektor kan det lätt åtgärdas genom att ta transponatet av radvektorn: row = [2 4 6 8 10]; column = row' column = 2 4 6 8 10 Transponatet av en vektor kan man ta antingen med eller med kommandot transpose. Vektorer i MATLAB indexeras från 1, vilket betyder att om man vill ha ut det första värdet i en vektor skriver man: prime = [2, 3, 5, 7, 11, 13, 17, 19]; prime(1) 2 Om man vill ha ut det sista värdet i en vektor kan man använda sig utav kommandot end: prime(end) 19 När vi har pratat om vektorers index har vi hittills endast använt en siffra i som representerat det i:te talet i vektorn. Men för att kunna skilja på rad- och kolumnvektorer måste man använda sig utav två index. Ett index som motsvarar raden och ett som motsvarar kolumnen. Det tredje talet i en radvektor skrivs alltså row(1,3) vilket betyder att vi vill ha talet som är i första raden och i tredje kolumnen. Det tredje talet i en kolumnvektor hittas genom column(3,1). Det kan tyckas onödigt då row(3) och column(3) kommer returnera samma värde som row(1,3) och column(3,1) men sättet med två index är tydligare och kommer behövas då vi introducerar matriser i kapitel 2.1.2. Matriser fungerar litegrann som 2-dimensionella vektorer. En radvektor har alltid 1 som radindex och en kolumnvektor har alltid 1 som kolumnindex. Kolonoperatorn, som vi tidigare i kapitel 1.4.2 använt för att skapa vektorer, kan även användas för att ta ut värden ur en vektor: prime(4:end)
2 PROGRAMMERING MED MATLAB 26 prime = 7 11 13 17 19 I ovanstående exempel har vi plockat ut det fjärde elementet till och med det sista genom att använda end. Man kan även ta ut varannat tal i en vektor: prime(1:2:end) prime = 2 5 11 17 På liknande sätt kan man ta ut vart n:te tal genom prime(1:n:end) där n kan vara vilket heltal som helst. Om man vill ändra värden i en vektor kan man också använda sig av kolonoperatorn och end: prime(1:2:end)= 1 prime = 1 3 1 7 1 13 1 19 En vektor kan skapas på många olika sätt. I kapitel 1.4.2 har vi nämnt klammeroperatorn och kolonoperatorn, men MATLAB har även inbyggda kommandon som är väldigt användbara när man lärt sig dem. Bland annat kan man om man vet vilken längd man vill ha på sin vektor skapa en vektor med den längden, antingen bestående av nollor eller ettor med hjälp av kommandona zeros och ones: zeros = zeros(3,1) 0 0 0 ones = ones(1,3) 1 1 1 I det här exemplet får vi en kolumnvektor zeros bestående av 3 nollor och en radvektor ones bestående av 3 ettor. Om vet vilken storlek sin vektor kommer att ha är det bra att allokera minne genom att först skapa en vektor med nollor eller ettor. Storleken på vektorer har annars en tendens att växa obehindrat i t.ex. loopar, vilket är krävande. Att ändra värdena är enklare än att låta vektorn växa då man lägger till något. Om man vill ha många värden i sin vektor, t.ex. om man behöver lagra en vektor med 100 sekunder kan man använda sig av linspace:
2 PROGRAMMERING MED MATLAB 27 seconds = linspace(1,100); Genom att använda linspace på detta sättet skapar man en vektor från 1 till 100 med 100 värden. Vill man ha fler, eller färre, värden i sin vektor kan man ange antalet värden i sin vektor genom att lägga till en inparameter: seconds = linspace(1,100,50); Nu får vi en vektor från 1 till 100 med 50 värden. Detta sätt att skapa en vektor ger ofta punkter på decimalform eftersom intervallet ska delas upp i ett givet antal delintervall. Notera att linspace alltid skapar en radvektor så behöver man en kolumnvektor får man ta transponatet av radvektorn som linspace returnerar. Om man vill skapa en vektor med slumpade tal kan man använda sig av rand för slumpade tal mellan 0 och 1 eller randi för slumpartade heltal där första inparametern representerar maxvärdet. random = rand(1,4) random = 0.6948 0.8344 0.6096 0.5747 random2 = randi(15, 4, 1) random2 = 5 7 11 15 I det övre exemplet får vi en radvektor med 4 slumpade värden mellan 0 och 1. I det undre exemplet får vi en kolumnvektor med 5 slumpade heltal med maxvärdet 15. För att kombinera dessa två funktioner och få slumpade tal på decimalform som är större än ett: random + random2' 5.6948 7.8344 11.6096 15.5747 2.1.2 Matriser i MATLAB I inledningen av detta avsnitt nämnde vi att MATLABs styrka ligger i dess sätt att hantera matriser och i detta delkapitel kommer vi gå igenom vad en matris är, hur vi skapar matriser och vad vi kan göra med dem. En matris är en samling av rad- och kolumnvektorer som bildar ett rutnät av värden. Alla vektorer som bygger upp matrisen måste vara lika långa men radvektorerna behöver nödvändigtvis inte vara lika långa som kolumnvektorerna. Oftast har man 2-dimensionella matriser, alltså som ett schackbräde med värden, men man kan även ha flerdimensionella matriser men det kommer vi inte titta närmare på här.
2 PROGRAMMERING MED MATLAB 28 För att skapa en matris gör man på samma sätt som då vi skapade rad- och kolumnvektorer men kombinerat: matrix = [1, 2, 3; 4, 5, 6; 7, 8, 9] matrix = 1 2 3 4 5 6 7 8 9 Man kan även skapa en matris genom att sätta ihop radvektorer: row1 = [10 11 12]; row2 = [20 21 22]; matrix = [row1;row2] matrix = 10 11 12 20 21 22 Många av de sätt vi nyss lärde oss att använda för att skapa vektorer kan vi även använda då vi vill skapa matriser, så som zeros, ones, rand och randi. Notera att man inte kan använda linspace för att skapa matriser. Precis som tidigare anger vi hur många rader och kolumner som vi vill ha. zeros = zeros(2,3) zeros = 0 0 0 0 0 0 Om man vill ha en matris med lika många rader som kolumner behöver man endast ange ett värde: random = rand(3) random = 0.3017 0.0954 0.8593 0.0117 0.1465 0.9742 0.5399 0.6311 0.5708 För att ändra ett värde eller plocka ut från matrisen gör man på liknande sätt som för vektorer. Det man måste komma ihåg är att ange både vilken rad och kolumn som man vill använda. matrix = [1, 2, 3; 4, 5, 6; 7, 8, 9] matrix(2,3) 6
2 PROGRAMMERING MED MATLAB 29 Om man vill ändra alla värden på en viss rad kan man använda sig av kolonoperatorn. Uttrycket matrix(1,:) betyder första raden, alla kolumner: matrix = [1, 2, 3; 4, 5, 6; 7, 8, 9] matrix(1,:) 1 4 7 Man kan även använda sig av end för att ändra vissa värden i en matris. matrix(:,2:end) = 10 1 10 10 4 10 10 7 10 10 Översta raden i ovanstående exempel betyder att på alla rader, från och med andra kolumnen till sista, ska värdet ändras till 10. 2.1.3 Vektor- och matrisoperationer När man arbetar med vektorer och matriser är det viktigt att hålla koll på de vektor- och matrisoperationer som finns och skillnaden mellan dem. Som nämndes i introduktionskapitlet, avsnitt 1.4.2, så kan man multiplicera en vektor elementvis med sig själv men det finns även andra sätt som vi kommer gå igenom i detta delkapitel. Både vektorer och matriser kan hantera addition och subtraktion genom att operationen utförs elementvis: matrix1 = [4, 5, 32; 3, 7, 14]; matrix2 = 4*ones(2,3); matrix1 matrix2 0 1 28 1 3 10 matrix1 + matrix2 8 9 36 7 11 18 I det övre exemplet har vi t.ex. 32 4 = 28 och i det undre 32 + 4 = 36 i den första raden och tredje kolumnen. Man kan även multiplicera, dividera och upphöja vektorer och matriser elementvis:
2 PROGRAMMERING MED MATLAB 30 matrix1.*matrix2 16 20 128 12 28 56 matrix1./matrix2 1.0000 1.2500 8.0000 0.7500 1.7500 3.5000 matrix1.ˆ2 16 25 1024 9 49 196 Notera punkten framför operationen som symboliserar att operationen utförs elementvis. Det som är viktigt att tänka på när man utför dessa elementvisa operationer är att de vektorer och matriser som används måste ha samma dimensioner, alltså samma antal rader och kolumner, annars kommer MATLAB inte förstå vad den ska göra och ge ett felmeddelande. När man jobbar med matriser i MATLAB kommer man ofta få felmeddelanden, så det gäller att förstå dem när de dyker upp. Exempel på vanliga felmeddelanden och hur man kan åtgärda dem finns i appendix B Vanliga fel. Addition, subtraktion, multiplikation, division och upphöjt på det sätt som nu förklarats kallas för array-operationer och det viktiga med detta sätt är punkten framför operationen som man vill utföra. Den betyder att operationen kommer utföras element för element i vektorn eller matrisen och det är därför viktigt med samma dimension. Nu ska vi gå vidare och introducera ett nytt begrepp, matrisoperationer. Matrisoperationerna skiljer sig från array-operationerna på det sättet att man inte tar multiplikation och division elementvis. Istället följer man de matematiska reglerna som används i linjär algebra. I den här guiden kommer dessa regler förklaras ytterliggare i kapitel 4 Linjära system med MATLAB. Just nu räcker det att vi vet att det finns olika sätt att multiplicera och dividera matriser och att resultaten blir annorlunda. För att matrismultiplicera två matriser krävs det att den första matrisens kolumner ska vara lika många som den andra matrisens rader. Detta kan kännas en aning rörigt så vi tittar på ett exempel: matrix1 = [4,5;7,4;9 0] matrix1 = 4 5 7 4 9 0 matrix2 = [3,5,11;7,9,12] matrix2 =
2 PROGRAMMERING MED MATLAB 31 3 5 11 7 9 12 matrix1*matrix2 47 65 104 49 71 125 27 45 99 matrix2*matrix1 146 35 199 71 Notera att den nya matrisen som skapas när vi tar matrix1 matrismultiplicerat med matrix2 har fått en ny dimension med 3 rader och 3 kolumner. Tar vi matrismultiplikationen åt andra hållet får vi en matris med 2 rader och 2 kolumner. Ordningen av multiplikationen är alltså av betydelse. Om man vill ta samma matris multiplicerat med sig själv måste vi använda oss av transponat-operatorn för att få dimensionerna att stämma: matrix1 = [4,5;7,4;9 0] matrix1 = 4 5 7 4 9 0 matrix1*matrix1' 41 48 36 48 65 63 36 63 81 Om detta var svårt att förstå så är det ingen större fara. Man kommer lära sig mycket mer om vektorer och matriser i kursen om linjär algebra. Huvudsaken just nu är att vetskapen om att det finns olika sätt att räkna på då det gäller matriser finns. Det är viktigt att man kontinuerligt, då man programmerar, kontrollerar att resultatet blev som man tänkte sig. Så länge man har koll på det är det lugnt. Vi kan avsluta detta delkapitlen med att reda ut några begrepp. Här har vi pratat om vektorer och matriser men ni har säkert hört talas om arrayer, eller så kommer ni att göra det i framtiden och då kan det vara bra att veta skillnaden. I MATLAB är en vektor en rad eller kolumn med värden. En array är en 2-dimensionell vektor med värden som klarar array-operationer. En matris är också en 2-dimensionell vektor men med matrisoperationer. Skillnaden mellan array-operationer och matrisoperationer är, som vi tidigare nämnt att array-operationerna utförs elementvis medan matrisoperationerna följer de matematiska reglerna i linjär algebra.
2 PROGRAMMERING MED MATLAB 32 2.2 Mer om loopar Ett väldigt viktigt verktyg när man programmerar är att kunna hantera loopar av olika slag. När man har en översiktlig koll på de olika looparna som finns och hur de fungerar spelar det inte så stor roll i vilket programmeringsspråk som man sitter i. Det enda som skiljer är nämligen syntaxen, alltså hur man skriver koden, och den kan man kolla upp. Som tidigare nämnts är det viktigt att förstå problemet innan man börjar koda och att dela upp problemet i små delproblem. Om man gör det kommer man se att det finns väldigt många delproblem som kan lösas med hjälp av loopar. Vi har tidigare nämnt if, for och while vilket är de tre loopar som är mest grundläggande. Om man lär sig att kombinera dessa på ett bra sätt kan man lösa mycket. En loop inuti en annan loop kallas för nästlade loopar och kan vara mycket effektivt, speciellt när man har med matriser att göra. Ett vanligt exempel på nästlade loopar är nästlade for-loopar. På varje ställe i matrisen area vill vi samla arean av en rektangel med sidan som radens index och höjden som kolumnens index. for i=1:3 for j=1:3 area(i,j) = k; end end area = 1 2 3 2 4 6 3 6 9 Den yttersta for-loopen räknar upp matrisens radindex i och den inre räknar upp matrisens kolumnindex j. Först är i lika med 1 och j lika med 1, 2 och 3 innan i ökas till 2, o.s.v. Genom att göra en sån här loop ökar storleken på matrisen för varje varv i loopen. Det man kan göra då för att tjäna datortid är att allokera minne för matrisen med matris = zeros(3). Anledningen till att man skapar en matris med rätt dimensioner men fel element och sedan definierar om elementen så att de stämmer, är att man sparar beräkningstid. Gör man inte en matris i förväg, så kallad förallokering, definierar MATLAB en ny matris för varje iteration, vilket är en betydligt större ansträngning än att bara ändra ett element i matrisen. Ha därför för vana att alltid allokera minne i förväg när det ska skapas stora matriser eller vektorer. Man kan också kombinera de olika looparna med varandra, t.ex. en if utanför en for. Detta kan vara väldigt effektivt som validering av data då man bara vill utföra for-loopen om ett visst villkor är uppfyllt: index = 0; last = 4; if (index > 0) for i=index:last vector(i) = i end end
2 PROGRAMMERING MED MATLAB 33 Om index är 0 som i detta fallet går vi aldrig ens in i for-loopen. Om index hade varit 0 och vi inte hade haft if utanför for hade vi fått ett felmeddelande som talar om att vi försöker komma åt index 0, vilket inte existerar i MATLAB: Attempted to access vector(0); index must be a positive integer or logical. MATLAB returnerar felmeddelanden som detta när MATLAB inte förstår vad man menar. Då gäller det att försöka tyda utskrifterna, vilka är mer eller mindre standardiserade. Exempel på vanliga felmeddelanden finns under appendix B Vanliga fel. Att lägga en if-sats utanför en annan loop på detta sätt gör att man kan kontrollera fel som annars kan uppstå, tex undvika att dela med noll, negativa tal på längder o.s.v. I introduktionskapitlet, avsnitt 1.5, nämnde vi if och else men det finns även ett tredje alternativ, elseif. När man bygger en if-sats med många olika alternativ ska man tänka på att ta det vanligaste alternativet först, eftersom om man går in i if-satsen inte kommer gå in i elseif eller else. if kombineras vanligtvis med de logiska operationerna som vi gick igenom i introduktionen, se avsnitt 1.4.3. Tänk på att man även kan ha flera olika logiska uttryck i en if. Att kombinera många olika logiska uttryck med if och elseif kan göra programmet effektivare så det är viktigt att tänka igenom vilka alternativ man kan tänka sig få och hur man kan kombinera dem. weather = 1; %1 means sun, 0 means rain temperature = 22; if(weather>0) if(temperature<0) disp('soligt, minusgrader') elseif(temperature==0) disp('soligt, nollgradigt ') elseif(temperature>0 && temperature<21) disp('soligt, plusgrader') else disp('soligt, oever 20 grader') end else disp('regn') end I det här exemplet har vi förutsatt att man endast är intresserad av temperaturen om det är soligt och att det oftare är kallt än varmt. När man bygger en if-sats behöver man inte ha med varken elseif eller else utan ibland behöver man endast en if-rad t.ex. i början av sin kod. I nedanstående exempel vill vi kontrollera att numret vi skickar in till while-loopen är positivt för att kunna räkna ut fakulteten. number = 4; factorial = 1; if number>0 while (number>1) factorial= factorial*number; number = number 1; end end
2 PROGRAMMERING MED MATLAB 34 En ny variant som vi inte tidigare nämnt är switch-satsen: mynumber = 1; switch mynumber case 1 disp('negativ etta'); case 0 disp('noll'); case 1 disp('positiv etta'); otherwise disp('annan siffra'); end En switch fungerar som så att man har ett switch-uttryck som antingen är ett nummer eller en textsträng som man sedan evaluerar mot ett case-uttryck. När switch-uttrycket och case-uttrycket överensstämmer utförs raden under. I ovanstående exempel är mynumber 1 och case 1 evalueras och skriver ut Positiv etta. I en switch-sats evalueras endast ett case och satsen avbryts efter blocket är utfört. Om inget av de olika alternativen stämmer körs otherwise vilket kan jämföras med else. Notera att otherwise är valbart precis som else. 2.3 Script i MATLAB I introduktionen, avsnitt 1.5, nämnde vi att ett script är ett dokument i MAT- LAB som kör koden i filen rad för rad. Vi introducerade även funktioner med funktionshuvud bestående av inparametrar och returvärden. I båda dessa fallen använde vi oss av MATLABs M-filer, vilket man ska ha som vana att alltid använda då M-filerna måste sparas för att kunna köras. Med smarta namngivningar kan man därför lätt hålla koll på sina olika koder. Frågan är nu när man ska använda sig utav script och funktioner. Generellt sett ska man skapa funktioner då man inser att man upprepar samma kod flera gånger. T.ex. då man på flera ställen i sin kod räknar ut en area kan man skapa en funktion som gör detta istället och endast anropa funktionen på flera ställen med olika inparametrar. Tänk på att när man har funktioner så skapas lokala variabler som inte senare kan användas. Script ska man som sagt alltid ta för vana att använda sig av om man skriver lite längre kod som man vill spara, ska man endast testa mindre saker kan script vara lite överdrivet. Ett nytt begrepp som vi inte tidigare pratat om är anonyma funktioner. När vi pratar om vanliga funktioner skapar vi funktionen i en extern M-fil och har en annan M-fil med själva huvudprogrammet. Men ibland kan det behövas en mindre funktion, då kan det kännas onödigt att skapa en ny fil bara för det. Den anonyma funktionen skrivs alltså i samma M-fil som huvudprogrammet, förslagsvis samlade på samma ställe. Ett exempel kan vara om man på många ställen vill kvadrera tal: sqr = @(x) x.ˆ2; Variabeln sqr är ett funktionshandtag, @-operatorn skapar själva handtaget och berättar att det är en anonym funktion, x:et inom parantesen beskriver att funktionen tar ett x-värde som inparameter. Denna funktion returnerar ett värde för varje inparameter x, så två inparametrar ger två returvärden:
2 PROGRAMMERING MED MATLAB 35 number = [2 3]; sqr(number) sqr = 4 9 Man kan även skapa anonyma funktioner med inga eller flera inparametrar. constant = @() 10; constant() + 1 ans = 11 myfunction = @(x,y) (3*x + 12*y.ˆ2 x*y); myfunction(3,4) ans = 189 2.4 Läsa in data i MATLAB I detta delkapitel ska vi lära oss hur man läser in data till MATLAB. Vad som är viktigt att komma ihåg är att filen man vill läsa in ifrån måste ligga i samma mapp som sin M-fil för att MATLAB ska hitta det. Man kan läsa in många olika filer i MATLAB, t.ex. filer från andra program. Men hur man gör det kommer senare i A Appendix: Rapportskrivning med MATLAB, det vi ska lära oss nu handlar om hur man läser in data från textfiler. Det finns många olika sätt att läsa in data i MATLAB och efter en snabb anblick kan det verka som att alla sätt fungerar exakt likadant. Ofta kan man läsa in en fil på många olika sätt och många har säkert sitt favoritsätt som man alltid använder. Men självklart är inte alla sätt identiska och därför kan det vara bra att titta på några olika så man vet vilka som finns och när dom är bra att använda. Vi böjar med hur man läser in data med hjälp av MATLABs grafiska interface. Det kan man göra på två olika sätt beroende på om man vill läsa in data från en fil eller från ett urklipp. För att importera från en fil klickar man Home Import data, dubbelklickar på filen man vill läsa in ifrån och ett nytt fönster öppnas, se figur 15. Här har vi läst in en textfil med endast siffror där ena kolumnen motsvaras av längder och den andra kolumnen av skostolekar. Man kan välja att läsa in textfilen som vektorer eller en matris. Om man läser in som en matris kommer matrisen ha samma namn som textfilen om man inte själv ändrar det. Om man väljer att läsa in två kolumnvektorer kommer de ha namnen VarName1 och VarName2 som initialnamn men det kan man ändra genom at dubbelklicka på namnet och ändra till t.ex. length och size. När man är redo att importera sin data klickar man på ikonen import längst upp till höger.
2 PROGRAMMERING MED MATLAB 36 Figur 15: Det nya fönstret som öppnas i MATLAB då man läser in datafiler. För att importera data från urklippet klickar man på den lilla triangeln i Workspace och klickar sedan klistra in. För att använda denna metod krävs det att det man har kopierat kan tydas av MATLAB. Jämför att kopiera siffersekvensen 3 4 5 med four = 4. Om man ska ändra ofta i en textfil men man hela tiden vill läsa in datat för att t.ex. plotta skostorleken mot längden kan det vara bra att läsa in textfilen i ett script. Så länge filen inte byter namn kan man då köra samma program men få olika figurer beroende på hur textfilen senast är sparad. importdata: importdata: Det enklaste sättet att göra detta på är att använda sig utav A = importdata('numbers.txt'); length=a.data(:,1); size=a.data(:,2); Det här sättet är ett väldigt enkelt sätt att läsa in data till en matris om man bara har siffror och vet hur filen är uppbyggd, vilket man väldigt ofta vet då man själv skapat textfilen. Textfilen som vi använt i detta exempel är alltså samma som i tidigare exempel. Ibland kan man ha textfiler med en rad med text ovanför som beskriver vad datapunkterna motsvarar. T.ex. skulle det kunna stå length och size överst i filen. Det man kan göra då för att bara ta ut datapunkterna är att använda sig av delimiterin och headerlinesin som beskriver hur datat är separerat från varandra och på vilken rad man ska börja läsa in datat. filename = 'numbers.txt'; delimiterin = ' '; headerlinesin = 1; A = importdata(filename,delimiterin,headerlinesin); Ovanstående exempel är alltså bra om man har en rad med text ovanför sina datapunkter. load: Ett annat kommando som man kan använda sig av för att läsa in data från filer till en matris är load. Utan textrad överst skriver man: