opgaver:Uge2
Pia Jensen (Talk | contribs) |
m ("MATLAB® Primer" (tidligere kaldet "Getting Started with MATLAB")) |
||
(10 intermediate revisions by one user not shown) | |||
Line 14: | Line 14: | ||
Overvej, hvordan data bedst kan præsenteres. Skal de skaleres, rebinnes, skal nogle af data smides væk, eller transformeres på anden måde? Lav en serie figurer. | Overvej, hvordan data bedst kan præsenteres. Skal de skaleres, rebinnes, skal nogle af data smides væk, eller transformeres på anden måde? Lav en serie figurer. | ||
− | Start gerne med at | + | Start gerne med at arbejde med temperatur versus spænding for datasæt nummer 97, da det er det sjoveste. Temperaturen er i kolonne nummer 4, mens spændingen er i kolonne 9. |
{{hidden begin|toggle=right|title=Hint|titlestyle=background:#ccccff|bg2=#eeeeee}} | {{hidden begin|toggle=right|title=Hint|titlestyle=background:#ccccff|bg2=#eeeeee}} | ||
+ | Brug dataindlæsnings-metoden som er vist i den vedlagte <code>.m</code>-fil til at indlæse dine data. Husk at pakke datafilerne ud i den mappe som du kører MATLAB i - ellers kan programmet jo ikke finde ud af hvor de ligger. | ||
+ | For hjælp til at plotte, kig i kapitel 4 i "MATLAB® Primer" (tidligere kaldet "Getting Started with MATLAB") bogen, der ligger på Absalon. | ||
+ | |||
+ | Start med at arbejde med datasæt nummer 97, og plot temperatur versus spænding. Er der nogle punkter der ligger underligt? Prøv at se om du kan fjerne disse fra datasættet. | ||
{{hidden end}} | {{hidden end}} | ||
{{hidden begin|toggle=right|title=Løsning|titlestyle=background:#ccccff|bg2=#eeeeee}} | {{hidden begin|toggle=right|title=Løsning|titlestyle=background:#ccccff|bg2=#eeeeee}} | ||
+ | Et eksempel på en typisk indlæsning af data kan være koden | ||
+ | :<code>fid = fopen([datadir,'2010_01_0097.dat']);</code> | ||
+ | :<code>Data0097 = cell2mat(textscan(fid, ...</code> | ||
+ | ::<code> '%n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n', ...</code> | ||
+ | ::<code> 'headerlines',14));</code> | ||
+ | :<code>fclose(fid);</code> | ||
+ | |||
+ | hvor <code>datadir</code> er en streng der fortæller MATLAB hvor dataen er gemt, f.eks. <code>data/saras/</code>. Nu er hele datafilen blevet indlæst i en matrice ved navn <code>Data0097</code>, og denne kan man så arbejde videre med. | ||
+ | |||
+ | [[File:uge2fig1.png|frame|Plot af temperatur versus spænding for datafil nummer 97.]] | ||
+ | For at plotte temperatur (kolonne 4) versus spænding (kolonne 9), kan man bruge koden | ||
+ | |||
+ | :<code>figure</code> | ||
+ | :<code>plot( Data0097(1:end,4),Data0097(1:end,9),'.','MarkerFaceColor', ...</code> | ||
+ | ::<code> [0.4 0.4 0.8],'MarkerEdgeColor',[0.4 0.4 0.8] )</code> | ||
+ | :<code>title('Originale data','FontWeight','b','FontSize',12)</code> | ||
+ | :<code>xlabel('Temperatur [K]','FontSize',12)</code> | ||
+ | :<code>ylabel('Spænding [V]','FontSize',12)</code> | ||
+ | :<code>axis([0 4.2 9.45e-7 9.8e-7])</code> | ||
+ | |||
+ | Denne figur kan du se her til højre. | ||
+ | |||
+ | Man kan nu se lidt nærmere på figuren, og se at der er nogle punkter der ligger underligt i forhold til alle de andre - f.eks. langt under kurven i den venstre del af figuren. Disse punkter er fejlmålinger, og dem vil man gerne have væk fra sit datasæt. | ||
+ | [[File:uge2fig2.png|frame|Der er brug for en ny counter til at gemme punkterne, da det nye array ikke skal have tomme linjer.]] | ||
+ | Den nemmeste måde at fjerne fejlpunkter på, er ved at sætte nogle grænser for hvor man tillader data at være - og så loope igennem alle datapunkter og kun gemme dem der overholder reglerne. F.eks. kan man fjerne nogle af fejlpunkterne med koden | ||
+ | |||
+ | :<code>k=0;</code> | ||
+ | :<code>for n = 1:length( Data0097(1:end,4) )</code> | ||
+ | ::<code> if Data0097(n,4) < 1.5</code> | ||
+ | :::<code> if Data0097(n,9) > 9.64*10^(-7)</code> | ||
+ | ::::<code> if Data0097(n,9) < 9.85*10^(-7)</code> | ||
+ | :::::<code> k = k + 1;</code> | ||
+ | :::::<code> DataCorrected(k,2) = Data0097(n,9);</code> | ||
+ | :::::<code> DataCorrected(k,1) = Data0097(n,4);</code> | ||
+ | ::::<code> end</code> | ||
+ | :::<code> end</code> | ||
+ | ::<code> else </code> | ||
+ | :::<code> k = k + 1;</code> | ||
+ | :::<code> DataCorrected(k,2) = Data0097(n,9);</code> | ||
+ | :::<code> DataCorrected(k,1) = Data0097(n,4);</code> | ||
+ | ::<code> end</code> | ||
+ | :<code>end</code> | ||
+ | |||
+ | Denne kode laver en counter <code>k</code> der tæller hvor mange punkter der er blevet "godkendt" som gode data. Den tjekker nu for hvert datapunkt, <code>n</code>, om den overholder kriterierne, og hvis den gør gemmes punktet i det nye data-array <code>DataCorrected</code>. Hvis punktet ikke overholder kriterierne, bliver det ikke gemt. | ||
+ | |||
+ | Man kan også lave denne sortering vha. logiske variable i MATLAB, ved brug af koden | ||
+ | |||
+ | :<code>LOGIC1 = Data0097(:,4) < 1.5;</code> | ||
+ | :<code>LOGIC2 = Data0097(:,9) > 9.64*10^(-7);</code> | ||
+ | :<code>LOGIC3 = Data0097(:,9) < 9.85*10^(-7);</code> | ||
+ | :<code>LOGIC4 = Data0097(:,4) >= 1.5;</code> | ||
+ | :<code>LOGIC5 = LOGIC1 + LOGIC2 + LOGIC3 == 3;</code> | ||
+ | :<code>LOGIC = LOGIC5 + LOGIC4 > 0;</code> | ||
+ | :<code>DataCorrected = NaN(length(Data0097(LOGIC,9)),2);</code> | ||
+ | :<code>DataCorrected(:,2) = Data0097(LOGIC,9);</code> | ||
+ | :<code>DataCorrected(:,1) = Data0097(LOGIC,4);</code> | ||
+ | |||
+ | Denne kode laver boolean arrays (lister af <code>true</code> og <code>false</code> værdier, skrevet ud som 0'er og 1'ere hvis man skriver dem ud) for hvorvidt udtrykkene er sande eller ej. Disse udtryk kombineres så til nye boolean arrays, der til sidst bruges for at få de ønskede data ud af originaldataen. | ||
+ | |||
+ | Andre dele af data der kan ses på: For datasæt 12, 13 og 14 er det interessant at se på magnetfelt (kolonne 2) versus spænding (kolonne 9) og magnetfelt versus magnetiseringen (de udregnes ud fra den givne formel, $\tau = MB$, og at $\tau$ antages at være proportional med spændingen). | ||
{{hidden end}} | {{hidden end}} | ||
Line 25: | Line 89: | ||
Overvej hvordan man kan udlede den indre støj på de målte data. Antag at der ikke er systematiske fejl, og tilføj dette til figurerne. | Overvej hvordan man kan udlede den indre støj på de målte data. Antag at der ikke er systematiske fejl, og tilføj dette til figurerne. | ||
{{hidden begin|toggle=right|title=Hint|titlestyle=background:#ccccff|bg2=#eeeeee}} | {{hidden begin|toggle=right|title=Hint|titlestyle=background:#ccccff|bg2=#eeeeee}} | ||
− | + | Se igen på temperatur versus spænding for datasæt 97 - der er rigtig meget støj, kan du gøre noget ved dette? | |
{{hidden end}} | {{hidden end}} | ||
{{hidden begin|toggle=right|title=Løsning|titlestyle=background:#ccccff|bg2=#eeeeee}} | {{hidden begin|toggle=right|title=Løsning|titlestyle=background:#ccccff|bg2=#eeeeee}} | ||
+ | For at fjerne den indre støj i dataen kan man binne den - altså samle et antal punkter sammen til ét. For at kunne binne data er man først og fremmest nødt til at sortere det i en rækkefølge så punkterne ligger efter hinanden stigende på førstaksen. Dette gøres med koden (igen arbejdes der med temperatur versus spænding for datasæt 97, nu det korrigerede datasæt, som forklaret i løsningen til spørgsmål a) | ||
+ | :<code>DataCorrectedSorted = sortrows(DataCorrected);</code> | ||
+ | |||
+ | Nu kan man så binne sine data, med f.eks. 100 punkter i hvert nyt punkt. Usikkerheden på hvert binnede punkt er SDOM. | ||
+ | |||
+ | :<code>bin = 100;</code> | ||
+ | :<code>T(1) = sum( DataCorrectedSorted(1:bin,1) )/bin;</code> | ||
+ | :<code>T_u(1) = std( DataCorrectedSorted(1:bin,1) )/sqrt(bin); </code> | ||
+ | :<code>U(1) = sum( DataCorrectedSorted(1:bin,2) )/bin;</code> | ||
+ | :<code>U_u(1) = std( DataCorrectedSorted(1:bin,2) )/sqrt(bin);</code> | ||
+ | :<code>number_of_datapoints = length( DataCorrectedSorted(1:end,1) );</code> | ||
+ | :<code>number_of_datapoints_fixed = fix( length( DataCorrectedSorted(1:end,2) )/bin );</code> | ||
+ | :<code>for n = 2:number_of_datapoints_fixed - 1</code> | ||
+ | ::<code> T(n) = sum( DataCorrectedSorted(n*bin+1:(n+1)*bin,1) )/bin;</code> | ||
+ | ::<code> T_u(n) = std( DataCorrectedSorted(n*bin+1:(n+1)*bin,1) )/sqrt(bin);</code> | ||
+ | ::<code> U(n) = sum( DataCorrectedSorted(n*bin+1:(n+1)*bin,2) )/bin;</code> | ||
+ | ::<code> U_u(n) = std( DataCorrectedSorted(n*bin+1:(n+1)*bin,2) )/sqrt(bin);</code> | ||
+ | :<code>end</code> | ||
+ | |||
+ | [[File:uge2fig3.png|frame|Plot af temperatur versus spænding for datafil nummer 97, korrigeret og binnet.]] | ||
+ | Disse binnede data kan, som illustration, plottes oven på de korrigerede data med koden: | ||
+ | |||
+ | :<code>figure</code> | ||
+ | :<code>plot( DataCorrected(1:end,1),DataCorrected(1:end,2),'.','MarkerFaceColor', ...</code> | ||
+ | ::<code> [0.4 0.4 0.8],'MarkerEdgeColor',[0.4 0.4 0.8] )</code> | ||
+ | :<code>hold on</code> | ||
+ | :<code>errorbar( T, U, U_u,'.','MarkerFaceColor',[0.1 0.1 0.6],...</code> | ||
+ | ::<code> 'MarkerEdgeColor',[0.1 0.1 0.6] )</code> | ||
+ | :<code>title(['Korrigeret data (bin = ' num2str(bin) ')'],'FontWeight','b', ...</code> | ||
+ | ::<code> 'FontSize',12)</code> | ||
+ | :<code>xlabel('Temperatur [K]','FontSize',12)</code> | ||
+ | :<code>ylabel('Spænding [V]','FontSize',12)</code> | ||
+ | :<code>axis([0 4.2 9.45e-7 9.8e-7])</code> | ||
+ | |||
+ | denne figur er vist her til højre. | ||
{{hidden end}} | {{hidden end}} | ||
=== Spørgsmål c === | === Spørgsmål c === | ||
Overvej en fortolkning af data. | Overvej en fortolkning af data. | ||
− | {{hidden begin|toggle=right|title= | + | <!--{{hidden begin|toggle=right|title=Løsning|titlestyle=background:#ccccff|bg2=#eeeeee}} |
− | {{hidden end}} | + | {{hidden end}}--> |
− | + | ||
− | + | ||
+ | |||
+ | == Samlede løsninger == | ||
+ | * Et samlet dokument med MATLAB kode til at løse alle opgaverne ovenfor kan hentes her: [[Media:opgaver_uge2_sara.m|opgaver_uge2_sara.m]] |
Latest revision as of 17:09, 21 April 2014
Denne uge er der kun en enkelt opgave. I bliver givet nogle data, som I så skal arbejde med. Når I er færdige med nedenstående spørgsmål anbefales det at I leger lidt videre med data, for at vænne jer til at arbejde med større datasæt i MATLAB. I kan også prøve at indlæse nogle af jeres egne data (I har da gemt data fra jeres tidligere kurser, ikke?).
Contents |
Opgave 1 - Saras data
- Start med at hente pakken med datasættene: ExerciseSarasData.zip
Vi skal her arbejde med ægte data, fra Sara Eisenhardts speciale, 2010. Eksperimentet var måling af det magnetiske moment af en prøve af stoffet LiHoF4, som kun er magnetisk ved temperaturer under 1.5 K. Det er jeres opgave at analysere Saras data og producere et godt plot.
Magnetiseringen blev målt med et kraftmoment-magnetometer, en opstilling helt analog til jeres vægt-vippe opstilling. Magnetiseringen i et påtrykt felt giver anledning til et kraftmoment på prøven, $\tau = M B$. Dette giver anledning til en bøjning af en vippe, som igen forårsager ændring af modstanden i en strain gauge. Denne måles som spænding over en Wheatstonebro med en lock-in forstærker.
I dataserierne er bl.a. angivet målt spænding og påtrykt $B$-felt som en tidsserie, der er samplet ofte. Resten er ikke vigtigt her. Se den .m
-fil der er vedlagt dataen for tips til hvordan data kan indlæses.
Spørgsmål a
Overvej, hvordan data bedst kan præsenteres. Skal de skaleres, rebinnes, skal nogle af data smides væk, eller transformeres på anden måde? Lav en serie figurer.
Start gerne med at arbejde med temperatur versus spænding for datasæt nummer 97, da det er det sjoveste. Temperaturen er i kolonne nummer 4, mens spændingen er i kolonne 9.
Brug dataindlæsnings-metoden som er vist i den vedlagte .m
-fil til at indlæse dine data. Husk at pakke datafilerne ud i den mappe som du kører MATLAB i - ellers kan programmet jo ikke finde ud af hvor de ligger.
For hjælp til at plotte, kig i kapitel 4 i "MATLAB® Primer" (tidligere kaldet "Getting Started with MATLAB") bogen, der ligger på Absalon.
Start med at arbejde med datasæt nummer 97, og plot temperatur versus spænding. Er der nogle punkter der ligger underligt? Prøv at se om du kan fjerne disse fra datasættet.
Et eksempel på en typisk indlæsning af data kan være koden
fid = fopen([datadir,'2010_01_0097.dat']);
Data0097 = cell2mat(textscan(fid, ...
'%n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n %n', ...
'headerlines',14));
fclose(fid);
hvor datadir
er en streng der fortæller MATLAB hvor dataen er gemt, f.eks. data/saras/
. Nu er hele datafilen blevet indlæst i en matrice ved navn Data0097
, og denne kan man så arbejde videre med.
For at plotte temperatur (kolonne 4) versus spænding (kolonne 9), kan man bruge koden
figure
plot( Data0097(1:end,4),Data0097(1:end,9),'.','MarkerFaceColor', ...
[0.4 0.4 0.8],'MarkerEdgeColor',[0.4 0.4 0.8] )
title('Originale data','FontWeight','b','FontSize',12)
xlabel('Temperatur [K]','FontSize',12)
ylabel('Spænding [V]','FontSize',12)
axis([0 4.2 9.45e-7 9.8e-7])
Denne figur kan du se her til højre.
Man kan nu se lidt nærmere på figuren, og se at der er nogle punkter der ligger underligt i forhold til alle de andre - f.eks. langt under kurven i den venstre del af figuren. Disse punkter er fejlmålinger, og dem vil man gerne have væk fra sit datasæt.
Den nemmeste måde at fjerne fejlpunkter på, er ved at sætte nogle grænser for hvor man tillader data at være - og så loope igennem alle datapunkter og kun gemme dem der overholder reglerne. F.eks. kan man fjerne nogle af fejlpunkterne med koden
k=0;
for n = 1:length( Data0097(1:end,4) )
if Data0097(n,4) < 1.5
if Data0097(n,9) > 9.64*10^(-7)
if Data0097(n,9) < 9.85*10^(-7)
k = k + 1;
DataCorrected(k,2) = Data0097(n,9);
DataCorrected(k,1) = Data0097(n,4);
end
end
else
k = k + 1;
DataCorrected(k,2) = Data0097(n,9);
DataCorrected(k,1) = Data0097(n,4);
end
end
Denne kode laver en counter k
der tæller hvor mange punkter der er blevet "godkendt" som gode data. Den tjekker nu for hvert datapunkt, n
, om den overholder kriterierne, og hvis den gør gemmes punktet i det nye data-array DataCorrected
. Hvis punktet ikke overholder kriterierne, bliver det ikke gemt.
Man kan også lave denne sortering vha. logiske variable i MATLAB, ved brug af koden
LOGIC1 = Data0097(:,4) < 1.5;
LOGIC2 = Data0097(:,9) > 9.64*10^(-7);
LOGIC3 = Data0097(:,9) < 9.85*10^(-7);
LOGIC4 = Data0097(:,4) >= 1.5;
LOGIC5 = LOGIC1 + LOGIC2 + LOGIC3 == 3;
LOGIC = LOGIC5 + LOGIC4 > 0;
DataCorrected = NaN(length(Data0097(LOGIC,9)),2);
DataCorrected(:,2) = Data0097(LOGIC,9);
DataCorrected(:,1) = Data0097(LOGIC,4);
Denne kode laver boolean arrays (lister af true
og false
værdier, skrevet ud som 0'er og 1'ere hvis man skriver dem ud) for hvorvidt udtrykkene er sande eller ej. Disse udtryk kombineres så til nye boolean arrays, der til sidst bruges for at få de ønskede data ud af originaldataen.
Andre dele af data der kan ses på: For datasæt 12, 13 og 14 er det interessant at se på magnetfelt (kolonne 2) versus spænding (kolonne 9) og magnetfelt versus magnetiseringen (de udregnes ud fra den givne formel, $\tau = MB$, og at $\tau$ antages at være proportional med spændingen).
Spørgsmål b
Overvej hvordan man kan udlede den indre støj på de målte data. Antag at der ikke er systematiske fejl, og tilføj dette til figurerne.
Se igen på temperatur versus spænding for datasæt 97 - der er rigtig meget støj, kan du gøre noget ved dette?
For at fjerne den indre støj i dataen kan man binne den - altså samle et antal punkter sammen til ét. For at kunne binne data er man først og fremmest nødt til at sortere det i en rækkefølge så punkterne ligger efter hinanden stigende på førstaksen. Dette gøres med koden (igen arbejdes der med temperatur versus spænding for datasæt 97, nu det korrigerede datasæt, som forklaret i løsningen til spørgsmål a)
DataCorrectedSorted = sortrows(DataCorrected);
Nu kan man så binne sine data, med f.eks. 100 punkter i hvert nyt punkt. Usikkerheden på hvert binnede punkt er SDOM.
bin = 100;
T(1) = sum( DataCorrectedSorted(1:bin,1) )/bin;
T_u(1) = std( DataCorrectedSorted(1:bin,1) )/sqrt(bin);
U(1) = sum( DataCorrectedSorted(1:bin,2) )/bin;
U_u(1) = std( DataCorrectedSorted(1:bin,2) )/sqrt(bin);
number_of_datapoints = length( DataCorrectedSorted(1:end,1) );
number_of_datapoints_fixed = fix( length( DataCorrectedSorted(1:end,2) )/bin );
for n = 2:number_of_datapoints_fixed - 1
T(n) = sum( DataCorrectedSorted(n*bin+1:(n+1)*bin,1) )/bin;
T_u(n) = std( DataCorrectedSorted(n*bin+1:(n+1)*bin,1) )/sqrt(bin);
U(n) = sum( DataCorrectedSorted(n*bin+1:(n+1)*bin,2) )/bin;
U_u(n) = std( DataCorrectedSorted(n*bin+1:(n+1)*bin,2) )/sqrt(bin);
end
Disse binnede data kan, som illustration, plottes oven på de korrigerede data med koden:
figure
plot( DataCorrected(1:end,1),DataCorrected(1:end,2),'.','MarkerFaceColor', ...
[0.4 0.4 0.8],'MarkerEdgeColor',[0.4 0.4 0.8] )
hold on
errorbar( T, U, U_u,'.','MarkerFaceColor',[0.1 0.1 0.6],...
'MarkerEdgeColor',[0.1 0.1 0.6] )
title(['Korrigeret data (bin = ' num2str(bin) ')'],'FontWeight','b', ...
'FontSize',12)
xlabel('Temperatur [K]','FontSize',12)
ylabel('Spænding [V]','FontSize',12)
axis([0 4.2 9.45e-7 9.8e-7])
denne figur er vist her til højre.
Spørgsmål c
Overvej en fortolkning af data.
Samlede løsninger
- Et samlet dokument med MATLAB kode til at løse alle opgaverne ovenfor kan hentes her: opgaver_uge2_sara.m