Datenpunkte glätten ( Funktionen gesucht )



  • Hallo zusammen,

    ich könnte eure Expertise benötigen. Es geht daraum Datenpunkte zu fitten / smoothen (siehe Anhang). Allgemein habe ich mehrere Hundert dieser Kurven, die es gilt in der numerisch instabilen Zone (grün eingekastelt) in einer Art zu glätten wie beispielsweise in Blau dargestellt. Selber hab ich ein Smoothing-Iterator entworfen, der mir die Datenpunkte glättet, aber dieses Rauschen bkeomm ich da nicht weg. Ich habe versucht mittels GSL und einer B-Spline Funktion die Daten zu fitten, allerdings funktioniert das nicht mit meinen Daten 😕 (bekomm immer irgenwelche Fehler von der Lib und ein offizielles Forum gibt es ja anscheinend nicht).

    Die Frage an euch. Wisst ihr irgendwelche Funktionen / Libs, die solch ein Problem händeln können. Quasi den Datensatz übernehmen und dann eine geglättete Kurve ausgeben? Ansonten versuch ich nur den Start und Endpunkt des Rauschens zu finden und setzt ne lineare Linie rein (was aber auch nicht so schön wäre).

    Wär euch sehr über Informationen dankbar (häng an dem Problem schon länger).

    Grüße Tobi

    Bild hier: http://holzmann-cfd.de/cppForum/C++Problem.png



  • Weißt du irgendwas über den funktionalen Zusammenhang? Wenn ja, könntest du die Funktion anfitten. Wenn nicht, dann finde ich es schwieriger. Ich würde es vermutlich mit TSplinePoly3 versuchen und mal schauen, wie das Ergebnis aussieht. Aber dein gemalter Fit geht ja doch schon ordentlich an den einzelnen Punkten vorbei. Vielleicht erreicht man das, indem man vorher mal rebinnt (also mehrere Punkte zu einen zusammenfasst) und dann den Spline macht?



  • So wie deine Grafik aussieht, musst du alle Werte die eine große Streuung haben, wegwerfen und die beiden Kurven dann mit einem Spline verbinden.



  • Hi,

    ich hab leider keine funktionalen Zusammenhänge. Zuerst geht es darum dieses Rauschen rauszufiltern, damit ich alle Kurven ohne dieses Rauschen habe. Die Kurven stellen zusammen letztlich eine 3D Fläche dar, die ich dann fitten werde.

    Ich hab mir auch gedacht, dass ich den ersten und letzten Punkt des Rauschens suche, dort die Ableitung berechne und dann einfach eine Parabel reinsetzt, mit der Kondition, dass die Steigungen gleich sein müssen. Allerdings bin ich mir noch nicht so sicher wei ich diese Punkte herausfinde finde.

    Der Fit (meine eingezeichnete Kurve) war nur schematisch. Auf die 100%ige Genauigkeit kommt es vorab noch nicht an aber ich benötige eine halbwegs stetige Kurve. Die Zusammenlegung mehrerer Punkte ist in meinem Programm schon enthalten. Allerdings würde ich das eben auch nur auf das Rauschen anwenden wollen und das setzt die Kenntniss der Start und Endpunkte voraus, die bei jedem Datensatz anders sind.

    Danke schonmal für die Funktionsnennung. Ich schau mir das mal an.



  • DirkB schrieb:

    So wie deine Grafik aussieht, musst du alle Werte die eine große Streuung haben, wegwerfen und die beiden Kurven dann mit einem Spline verbinden.

    Guter Ansatz. Wie würdest du die Auswertung der Punkte mit einer großen Streuung analysieren?



  • Nach der Anmerkung von Dirk hab ich nun folgendes implementiert. Eine Funktionsanalyse mit einem Sigma, dass mir die Bereiche des Rauschen demonstrieren soll (siehe Anhang). Umgesetzt hab ichs (ganz simple gerade) mit:

    void AOPC::fluctuationAnalyze
    (
        List<List<scalar> > & data
    )
    {
        Info<< "    ++ Noisy will be analyzed\n";
    
        List<scalar> sigmaField(data.size(), 0);
    
        forEach(data, i)
        {
            const scalar& TYS = data[i][2] / 1000000;
            const scalar sigma = 0.05 * TYS;
    
            sigmaField[i] = 1/(pow(sigma, 2));
    
            if (i==0)
            {
                Info<< data[i][1] << "\t" << 0 << endl;
            }
            if (i> 0)
            {
                Info<< data[i][1] << "\t" << sigmaField[i-1] - sigmaField[i] << endl;
            }
        }
    }
    

    Damit kann ich dann schon mal was anfangen. Sigma ist im Plot auch gezeigt. Wenn ich die Kurve vorher noch etwas smoothe dann wird das noch wesentlich schöner und ich kann das Rauschen rauswerfen. Bleibt nur noch die Ersetzung mit einer Spline.

    Danke soweit schon mal (:
    @wob... hab gesehen, dass ich roots dafür brauche. Hab die Woche leider keine Zeit mehr und sollte das mit der Spline funktionieren, dann übernehm ich das erstmal. Ansonsten werde ich mir die Funktion mal genauer anschauen.

    Zum Bild: http://holzmann-cfd.de/cppForum/sigma.png



  • Du hast, wenn ich mir das erste Bild anschaue, ja zwei Effekte
    1. Rauschen
    2. Einen (gemessenen ?) Kurvenverlauf, der nicht der von Dir eingezeichneten Ideallinie entspricht.

    Das Rauschen kannst Du mit einem Tiefpassfilter (gauss oder rechteck, ausprobieren) oder einer Kalmanfilterung einigermassen weg bekommen. Dann bleibt der nicht dem geüwnschten/erwarteten Kurvenverlauf entsprechende Teil. Da stellt sich mir aber die Frage, wir denn die vielen anderen Kurven aussehen?



  • DirkB schrieb:

    So wie deine Grafik aussieht, musst du alle Werte die eine große Streuung haben, wegwerfen und die beiden Kurven dann mit einem Spline verbinden.

    Hi Dirk,

    ich hab das jetzt so umgesetz wie du das gesagt hast. Ich hab die Streuungswerte nun weg geschnitten und hab nun zwei Kurven die ich mit einer Spline verbinden möchte. Hast du mir Referenzen, wo ich nachsehen kann wie ich das umsetzen könnte?



  • Hallo zusammen,

    ich hab nun die SPline durch ein Polynom 3ten Grades angenähert, da ich die Anfangs und Endpunkte kenne und damit auch die Steigung. Sieht schon sehr gut aus allerdings ist die Filterung (was rauszuschneiden ist) recht bescheiden.

    Hab ihr Referenzen bezüglich Tiefpassfilter etc. oder schwebt euch eine andere Idee vor, diesen Bereich (Anfangs- und Endpunkt) zu erkennen?


Anmelden zum Antworten