Projekt i MATLAB (3)
Hej! Jag är nöjd med vad vi kom fram till i mina föregående trådar, men hoppas att också läraren är det :') Jag har dock en sista grej att komplettera. Jag infogar allt som vanligt.
Uppgiften
Mitt första försök + Feedback
- Varför används ArrayValued? Funktionen finns inte testad någonstans. Indenturing i loopen saknas. Satsen q=0 är meningslös. Texten ”Först nollställs vektorn som byggs av funktionen …” ska inte ingå i funktionens hjälptext.
function [t] = totalConsumption(x,speedX,distanceX)
%Funktionen räknar den sammanlagda elkonsumtion för en viss sträcka,
%given som ett tal eller vektor x, på en given rutt. Rutten ges i form
%av två vektorer, (disantceX) och (speedX)
%Först nollställs vektorn som byggs av funktionen. Detta för att kunna köra
%funktionen flera gånger med fallande längd på inputvektorn x.
q=0;
%Sedan körs loopen som bygger vektorn genom att köra totalConsumption ett
%värde i taget. Om x är tal så körs den loop en gång bara och q blir också tal
for i=1:length(x)
%Integranden består av funktionen för hastighet vid en given position
%på en given rutt insatt i funktionen
%för elkonsumptionen för en given hastighet. ArrayValued,true är har lagts till
%då Matlab inte fungerar om den inte finns där
q(i)=integral(@(pos) consumption(velocity_routeX(x(i),speedX,distanceX)),0,x(i),
'ArrayValued';true);
end
end
Jag tänker att t.ex q=0; är viktigt för att loopen inte ska ändras? men tydligen är det fel.
Ok, men nu får du nog jobba lite själv...
Filen går inte att köra ens. Lite tips:
* Indentera. Man kan ställa in MATLAB så den indenterar själv, finns olika varianter.
* Om du vill dela av en lång rad måste du avsluta den brutna raden med ...
* Satsen q=0 initierar q till en skalär (eg. en vektor med längd 1), sedan skriver du över den med något annat. Det är det läraren anmärker på.
* Kolla i editorn, hovra över de små linjerna jag markerat, läs varnings- och felmeddelandena. Den lilla fyrkanten överst skall helst vara grön, definitivt inte röd. Röd indikerar syntaxfel av något slag:
Ett grundtips som du bör använda är att sätta brytpunkter och stega dig fram i koden, du kan då se hur variablerna ändras, vad som går rätt och fel, osv. Det är ett utmärkt sätt att både debugga och att förstå egen och andras kod.
Läs hjälptexten för integral och tänk efter på lärarens synpunkt på 'ArrayValued'.
Det är förresten ett annat grundtips, använd help i MATLAB mycket, t.ex. 'help integral'. MATLAB har så många funktioner att ingen människa kan hålla reda på dem, än mindre när man kan kalla på varje funktion på flera olika sätt.
Ja! Har jag gjort rätt nu? det är grönt överallt i scriptet :)
Edit: tog bort hjälptexten bara för enkelhetsskull
function t = totalConsumption(x,speedX,distanceX)
for i=1:length(x)
end
t(i)=integral(@(pos) consumption(velocity_routeX(x(i),speedX,distanceX)),0,x(i));
end
Din for-loop slutar där den börjar.
Vad är pos i din integral-funktion?
pos är positionen för en viss rutt (A eller B).
Jag, jag behöver nog hjälp med for-loopen, när jag lägger "end" i slutet av scripten så blir det "fel"
Bortse från vissa delar av hjälptexten
Jag hade börjat med att plotta c(v(s)) för någon rutt för att få en känsla av vad som integreras och uppskatta en förväntad storleksordning av integralen. Det blir svårare att göra fel då.
t(i)=integral(@(pos) consumption(velocity_routeX(x(i),speedX,distanceX)),0,x(i));
Du skriver
@(pos) consumption(velocity_routeX(x(i),speedX,distanceX))
men det finns inget pos-beroende i consumption(velocity_routeX(x(i),speedX,distanceX)), eller?
Jämför
@(x) sin(x) + x.^2
Strunta först i for-loopen och se om du kan få ut konsumtionen under t.ex de första 5 kilometerna.
Alltså, jag har tidigare gjort en liknande (lättare) uppgift. Integrerar funktionen utan problem, men det blir svårt i projektet, för att jag försöker kombinera uppgift 2 med 4, och då måste jag ju har en loop??
function y=v(t)
g=9.81;
m=80;
c=12;
y=((g*m)/c)*(1-exp((-c*t/m)));
end
disp('Detta program räknar ut sträckan i meter som en fallskärmhoppare hinner efter en viss tid i sekunder.')
x= input('vilken tid i sekunder? ');
q=integral(@(t) v(t),0,x);
q
Och där integrerar du v(t) m.a.p t.
I den tidigare koden så integrerar du m.a.p pos, men integranden har inget pos-beroende.
Yepp, jag gör det, märker nu att det borde stå x istället för pos (?)
function t = totalConsumption(x,speedX,distanceX)
for i=1:length(x)
t(i)=integral(@(x) consumption(velocity_routeX(x(i),speedX,distanceX)),0,x(i));
end
end
Själva namnet på variabeln är inte relevant.
Du vill integrera från 0 till det du kallar x(i). Då funkar alla namn på integrationsvariabel, utom x! pos går bra, men consumption måste då hämta värden vid pos.
integral(@(pos) consumption(velocity_routeX(pos,speedX,distanceX)),0,x(i))
Så typ? Ser ut som att jag inte har "pos" någonstans förutom i velocity_routeX och integral-uttrycket :o
function t = totalConsumption(x,speedX,distanceX)
for i=1:length(x)
x=input('ange ett värde på positionen');
t(i)=integral(@(pos) consumption(velocity_routeX(pos,speedX,distanceX)),0,x(i));
end
end
Du kan kalla integrationsvariaveln för i princip vad du vill. Den ska variera mellan 0 och x(i)
x däremot verkar du skicka in i funktionen, men sedan så sätts x till input(...) i loopen. Ska det vara så?
Får ingen syntaxfel nu, tror jag :') men tog bort det där med input, det var värdelöst!
function Dr_G = totalConsumption(x,speedX,distanceX)
for i=1:length(x)
Dr_G=integral(@(pos) consumption(velocity_routeX(pos,speedX,distanceX)),0,x(i));
end
end
Det här borde funka.
Det är dock lätt att göra fel, så jag skulle plotta
@(pos) consumption(velocity_routeX(pos,speedX,distanceX))
från 0 till max och se om det verkar vettigt.
Jag använde
fplot(@(pos) consumption(velocity_routeX(pos,speedX,distanceX)))
men verkar inte få någon figur!
Får du ut något värde, t.ex
consumption(velocity_routeX(21,speedX,distanceX)))
?
Nej! Men om jag definierar vad inputsen är, ja.
T.ex
Edit: Vad har jag kvar? Jag tänker att första parametern "pos" borde definieras med en vektor eller??
A=speedA_kmph;
B=distanceA_km;
consumption(velocity_routeX(21,A,B))
%ger oss ett värde på
137.2390
Ja, speedX och distanceX finns ju bara som inparapmetrar till totalConsumption.
Återkommer i morgon.
God natt!!
Jag får detta när jag f-plotar integralen med respektive rutt enligt:
fplot(@(pos) consumption(velocity_routeX(pos,A,B)))
hold on
fplot(@(pos) consumption(velocity_routeX(pos,C,D)))
Då ser något knasigt ut. Är A och B rätt?
...Tror jag.
Ok, men du får plotta för relevanta värden på pos. fplot är nån svart låda som själv väljer värden på pos. Plotta från pos = 0 till maxavståndet.
Typ så? Jag vet att det inte stämmer riktigt, men är jag på rätt spår?
Edit: En sak jag glömde att nämna; Jag kombinerar uppgift 2 och 4 med varandra. :)
function Dr_G = totalConsumption(x,speedX,distanceX)
for i=1:length(x)
x=linspace(0,1,max(A));
Dr_G=integral(@(pos) consumption(velocity_routeX(pos,speedX,distanceX)),0,x(i));
end
end
Prova t.ex
position = linspace(0,200,201);
plot(position, consumption(velocity_routeX(position,speedX,distanceX),'-')
speedX och distanceX får du först definiera.
Jag har lagt två inputs för att definiera parametrarna, men känns som om något fortfarande fattas.
function Dr_G = totalConsumption(x,speedX,distanceX)
for i=1:length(x)
Dr_G=integral(@(pos) consumption(velocity_routeX(pos,speedX,distanceX)),0,x(i));
speedX=input('Ange ett värde på hastigheten');
distanceX=input('Ange ett värde på sträckan');
end
end
Nu har du med speedX och distanceX som inparametrar, räknar sedan ut integralen, och så sätter du nya värden på speedX och distanceX (och gör inget mer).
Jag hade nog gjort en funktion som beräknar konsumtionen mellan 0 och x. Sedan kan funktionen anropas med olika x-värden. (Skippa for-loop i funktionen.)
För att se att allt verkar vettigt så skulle jag gärna se plotten
position = linspace(0,200,201);
plot(position, consumption(velocity_routeX(position,speedA_kmphX,distanceA_kmph)),'-')
Plotten:
Negativ konsumtion kan ju inte gärna stämma. Något är knas.
Jag vill gärna se hur integranden ser ut, så kan man angöra om felet kan ligga där, eller om det är integreringen som spökar.
Det är fortfarande samma kod, jag har bara plottat som vanligt.
Kan orsaken vara att inparametrarna? typ byta plats på speedX och distanceX? Men jag måste även göra det i hastighetsfunktionen, tror dock det inte spelar någon roll...
Edit: Har nu byt plats på inparametrarna - ingen skilland.
function Dr_G = totalConsumption(x,speedX,distanceX)
for i=1:length(x)
Dr_G=integral(@(pos) consumption(velocity_routeX(pos,speedX,distanceX)),0,x(i));
end
end
Soderstrom skrev:
Plotten:
Om det här är plotten jag har efterfrågat så är något knas med något i consumption(...).
Hur säker är du på att velocity_routeX(...) är korrekt?
Jag ser inte nåt fel :D , inga syntaxfel + Jag har tidigare använt denna funktion och fick rätt plot :')
function v = velocity_routeX(pos,speedX,distanceX)
%Funktionen r¨aknar hastigheten f¨or en given position f¨or en viss rutt.
%Rutten ges i form av tv˚a vektorer. En med ett antal distanser p˚a rutten
%och den andra med hastigheter f¨or distanserna.
sd = spline(distanceX,speedX); %H¨ar skapas ett approximerat funktionsuttryck
%f¨or v
v = ppval(sd,pos); %H¨ar ber¨aknas v f¨or given position
end
Och koden för consumption(...)?
Ser inga konstigheter även här :|
function c = consumption(v)
%En funktionen som räknar elkonsumptionen vid en viss hastighet v.
%Värden är mellan 2 km/h - 200 km/h.
load ('elbilTesla.mat','consumption_Whpkm','speed_kmph'); %Värdena laddas in i elbilTesla.mat,
%för att skapa ett approximerat funktionsuttryck.
cs=spline(speed_kmph,consumption_Whpkm); %Approximationen skapas
c=ppval(cs,v); %Här beräknas värdet för hastigheten som givits
end
Aha, sträckan verkar ju inte gå över 65 km (för ena rutten), så om man extrapolerar därifrån så kan ju vad som helst hända. Fick för mig att det var 200 km, men det var nog något annat.
Kolla vad max är på varje sträcka och gå inte över det.
Yepp, v är mellan 2-200 km/h. S är som du sa, nästan :)
Men då måste jag ju använda mig av en loop :(
Så typ; for i=1:length(x)
j=x(i);
if j>max(distanceX)
disp(['j ska vara <= ', num2str(max(distanceX)),'km'])
else
Dr_G=integral(@(pos) consumption(velocity_routeX(pos,distanceX,speedX)),0,j);
end
end
Bump:(
Vad funkar inte nu?
Jag skulle först plotta konsumtionen mellan 0 och 65.
En loop får du nog ha med någonstans.
Jag får detta när jag plottar, men det är ingenting jag behöver lägga i rapporten eller?
Han säger dock "Funktionen finns inte testad någonstans. Indenturing i loopen saknas."
Skriv nu en funktion som integrerar denna. Du verkar vilja använda integral(...). 0 kan vara undre gräns, övre gräns kan du ha som input. Du har i princip den koden redan.
Sedan kan funktionen anropas med olika parametrar för att få ut consumption var 5:e km eller vad det nu var (i en loop).
Du kan också lägga in loopen i funktionen. Lite av en smaksak.
Jag gjorde så och skickade in uppgiften, vad tror du?
Visa spoiler
distanceX= input('En sträckas vektor ');
svektor=0:5:max(distanceX);
%vektor delas in var femte kilometer
speedX=input('En hastighets vektor ');
%konsumptionen räknas med en forloop som skickar in vektorerna
for i=1:length(svektor)
x=svektor(i);
Consupmtion(i)= totalConsumption(x,distanceX,speedX);
end
Consupmtion
Ja, det ska väl funka. Antar att du har testkört och så?
Ja jag har testkört såhär:
Visa spoiler
%Trycker på "Run" och fyller i command window:
D
n sträckas vektor [12 24 4 44 21 ]
En hastighets vektor [12 24 4 44 21 ]
%då får jag :
Consupmtion =
1.0e+03 *
0 1.2414 1.8871 2.3843 2.8293 3.2530 3.6704 4.0903 4.5189
Ska jag ha med detta i rapporten eller räcker det med koderna?
Tillägg: 25 nov 2021 19:06
Det fungerar även om jag skickar kolonnvektorer.