Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Rätselecke » ca. 15. Windalfrästel

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
18.10.2003, 13:55 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


zu schreiben ist folgende funktion die eine lineare regression durchführt und die paramter für eine gerade der form y=a*x+b ermittelt

C++:
template <class Typ>
void linearRegression(double &a,double &b,Typ* x, Typ* y,int n);


--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
18.10.2003, 17:28 Uhr
(un)wissender
Niveauwart


Äh, was ist eine lineare Regression?
Du kannst Typ auch per Referenz übergeben, ist schöner, du alter C-Coder!
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
18.10.2003, 17:42 Uhr
(un)wissender
Niveauwart


Habe google bemüht und beschlossen nicht am Rätsel teilzunehmen, wenn der Moderator mir nicht erweiterte Infos bzw. Hinweise zukommen läßt.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
18.10.2003, 18:07 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


@unwissender
lernt ihr Informatiker kein Statistik? Bin ja ganz überrascht das ich das noch erklären muss ich dachte ihr würdet euch bei dem rätsel eher zu tode langeweilen und schmeist mir innerhalb von 5 minuten eine lösung an den kopf deshalb gabs keine weiteren erklärungen dazu

ja kannst du auch per referenz machen allerdings frist der das dann nicht mehr
sparen tust du dabei ja auch meines wissen nur die kopie des pointers aufm stack

C++:
int x_werte[10]={0,2,3,4,5,6,7,8,9,10};
int y_werte[10]={1,2,3,4,5,6,7,8,9,10};
double a,b;
linearRegression(a,b,x_werte,y_werte,10);



ok also bei einer regression übergibst du quasi eine punktwolke und versucht in diese eine funktion reinzupacken,so das der abstand von allen punkten zur funktion minimal wird.
Am ende gibt es dann auch noch ein mass mit dem man sich quasi angucken kann wie gut die funktion passt. (um ggf. zu versuchen lieber ne andere funktion reinzupacken)

Bei der Aufgabe sollst du für ne übergebene Punktwolke die Parameter der Gerade ermitteln.
Eine Gerad hat immer die Formel f(x) =a*x+b
Zu ermitteln sind dann die beiden parameter a und b.

so und nun zu rechnung
a= Summe ((xi-x_quer)*(yi-y_quer))/(Summe((xi-x_quer)*(xi-x_quer))

b=y_quer-a*x_quer

x_quer und y_quer sind jeweils das arithmetische mittel also die Summe der x- bzw y-werte durch die anzahl

wenn du dir den spass am ende mal angucken willst kann man das bestimm ganz schön mit excel oder gnuplot mal plotten was der so ausgerechnet hat.

so hoffe jetzt ist alles klar
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 18.10.2003 um 18:09 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
18.10.2003, 18:28 Uhr
(un)wissender
Niveauwart


Bei Referenzübergabe sparst du gar nicht, sieht nur cooler aus!
Naja und man muss nicht auf null testen, man spart also eine if()-Abfrage, da das aber nur Weicheier und Javaprogrammierer machen (wenn sie denn Pointer hätten) kann man es also auch vergessen.

Was glaubst du eigentlich, was für ein Matheheld ich bin, schließlich sind die Informatiker auch nicht mehr das, was sie mal waren.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
18.10.2003, 18:31 Uhr
(un)wissender
Niveauwart


Das heißt ich soll dir a,b ausrechnen, damit du die Gerade cool ziehen kannst, ok, das richtig ja böse nach quadrieren in Masse.
Ich verspreche nichts, habe wenig Zeit, mal schaun.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
18.10.2003, 20:19 Uhr
(un)wissender
Niveauwart


So, habe was fertig gemacht, funktioniert mit meinen gestellten Werten ganz toll.
(Sicherlich noch ausbaufähig, aber mir fehlt die Motivation, alles zu testen und ggf. zu korrigieren)


C++:
#include <iostream>
#include <cmath>
using namespace std;

template<typename T> class Point {
    private:
        T x;
        T y;
    public:        
        Point() : x(0), y(0) {}
        Point(T &x_, T &y_) : x(x_), y(y_) {}
        const T& getX() const { return x; }
        const T& getY() const { return y; }
        
        Point<T> & setValues(T &x_, T &y_)
        { x = x_; y = y_; return *this; }
        
        Point<T> & operator+=(const Point<T> &point)
        { x += point.x; y += point.y; return *this; }
        
        Point<T> & operator/=(const T &div)
        { x /= div; y /= div; return *this; }    
};

template<class T>
void linearRegression(double &a,
                      double &b,
                      T *x_coords,  
                      T *y_coords,
                      int coords_length)
{
    int half_coords_length = coords_length / 2;                  
    Point<T>workerPoint;
    
    //Die erste Hälfte der Punkte sammeln und durch ihre
    //Anzahl teilen (x- und y-Koordinate),
    //um einen mittleren x- bzw. Y-Wert zu bekommen.
    Point<T> first_avg_point;
    for(unsigned int i = 0; i < half_coords_length; ++i)
        first_avg_point += workerPoint.setValues(*x_coords++, *y_coords++);        
    first_avg_point /= half_coords_length;
    
    //Die zweite Hälfte der Punkte sammeln und durch ihre
    //Anzahl teilen (x- und y-Koordinate),
    //um einen mittleren x- bzw. Y-Wert zu bekommen.
    Point<T> second_avg_point;  
    for(unsigned int i = half_coords_length; i < coords_length; ++i)
        second_avg_point += workerPoint.setValues(*x_coords++, *y_coords++);    
    second_avg_point /= coords_length - half_coords_length;
      
    T deltaY = abs(first_avg_point.getY() - second_avg_point.getY());  
    T deltaX = abs(first_avg_point.getX() - second_avg_point.getX());
    
    a = deltaY / deltaX; //Steigung berechnet;    
    //y = mx + b ungestellen in b = -(mx) + y;
    b = -(a * second_avg_point.getX()) + second_avg_point.getY(); //b berechnen;  
}

int main()
{
    double m;
    double b;
    double x_coors[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
    double y_coors[] = {3.0, 2.0, 1.0, 6.0, 5.0, 4.0};
    linearRegression(m, b, x_coors, y_coors, sizeof(x_coors) / sizeof(double));
    cout << "Ermittelte Steigung: "   << m
         << "\nY-Abstand bei x=0:   " << b;    
    return 0;
}



--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
18.10.2003, 20:26 Uhr
(un)wissender
Niveauwart


Da sind echt noch nicht genug Posts von mir!
Also, ist natürlich eine naive Version, viel mehr ist von mir nicht zu erwarten, habe in Mathe nicht soooo gut aufgepasst.

Wenn das so stimmt dann hätte ich deine Hilfe auch nicht gebraucht, allerdings ist rumjammern immer gut, vielleicht bekommt man ja was!
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
18.10.2003, 21:38 Uhr
(un)wissender
Niveauwart


Was man noch tun könnte:
-Punkte sortieren
-Prüfen, ob Punkte stark abweichen
-Prüfen, ob Geradenzeichnung sinnvoll ist(bei einem Kreis von Punkten kannste Zeichnen was du willst).
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
19.10.2003, 13:32 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


ähm..... schön
ist ein bisschen kompliziert, so eine Hardcorelösung wollte ich gar nicht haben

meine ist so


C++:
template <class Typ>
void linearRegression(double &a,double &b,Typ* x, Typ* y,int n){
    int i;
    double x_quer,y_quer,oben,unten;
    x_quer=y_quer=oben=unten=0;
    for(i=0;i<n;++i){x_quer+=x[i];y_quer+=y[i];}
    x_quer/=n;y_quer/=n;
    for(i=0;i<n;++i){oben+=(x[i]-x_quer)*(y[i]-y_quer);unten+=(x[i]-x_quer)*(x[i]-x_quer);}
    a=oben/unten;
    b=y_quer-a*x_quer;
}




also problem bei deiner Lösung ist zum einen das du irgendwie was anderes rechnest als ich

dann verwendest du den Typ weiter, wenn man z.b. integers nimmt dann bekommt man rundungsfehler beim teilen, man sollte also schon gleich doubles verwenden wenn man die mittelwerte errechnet.
an sonsten kann ich nur sagen das du mir was templates angeht noch ein gutes stück voraus bist

Ich versuch mal nachher deine Lösung so zu ändern das das was ich meinte rauskommt
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 19.10.2003 um 13:43 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ Rätselecke ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: