Massesenter stang matlab

Det er god trening å prate matematikk. Her er det fritt fram for alle. Obs: Ikke spør om hjelp til oppgaver i dette underforumet.

Moderators: Vektormannen, espen180, Aleks855, Solar Plexsus, Gustav, Nebuchadnezzar, Janhaa

Post Reply
Nebuchadnezzar
Fibonacci
Fibonacci
Posts: 5648
Joined: 24/05-2009 14:16
Location: NTNU

Skal skrive e funksjon i matlab som beregner hvor massesenteret til en stang ligger.

Tenk deg en lang stang hvor massen er ulikt fordelt. Den første meteren veier 3 kg, den neste meterenveier 5 kg, den neste 2 kg, osv.


Vi kan representere dette som en tabell

stang = [3 5 2 ...].

Stangens massemidtpunkt er det punktet hvor det er like mye vekt på hver side.

a) Lag en funksjon som tar inn en tabellrepresentasjon av stangen og returnerer massemidtpunktet
prøvde meg med noe slikt

Code: Select all

function Y = Massepunkt(a)

b = length(a);
h = zeros(1,b);

    for i=1:b
      h(i) =a(i)*(i - 1/2);
    end    
Y = sum(h)/(sum(a));
end
Joda, koden kjører. Men gir meg feil verdi for massepunktet. for eksempel for a = [1 2 1 2]

Noen tips om å sette opp koden riktig? =)
"Å vite hva man ikke vet er og en slags allvitenhet" - Piet Hein
https://s.ntnu.no/Integralkokeboken
Lektor - Matematikk, Fysikk og Informatikk
drgz
Fermat
Fermat
Posts: 757
Joined: 24/12-2008 23:22

Hvis jeg tolker koden din rett prøver du å skrive

[tex]R = \frac1M\sum_im_ir_i[/tex]

Da kan du i så fall skrive:

Code: Select all

function R = massepunkt(m)
m = m(:);
r = [0.5:1:numel(m)-0.5]';
R = r'*m/sum(m);
end
Nebuchadnezzar
Fibonacci
Fibonacci
Posts: 5648
Joined: 24/05-2009 14:16
Location: NTNU

Koden din er også feil, virker det som =(

Gjør samme feilen som min.

Skriver jeg inn

1 2 1 2

får jeg ut

2.16667

Men det skal da bli 2 ?
"Å vite hva man ikke vet er og en slags allvitenhet" - Piet Hein
https://s.ntnu.no/Integralkokeboken
Lektor - Matematikk, Fysikk og Informatikk
drgz
Fermat
Fermat
Posts: 757
Joined: 24/12-2008 23:22

1*0.5+2*1.5+1*2.5+2*3.5 = 0.5+3+2.5+7=13

13 / 6 = 2+1/6
Nebuchadnezzar
Fibonacci
Fibonacci
Posts: 5648
Joined: 24/05-2009 14:16
Location: NTNU

Sikkert bare meg som er dum, men massesenteret er vel definert slik at det skal være like mye masse på høyre og venstre side?

Om vi ser på det i bare to dimensjoner

Dersom stangen er delt inn 1 2 1 2

så er jo det like mye masse på høyre og venstre side om balansepunktet/tungdepunktet ligger i (0,2) ?

EDI: Jeg er *****la dum

alt gir mening nå
"Å vite hva man ikke vet er og en slags allvitenhet" - Piet Hein
https://s.ntnu.no/Integralkokeboken
Lektor - Matematikk, Fysikk og Informatikk
espen180
Gauss
Gauss
Posts: 2578
Joined: 03/03-2008 15:07
Location: Trondheim

Ikke en kommentar på syntaks, men om programmeringsstil. Der ut som

Code: Select all

function mpkt = massepunkt(a)
    M=sum(a);
    m=cumsum(a);
    i=1;
    while m(i) < M/2
        i=i+1;
    end
    mpkt=i;
end
gjør jobben mer effektivt, ettersom den tar i bruk den innebydge funksjonen cumsum.

Jeg testa begge, og denne er omtrent 2-3 ganger raskere.

Jeg sjekka også alternativet

Code: Select all

function mpkt = massepunkt(a)
    M=sum(a);
    m=cumsum(a);
    mpkt=find(m>=M/2,1);
end
Den er også raskere enn din kode, men ikke så rask som den over.

Edit: Fiksa feil i den første koden.
Last edited by espen180 on 23/10-2011 22:24, edited 1 time in total.
drgz
Fermat
Fermat
Posts: 757
Joined: 24/12-2008 23:22

Nebuchadnezzar wrote:Sikkert bare meg som er dum, men massesenteret er vel definert slik at det skal være like mye masse på høyre og venstre side?

Om vi ser på det i bare to dimensjoner

Dersom stangen er delt inn 1 2 1 2

så er jo det like mye masse på høyre og venstre side om balansepunktet/tungdepunktet ligger i (0,2) ?

EDI: Jeg er *****la dum

alt gir mening nå
Er vel noe med hvordan du vekter de forskjellige verdiene i vektoren din.

@espen180: å benytte innebygde funksjoner betyr ikke automatisk at det går raskere (uten at jeg skal påstå at det ikke gjør det i dette tilfellet). For å teste virkelig hastighet i MATLAB burde man også summere kjøretid over N kall og dele totalen på N da en MATLAB funksjon ofte vil være raskere etter å ha blitt kjørt noen ganger pga JIT.
Nebuchadnezzar
Fibonacci
Fibonacci
Posts: 5648
Joined: 24/05-2009 14:16
Location: NTNU

Okai, dette blir litt på siden ^^

Hvis jeg ønsker å finne ut om den innebygde funksjonen for å finne primtall

isPrime

er raskere enn min kode

Code: Select all

function Y = Primtall(a)
if a<2
    Y=0;
    return
else
    for i=2:(floor(sqrt(a)))
        if a/i==round(a/i)
            Y=0;
             return
        end
    end
end
Y = 1;
end
Hvordan går jeg da frem?
"Å vite hva man ikke vet er og en slags allvitenhet" - Piet Hein
https://s.ntnu.no/Integralkokeboken
Lektor - Matematikk, Fysikk og Informatikk
drgz
Fermat
Fermat
Posts: 757
Joined: 24/12-2008 23:22

Din kode er garantert ikke raskere, det kan jeg si med en gang.

Men det du gjør er:

Code: Select all

N = 1000; % feks
p = et eller annet stort tall

tic;
for k = 1:N
    isp =isprime(p);
end
avgtime = toc/N


tic;
for k = 1:N
    isp = Primtall(p);
end
avgtime = toc/N
espen180
Gauss
Gauss
Posts: 2578
Joined: 03/03-2008 15:07
Location: Trondheim

claudeShannon wrote:@espen180: å benytte innebygde funksjoner betyr ikke automatisk at det går raskere (uten at jeg skal påstå at det ikke gjør det i dette tilfellet). For å teste virkelig hastighet i MATLAB burde man også summere kjøretid over N kall og dele totalen på N da en MATLAB funksjon ofte vil være raskere etter å ha blitt kjørt noen ganger pga JIT.
Jeg er klar over dette, og jeg kjørte faktisk funksjonene flere ganger for å få en gjennomsnittlig kjøretid. Hvor mange manger må funksjonen i så fall kjøres for å få en pålitelig måling? Jeg merket at første gang tok det ca 0.1 sekunder å kjøre begge to, men nebus stabiliserte seg fort på 35-56 mikrosekunder og min på 16-23 mikrosekunder.

Jeg påstår ikke at bruk av innebygde funksjoner nødvendigvis er raskere, men det er etter hva jeg har lest ofte tilfellet.

For å måle kjøretid kan man bruke kommandoene tic og toc. MATLAB tar tiden fra tic blir kalt til toc blir kalt og viser resultatet i kommandovinduet.
drgz
Fermat
Fermat
Posts: 757
Joined: 24/12-2008 23:22

espen180 wrote: Jeg er klar over dette, og jeg kjørte faktisk funksjonene flere ganger for å få en gjennomsnittlig kjøretid. Hvor mange manger må funksjonen i så fall kjøres for å få en pålitelig måling? Jeg merket at første gang tok det ca 0.1 sekunder å kjøre begge to, men nebus stabiliserte seg fort på 35-56 mikrosekunder og min på 16-23 mikrosekunder.
Antall repetisjoner avhenger nok litt av kompleksiteten til koden. F.eks eksempelet i denne tråden vil det nok kreve mange repetisjoner pga det er knapt nok kode som kjøres. Eventuelt kan man jo bytte ut antall iterasjoner med større datamengder sent inn i funksjonen og se hvordan det påvirker resultatet.
espen180 wrote: Jeg påstår ikke at bruk av innebygde funksjoner nødvendigvis er raskere, men det er etter hva jeg har lest ofte tilfellet.
Innebygde funksjoner er som regel raskest hvis det er blant de funksjonene som er kompilerte (samt ikke har for mange sjekker). svd(), qr(), osv er kompilerte funksjoner som baserer seg på LAPACK/BLAS direkte, mens andre innebygde funksjoner vil kanskje gå veien om mye rart før de til slutt havner nede på LAPACK/BLAS nivå, ergo mer tidkrevende.

Men det viktigste er jo at du er klar over det, og det er du tydeligvis, så da er alt bra (også ang. beregning av kjøretid). :)
Nebuchadnezzar
Fibonacci
Fibonacci
Posts: 5648
Joined: 24/05-2009 14:16
Location: NTNU

Espen, nå ville ikke den koden din kjøre... =(

Fikk feilmeldingen

---------------------------

massepunkt([1 1 1 1])

??? Attempted to access m(0); index must be a positive integer or logical.

Error in ==> Massepunkt2 at 5
while m(i) < M/2

---------------------------

Med koden

................................

function mpkt = massepunkt(a)
M=sum(a);
m=cumsum(a);
i=0;
while m(i) < M/2
i=i+1;
end
mpkt=i;
end

.................................

Prøvde jo å forandre i, men da ble alt feil
"Å vite hva man ikke vet er og en slags allvitenhet" - Piet Hein
https://s.ntnu.no/Integralkokeboken
Lektor - Matematikk, Fysikk og Informatikk
drgz
Fermat
Fermat
Posts: 757
Joined: 24/12-2008 23:22

Du kan vel sette i = 1 før du starter while-løkken?

Ang. Primtall-funksjonen din kan du heller teste:

Code: Select all

function y = Primtall(n)
if n == 1
    y = 0;
    return;
elseif n < 4
    y = 1;
    return;
elseif mod(n,2) == 0
    y = 0;
    return;
elseif n < 9
    y = 1;
    return;
elseif mod(n,3) == 0
    y = 0;
    return;
else
    r = floor(sqrt(n));
    f = 5;
    while f <= r
        if mod(n,f) == 0
            y = 0;
            return;
        end
        if mod(n,f+2) == 0
            y = 0;
            return;
        end
        f = f+6;
     end
    y = 1;
end 
(med forbehold om småfeil). Den er nok raskere enn din, men om den slår MATLAB sin innebygde vet jeg ikke.
Last edited by drgz on 24/10-2011 17:00, edited 2 times in total.
Nebuchadnezzar
Fibonacci
Fibonacci
Posts: 5648
Joined: 24/05-2009 14:16
Location: NTNU

Var jo det jeg skrev at jeg forandret, da gir den meg feil svar..
Massepunkt([1 2 8 1])

ans =

3
"Å vite hva man ikke vet er og en slags allvitenhet" - Piet Hein
https://s.ntnu.no/Integralkokeboken
Lektor - Matematikk, Fysikk og Informatikk
espen180
Gauss
Gauss
Posts: 2578
Joined: 03/03-2008 15:07
Location: Trondheim

Funksjonen må jo gi igjen et heltall, ellers kan du ikke bruke resultatet til noe. Min kode finner den første indeksen der den kulmulerte summen av vektoren er lik eller større enn halvparten av hele summen. Ergo kan funksjonen gi tilbake en verdi litt større enn forventet, men aldri mindre. Poenget er at den gir igjen et heltall som kan brukes i videre manipulasjoner av vektoren. I så måte er din kode bedre siden du kan bruke round() til å gjøre et bedre estimat, men det er mer tidkrevende og resultatene vil nærme seg for lange vektorer.
Post Reply