Ausgleichsgerade
-
Hallo Community,
ich will eine Regressionsgerade berechnen. Ich habe ca. 800 Stützstellen.
Gibt es ein mathematisches Verfahren, dass als Input den Stützstellenvektor hat und als diekten Output die Geradengleichung in der Hesseschen Normalform?Ich kenne ein Regressionverfahren, dass eine Gerade in der Form als Output hat:
y = m*x + bAußerdem ein Verfahren, dass
A*x + B*y = 1
als Output hat.Beide Geradengleichungen sind ungeeignet, da meine Gerade sowohl parallel zur Y-Achse als auch durch den Koordinatenursprung verlaufen kann.
Ich brauche daher diese Darstellung:
x * cos (alpha) + y * sin(alpha) - p = 0
wobei alpha und p meine Unbekannten sind.Wie könnte man da vorgehen?
Gruß,
Paul
-
Der_Paul schrieb:
Außerdem ein Verfahren, dass
A*x + B*y = 1
als Output hat.Beide Geradengleichungen sind ungeeignet, da meine Gerade sowohl parallel zur Y-Achse als auch durch den Koordinatenursprung verlaufen kann.
A=0, B!=0 -> parallel zur x-achse
A!=0, B=0 -> parallel zur y-achseIch brauche daher diese Darstellung:
x * cos (alpha) + y * sin(alpha) - p = 0
wobei alpha und p meine Unbekannten sind.Wie könnte man da vorgehen?
teile deine zweite gleichung durch sqrt( a^2 + b^2)
-
Versteh ich nicht so ganz:
(A*x + B*y) / (sqrt( a^2 + b^2)) = 1 / (sqrt( a^2 + b^2))was soll das bringen?
Mein Problem ist, dass A und B ungenau werden, wenn A und B gegen 0 gehen
(also die Gerade durch den Ursprung verläuft).Ich teile die Darstellung einer ungenauen Regressionsgerade durch die Wurzel der quadrierten Summen der Koeffizienten.... und dann? Hä?
Dann sind A und B aufeinmal exakt oder wie?Ich brauch eher sowas:
gegeben sind 3 Stützstellen:
x / y
10 / 20
11 / 21
12 / 22=> GLS
10 * cos (alpha) + 20 * sin (alpha) - p = 0 11 * cos (alpha) + 21 * sin (alpha) - p = 0 12 * cos (alpha) + 22 * sin (alpha) - p = 0
cos(alpha), sin(alpha), p könnte man durch X, Y, Z substituieren...
=>
GLS | 10 20 -1 | | X | | 0 | | 11 21 -1 | * | Y | = | 0 | | 12 22 -1 | | Z | | 0 |
Allerdings sind X und Y nicht unabhängig voneinander. Es gilt ja X+Y = 1
Kann man das GLS trotzdem lösen?
-
Der_Paul schrieb:
gegeben sind 3 Stützstellen:
x / y
10 / 20
11 / 21
12 / 22=> GLS
10 * cos (alpha) + 20 * sin (alpha) - p = 0 11 * cos (alpha) + 21 * sin (alpha) - p = 0 12 * cos (alpha) + 22 * sin (alpha) - p = 0
im allg. ist so ein Gls. nicht lösbar, deswegen solltest du die Methode
der kleinsten Quadrate wählen also aus Ax=b wird (A^T A)x=A^T bda alpha ein nichtlinearer parameter ist, kannst du es eh nicht direkt
mittels gauss lösen wenn du keine geeignete substitution findest.
am besten das gauss-newton verfahren verwenden.edit: eine möglichkeit den parameter alpha zu linearisieren wäre
cos(alpha) durch 'a' und sin(alpha) durch 'b' ersetzen
dann mit der oben genannten methode lösen und rücksubstituieren (macht dann natürlich nur bei mehr als 3 stützstellen sinn)
-
Locust schrieb:
im allg. ist so ein Gls. nicht lösbar, deswegen solltest du die Methode der kleinsten Quadrate wählen also aus Ax=b wird (A^T A)x=A^T b
Ich würde dir eigentlich davon abraten, das Problem mit den Normalengleichungen zu lösen. Es gibt bessere Methoden wie QR-Zerlegung oder SVD. Obwohl diese Methode natürlich auch funktioniert.
Zu deiner Form: Du möchtest x * cos (alpha) + y * sin(alpha) - p = 0, aber du hast A x + B y = 1. Du kannst also die Koeffizienten vergleichen:
A=cos(alpha)/p, B=sin(alpha)/p
Durcheinander dividieren ==> tan(alpha)=sin(alpha)/cos(alpha)=B/A.
So ähnlich kannst du auch p berechnen (Hoffentlich habe ich mich bei alpha nicht verrechnet ). Es ist also nur eine Umformung zwischen den beiden Geradendarstellungen, dafür brauchst du keinen anderen Algorithmus.
-
Wieso machst du nicht eine Fallunterscheidung? Fitte y=m*x+b und x=n*y+c und schaue hinterher, was besser passt (wo m oder n eben nicht gegen unendlich gehen).
-
Hallo Community,
ich bräuchte da auch Hilfe bei dem selbigen Thema.
hier mein Code, welchen ich kompiliert kriege aber trotzdem nicht funktioniert:
#include <stdio.h>
int const n=9;
float eingabe() {
int i;
float x[10];
float y[10];
for(i=1;i<=10;i++) {
printf("Geben Sie den %iten Wert für X ein: ", i);
scanf("%lf", &x[i]);
printf("Geben Sie den %iten Wert für Y ein: ", i);
scanf("%lf", &y[i]);
}
return x[i],y[i];
}float sum(float x[], int n) { /Summe/
float s=0;
int i;
for(i=0;i<n;i++) {
s+=x[i];
}
return s;
}float prosum(float x[], float y[], int n) { /Skalarprodukt/
float ps=0;
int i;
for(i=0;i<n;i++) {
ps+=x[i]*y[i];
}
return ps;
}int main() { /Hauptprogramm main/
int i, n;
float x[i], a, b, d;
float y[i];
for(i=0;i<n;i++) {
x[i]=i;
d=n*prosum(x,x,n)-sum(x,n)sum(x,n);
a=nprosum(x,y,n)-sum(x,n)*sum(y,n);
b=prosum(x,x,n)*sum(y,n)-sum(x,n)prosum(x,y,n);
}
if(d!=0) {
a=a/d;
b=b/d;
printf("\n\nAusgleichsgerade: y=%fx + %f",a,b);
}
else printf("\n\nd=0\n\n");
return 0;
}
-
@Slami sagte in Ausgleichsgerade:
nicht funktioniert:
Ist ja sehr ausführlich.
@Slami sagte in Ausgleichsgerade:
return x[i],y[i];
Was soll das machen? Es macht bestimmt etwas anders.
Du nimmst keinen Bezug auf die alte Frage. Warum gräbst du sie aus statt einen eigenen Thread aufzumachen?
Sieht auch eher so aus als hättest du Porbleme mit C.
-
Erstmal einen knapp 12 Jahre alten thread ausgraben, respekt!
-
@manni66
return x[i], y[i], soll mir die Felder, den Inhalt für das main zurückgeben. Ja, hab meine Schwierigkeiten mit Funktionen
@manni66 , @Cardiac und ja, ich nehme Bezug darauf, da es dasselbe Thema ist, wo meine Problematik sich bezieht.
-
@Slami sagte in Ausgleichsgerade:
@manni66
return x[i], y[i], soll mir die Felder, den Inhalt für das main zurückgeben. Ja, hab meine Schwierigkeiten mit Funktionen
Nein, mit C. x[i] ist kein "Feld". Die Fuktion kann genau ein float liefern.
int main() { /Hauptprogramm main/ int i, n; float x[i],
i ist nicht initialisiert. Was soll da wohl rauskommen. usw.
@manni66 , @Cardiac und ja, ich nehme Bezug darauf, da es dasselbe Thema ist, wo meine Problematik sich bezieht.
Nein, deine Problematik ist C.
-
@manni66
ah, dass heißt, eine Funktion kann nur einen float ausgeben. Das heißt dann im Umkehrschluss, dass ich für das zweite Array als float zum Ausgeben noch eine Funktion brauche. Wie soll man das alles wissen, wenn der Lehrer am 1. Tag des C++ Unterrichts das Tutorial in die Hand drückt und nur Aufgaben verteilt???
-
@Slami sagte in Ausgleichsgerade:
ah, dass heißt, eine Funktion kann nur einen float ausgeben.
Eine Funktion kann als Rückgabewert nur einen Wert haben. Muss aber nicht float sein.
Deine Funktion ist aber mit float deklariert.Das heißt dann im Umkehrschluss, dass ich für das zweite Array als float zum Ausgeben noch eine Funktion brauche.
Nein. Ein float und ein Array von float sind zwei Grundverschiedene Dinge (in C).
I.A. übergibt man in C ein Array an eine Funktion und diese befüllt es dann.Wie soll man das alles wissen, wenn der Lehrer am 1. Tag des C++ Unterrichts das Tutorial in die Hand drückt und
nur Aufgaben verteilt???Schwer.
Durcharbeiten, dabei auch andere Quellen benutzen. Bücher sind da sehr vorteilhaft.
Im übrigen ist das C und kein C++
-
@Slami sagte in Ausgleichsgerade:
am 1. Tag des C++ Unterrichts das Tutorial in die Hand drückt und nur Aufgaben verteilt
Tja, das ist doof. Wenn du für den Kurs bezahlst, verlange dein Geld zurück.
Besorge dir ein Buch. Das Forum wird nicht als Ersatzlehrer einspringen können und wollen.
-
ich brauche keinen Ersatzlehrer, nur eine Hilfestellung. Kriege ich jetzt auch alleine hin
Danke trotzdem
-
Wir können ja mal mit den Dingen anfangen, die richtig aussehen. Das wäre die Funktionen "sum" und "prosum"
Zu Problemen: fangen wir mal beim Hauptprogramm, also main, an:
int main() { // Hauptprogramm main int i, n; float x[i], a, b, d; float y[i];
In (hier) Zeile 3 definierst du 2 int-Variablen i und n. Beiden ist kein Wert explizit zugewiesen, also haben sie erstmal keinen bestimmten Wert. Außerdem überdeckt das n hier deine globale Konstante n, die du ganz oben im Programm definiert hast.
In Zeile 4 definierst du die drei float-Variablen a, b und d (wieder ohne Wert!) und das Feld x der Länge i. Aber i hat noch keinen Wert. Das kann so also nicht gehen.Ansonsten: bringe deinem Compiler oder deinem Editor bei, Warnungen anzuzeigen. Zum Beispiel solltest du bei dem
scanf
ineingabe
die Warnung bekommen:Format specifies type 'double *' but the argument has type 'float *' [-Wformat] Solution: Replace "%lf" with: "%f"
.Noch ein Tipp zum besseren Testen:
lass die Funktion "eingabe" erstmal weg und mache dir stattdessen 2 Testarrays:float x[] = {1,2,3,4}; float y[] = {3,5,7,9};
Wenn du diese verarbeitest, sollte wohl eine Gerade mit y=2*x+1 rauskommen. Wenn nicht, machst du was falsch. Dann brauchst du nicht immer Werte einzugeben, um dein Programm zu testen.
Ansonsten: werde dir über die Sprache klar (C oder C++) und besorge dir dann ein Buch. (für C++ wären empfehlenswert: Lippman: C++ Primer und Breymann: Der C++-Programmierer - für C (und das sieht hier nach C aus) kenne ich mich nicht mit guten Büchern aus)
-
@wob Danke