standardavvikelse
Hej,
Jag behöver returnera standardavvikelsen av en vektor med olika mätvärden.
Försöker med:
public double stdDev() {
double sd = 0;
for (int n=1; n<x.length; n++)
{
sd = sd + Math.pow(x[n] - mean(), 2)/n;
}
double stdDev = Math.sqrt(sd);
return stdDev;
}
Där jag redan har gjort en fungerande metod för mean och för att skapa en vektor. Detta ger helt fel värde. Kan någon hjälpa mig till rätta?
//Roger
Kan inte Java själv, men det ser ut som om du delar varje term du lägger till sd med n, som väl är räknaren i loopen?
dobedidoo skrev :Kan inte Java själv, men det ser ut som om du delar varje term du lägger till sd med n, som väl är räknaren i loopen?
Kan tänka mig att du ska ta bort det och istället göra double stdDev = Math.sqrt(sd/x.length);
Var kommer x[] ifrån?
PeterÅ skrev :Var kommer x[] ifrån?
Det är såklart också en relevant fråga!
Antar man att x[] faktiskt är definierad, då får man bestämma sig för om man vill dela med x.length eller, vilket är fallet ibland, x.length - 1. Beror på tillämpningen.
Tror det ska se ut så här:
public double stdDev()
{
double sd = 0;
double meanValue = mean(x); // där mean() beräknar medelvärdet
for (int n=1; n<x.length; n++) // förutsatt att x[] index är 1-baserad, annars int n=0; n<x.length-1
{
sd = sd + (x[n] - meanValue) * (x[n] - meanValue);
}
double stdDev = Math.sqrt(sd / x.length);
return stdDev;
}
x ska säkert vara argument till stdDev.
Japp, men x kan även vara globalt definierad: double x[];
dobedidoo skrev :PeterÅ skrev :Var kommer x[] ifrån?
Det är såklart också en relevant fråga!
Antar man att x[] faktiskt är definierad, då får man bestämma sig för om man vill dela med x.length eller, vilket är fallet ibland, x.length - 1. Beror på tillämpningen.
Ja, den är definierad, som instansvariabel i klassen: private double [] x ; .
dobedidoo
Tack
Har provat så som du skrivit. Med sd/x.length men det ger fel värde.
PeterÅ
Tack
Det där ser ut att kunna fungera. Är det någon särskild mening man skriver ut (x[n] - meanValue) * (x[n] - meanValue) som en produkt istället för att använda sig av en exponent?
Tyvär får jag nu felmeddelande: mean() in Measurements cannot be applied to (double[])
Fast metoden mean() returnerar en double...
Det är denna rad som ger kompileringsfel: double meanValue = mean(x); // där mean() beräknar medelvärdet
Anledningen är att det är tydligare och det är lättare att felsöka. Dessutom tror jag att multiplikation av två tal är effektivare (snabbare) än Math.Pow().
Visa mig definitionen på mean() och ditt anrop dit med x som argument.
PeterÅ skrev :Tror det ska se ut så här:
public double stdDev()
{
double sd = 0;
double meanValue = mean(x); // där mean() beräknar medelvärdet
for (int n=1; n<x.length; n++) // förutsatt att x[] index är 1-baserad, annars int n=0; n<x.length-1
{
sd = sd + (x[n] - meanValue) * (x[n] - meanValue);
}
double stdDev = Math.sqrt(sd / x.length);
return stdDev;
}
Angående for-loopen: Borde det inte vara antingen
for (int n=1; n<=x.length; n++) // om x[] är 1-baserad (dvs. <= i.st.f. bara <)
eller
for (int n=0; n<x.length; n++) // om x[] är 0-baserad (dvs. bara <)
?
PeterÅ skrev :Anledningen är att det är tydligare och det är lättare att felsöka. Dessutom tror jag att multiplikation av två tal är effektivare (snabbare) än Math.Pow().
Visa mig definitionen på mean() och ditt anrop dit med x som argument.
Jag förstår :)
public double mean() {
double sum = 0;
int i = 0;
for (i=0; i<x.length; i++) {
sum+=x[i];
}
return sum/counter;
}
Roger Moore skrev :dobedidoo
Tack
Har provat så som du skrivit. Med sd/x.length men det ger fel värde.Kanske summeringen i for-loopen blir för "kort" (enligt min förra post) och/eller så ska det delas med x.length - 1 (finns två varianter av standardavvikelsen, och vilken som är "bäst" beror på tillämpning).
Det ska vara
return sum/x.length;
En sak till:
Array Index i Java startar från 0. Därför ska dina loopar se ut så här när de hanterar x[]
for (i = 0; i < x.length; i++) Loopen startar med 0 och stannar när i = 9. Antal = 10
Med 1-baserad index blir det istället (ex. vis. Visual Basic)
for (i = 1; i <= x.length; i++) Loopen startar med 1 och stannar när i = 10. Antal = 10
Om du har 10 tal i x har de index 0-9 (=10 st) ELLER 1-10. Det är viktigt att du har koll på detta för du får ett sk. run time error om du använder ett indexvärde för x som inte finns.
dobedidoo: Har provat båda varianterna :/
PeterÅ: La nyss märke till det! Jag har ändrat fram och tillbaka en stund nu och det är därför det såg tokigt ut. Har för övrigt ändrat till sum/x.length men det löser inte kompileringsfelet :/
Aha! Du har ju x som klassmedlem. Ändra
double meanValue = mean(x);
till
double meanValue = mean();
Observera också att du måste ändra i funktionen public double stdDev()
från:
for (int n = 1; n < x.length; n++)
till:
for (int n = 0; n < x.length; n++)
PeterÅ skrev :Aha! Du har ju x som klassmedlem. Ändra
double meanValue = mean(x);
till
double meanValue = mean();
Tack för alla svar!
Jo PeterÅ men när jag gjorde sådär så fick jag samma värde som jag fick i början (när jag inte använde for (i=0...) och inte (i=1...) naturligtvis).
Jag har nu äntligen lyckats få fram korrekt svar men det lite underliga är att jag gjorde det genom att byta ut alla x.length mot counter (även i mean()-metoden).
Jag undrar varför det inte gick med x.length? Jag har en interaktionsruta där jag kan testa och skapa objekt osv. Om jag skapar en vektor m och sedan skriver m.length; så fungerar inte det heller. Varför?
Roger Moore skrev :PeterÅ skrev :Aha! Du har ju x som klassmedlem. Ändra
double meanValue = mean(x);
till
double meanValue = mean();Tack för alla svar!
Jo PeterÅ men när jag gjorde sådär så fick jag samma värde som jag fick i början (när jag inte använde for (i=0...) och inte (i=1...) naturligtvis).
Jag har nu äntligen lyckats få fram korrekt svar men det lite underliga är att jag gjorde det genom att byta ut alla x.length mot counter (även i mean()-metoden).
Jag undrar varför det inte gick med x.length? Jag har en interaktionsruta där jag kan testa och skapa objekt osv. Om jag skapar en vektor m och sedan skriver m.length; så fungerar inte det heller. Varför?
Tror jag vet varför... Jag har en metod som ökar storleken på vektorn när jag matat in för många värden. Men jag vill ju bara använda mig av de värden jag matat in, alltså är längden length för lång. Vad dum jag känner mig -_-
Utmärkt att du själv hittade felet. Rent generellt tror jag du ska minska på globala (klass)-variabler.
Framförallt ska funktionerna ha argument istället för som du gör nu. Ett bra exempel är mean().
Skriv om den funktionen för att ta en variabel som argument:
double mean(double d)
Fördelen är att den kan användas rent generellt och inte bara för din x[] samt att felsökning i alla fall inte blir svårare.
PeterÅ skrev :Utmärkt att du själv hittade felet. Rent generellt tror jag du ska minska på globala (klass)-variabler.
Framförallt ska funktionerna ha argument istället för som du gör nu. Ett bra exempel är mean().
Skriv om den funktionen för att ta en variabel som argument:
double mean(double d)
Fördelen är att den kan användas rent generellt och inte bara för din x[] samt att felsökning i alla fall inte blir svårare.
Tack för tipset! Ska ändra på det! :)