42 svar
325 visningar
Soderstrom är nöjd med hjälpen
Soderstrom 2767
Postad: 16 nov 2021 15:24 Redigerad: 16 nov 2021 15:34

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.

Matsmats 567 – Livehjälpare
Postad: 16 nov 2021 17:28

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.

Soderstrom 2767
Postad: 16 nov 2021 18:48 Redigerad: 16 nov 2021 18:50

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
Dr. G 9326
Postad: 16 nov 2021 18:55

Din for-loop slutar där den börjar. 

Vad är pos i din integral-funktion?

Soderstrom 2767
Postad: 16 nov 2021 19:06

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

Dr. G 9326
Postad: 16 nov 2021 20:23

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. 

Soderstrom 2767
Postad: 16 nov 2021 20:39

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
Dr. G 9326
Postad: 16 nov 2021 20:42

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. 

Soderstrom 2767
Postad: 16 nov 2021 20:45

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
Dr. G 9326
Postad: 16 nov 2021 21:03

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))

Soderstrom 2767
Postad: 16 nov 2021 21:55 Redigerad: 16 nov 2021 21:55

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
Dr. G 9326
Postad: 16 nov 2021 22:07

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å?

Soderstrom 2767
Postad: 16 nov 2021 22:18

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
Dr. G 9326
Postad: 16 nov 2021 22:29

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. 

Soderstrom 2767
Postad: 16 nov 2021 22:38 Redigerad: 16 nov 2021 22:39

Jag använde

fplot(@(pos) consumption(velocity_routeX(pos,speedX,distanceX)))

men verkar inte få någon figur!

Dr. G 9326
Postad: 16 nov 2021 23:07

Får du ut något värde, t.ex

consumption(velocity_routeX(21,speedX,distanceX)))

?

Soderstrom 2767
Postad: 16 nov 2021 23:54 Redigerad: 16 nov 2021 23:59

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
Dr. G 9326
Postad: 17 nov 2021 00:05

Ja, speedX och distanceX finns ju bara som inparapmetrar till totalConsumption.

Återkommer i morgon. 

Soderstrom 2767
Postad: 17 nov 2021 00:14

God natt!! 

Soderstrom 2767
Postad: 17 nov 2021 21:06 Redigerad: 17 nov 2021 21:06

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)))

Dr. G 9326
Postad: 17 nov 2021 21:52

Då ser något knasigt ut. Är A och B rätt?

Soderstrom 2767
Postad: 17 nov 2021 22:08

...Tror jag.

Dr. G 9326
Postad: 17 nov 2021 22:39

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. 

Soderstrom 2767
Postad: 17 nov 2021 23:21 Redigerad: 18 nov 2021 00:37

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
Dr. G 9326
Postad: 18 nov 2021 19:44

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.

Soderstrom 2767
Postad: 18 nov 2021 23:49

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
Dr. G 9326
Postad: 19 nov 2021 08:12

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)),'-')

Soderstrom 2767
Postad: 19 nov 2021 19:12 Redigerad: 19 nov 2021 20:26

 

Plotten:

Dr. G 9326
Postad: 19 nov 2021 20:19

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. 

Soderstrom 2767
Postad: 19 nov 2021 21:16 Redigerad: 19 nov 2021 21:26

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
Dr. G 9326
Postad: 19 nov 2021 21:29
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?

Soderstrom 2767
Postad: 19 nov 2021 21:33

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
Dr. G 9326
Postad: 19 nov 2021 21:48

Och koden för consumption(...)?

Soderstrom 2767
Postad: 19 nov 2021 22:24 Redigerad: 19 nov 2021 22:24

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
 
Dr. G 9326
Postad: 19 nov 2021 22:34

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. 

Soderstrom 2767
Postad: 19 nov 2021 23:18 Redigerad: 19 nov 2021 23:19

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

Soderstrom 2767
Postad: 22 nov 2021 20:41

Bump:(

Dr. G 9326
Postad: 22 nov 2021 20:55

Vad funkar inte nu?

Jag skulle först plotta konsumtionen mellan 0 och 65. 

En loop får du nog ha med någonstans. 

Soderstrom 2767
Postad: 23 nov 2021 17:34

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."

Dr. G 9326
Postad: 23 nov 2021 18:22

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. 

Soderstrom 2767
Postad: 24 nov 2021 17:21

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
Dr. G 9326
Postad: 25 nov 2021 18:50

Ja, det ska väl funka. Antar att du har testkört och så?

Soderstrom 2767
Postad: 25 nov 2021 19:03 Redigerad: 25 nov 2021 19:06

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.

Svara Avbryt
Close