Datenbank Frequenz einer Kurve ermitteln?

Fragen zu allen Themen rund ums Programmieren außerhalb von phpBB können hier gestellt werden - auch zu anderen Programmiersprachen oder Software wie Webservern und Editoren.
Antworten
Benutzeravatar
bgx
Mitglied
Beiträge: 228
Registriert: 30.11.2005 22:32
Kontaktdaten:

Datenbank Frequenz einer Kurve ermitteln?

Beitrag von bgx »

Man war ich lange nicht mehr Online hier, aber man sollte es nicht meinen, ich hab ein Problem auf das ich noch keine zufriedenstellende Lösung gefunden habe.

Ich Sammele in einer Datenbank Temperaturwerte welche ähnlich einer Sinuskurve mehrfach am Tag nach oben und nach unten geht. Nun würde ich gern irgendwie die Anzahl also die Frequenz der Kurve bestimmen.

Als Ausgangsdaten folgende Tabelle:

Code: Alles auswählen

id  time  s1  s2  s3  s4  s5  s6  s7  s8  s9  
1453 2010-03-06 20:50:59 59.0625 -3.5625 19.75 25.375 72.0625 41.3125 8.0625 56.5 16 
1452 2010-03-06 20:50:01 59.0625 -3.5625 19.75 25.4375 74.125 41.3125 8 60.1875 17 
1451 2010-03-06 20:49:04 59.0625 -3.8125 19.75 25.4375 74.125 41.125 8 60.1875 18 
1450 2010-03-06 20:47:59 59.0625 -3.1875 19.75 25.5 75.875 41.125 8 62.25 18 
1449 2010-03-06 20:46:59 59.0625 -3.1875 19.6875 25.5 76.875 40.3125 8 62.6875 18 
1448 2010-03-06 20:45:59 59.125 -3.875 19.6875 25.625 76.875 40.3125 8 62.6875 18 
1447 2010-03-06 20:45:00 59.125 -3.75 19.75 25.6875 75.25 39.875 8 60.8125 18 
1446 2010-03-06 20:43:59 59.125 -3.75 19.75 25.6875 72.125 39.625 8 57.9375 18 
1445 2010-03-06 20:42:59 59.125 -3.6875 19.75 25.8125 72.125 39.625 8 57.9375 18 
1444 2010-03-06 20:41:59 59.125 -3.6875 19.75 25.875 68.9375 40.0625 8 55.25 18 
mit folgender Abfrage bekomm ich das ganze schon fast digitalisiert:

Code: Alles auswählen

SELECT TRUNCATE(`s5`,-1),`time` FROM `if_digitemp` WHERE `time` > DATE_ADD( CURDATE( ) , INTERVAL -1 DAY) AND `time` < CURDATE() ORDER BY `time` ASC
Ergibt folgende Ausgabe:

Code: Alles auswählen

TRUNCATE(`s5`,-1)  time  
50 2010-03-14 06:01:27 
50 2010-03-14 06:02:00 
60 2010-03-14 06:03:00 
60 2010-03-14 06:04:00 
60 2010-03-14 06:05:01 
60 2010-03-14 06:06:01 
60 2010-03-14 06:07:01 
60 2010-03-14 06:08:00 
70 2010-03-14 06:09:01 
70 2010-03-14 06:10:00 
70 2010-03-14 06:11:00 
70 2010-03-14 06:12:00 
70 2010-03-14 06:13:01 
Jetzt komm ich aber nicht mehr weiter irgendwie zu zählen wie oft der Wert hin und her pendelt?

Wie kann ich am besten vorgehen?
P7BB
Mitglied
Beiträge: 383
Registriert: 15.07.2008 19:40

Re: Datenbank Frequenz einer Kurve ermitteln?

Beitrag von P7BB »

Zählen wie oft das hin- und her pendelt?
sowas könnte man mit einfachen if-abfragen machen:
Für steigend definierst du $zuletzt = 1 (1 = steigend). Dann der nächste Wert. Größer oder kleiner? Wenn kleiner, dann hast du den ersten "umschwung" gefunden. $last auf 0 setzen, damit du danach prüfen kannst, ob die nächste temperatur kleiner oder größer sein muss, als die vorgängerzahl. wenn die kleiner ist, gibt es noch nicht den wechsel auf wieder steigend. Wenn es aber größer ist, geht der Graph ja wieder nach oben. So kannst du dann Schritt für Schritt auswerten, wie oft es zu Temperaturschwankungen kommt. Als Sinus-Funktion kann man sowas nur sehr sehr grob bezeichnen, weil es eben zu viele Abweichungen gibt, weshalb man somit auch nie auf eine Funktion kommen würde ;)
Benutzeravatar
gn#36
Ehrenadmin
Beiträge: 9313
Registriert: 01.10.2006 16:20
Wohnort: Ganz in der Nähe...
Kontaktdaten:

Re: Datenbank Frequenz einer Kurve ermitteln?

Beitrag von gn#36 »

Das beste Vorgehen hängt denke ich ein bisschen davon ab, wie viele Messwerte du hast. Prinzipiell kannst du bei einer reinen Sinuskurve ja die Frequenz auch einfach durch den Abstand der Messwerte bestimmen, das setzt aber vorraus, dass deine Samplingrate auch so hoch ist, dass du diese Maxima mitbekommst. In dem Fall könntest du die Daten des Tages einfach auslesen und dann lokale Maxima bestimmen, der durchschnittliche zeitliche Abstand ist das inverse der Frequenz.

Das kann aber relativ ungenau sein, vor allem wenn du viele unterschiedliche Frequenzen im Signal hast, dann müsstest du zumindest erst filtern um die gewünschte zu extrahieren.

Besser ist folgendes: Wenn du die Daten ansonsten im festen zeitlichen Abstand gemessen hast kannst du sie auch mittels einer diskreten Fouriertransformation in den Frequenzbereich transformieren, eine Hochpassfilterung vornehmen (schließlich interessiert dich nicht der Gleichanteil des Signals sondern die Schwingung) und schließlich das Maximum bestimmen. Aus dem Index des Maximums, der Anzahl der Samples und der verwendeten Samplingrate kannst du dann sehr leicht berechnen bei welcher Frequenz das Maximum liegt. Statt der Hochpassfilterung kannst du auch den Mittelwert aus dem Signal entfernen bevor du es transformierst.

Hier gibt es eine Funktion für die Schnelle Fouriertransformation. Die setzt zwar vorraus, dass die Anzahl der übergebenen Daten eine Potenz von zwei ist, aber du verfälscht das Ergebnis nicht wenn du einfach Nullen anhängst. Die Funktion erwartet allerdings Komplexe Zahlen als Input, das ist aber auch kein Problem, du kannst den Imaginärteil einfach zu null setzen.
Neben dieser Funktion brauchst du dann nur noch was das den Absolutbetrag korrekt bildet:

Code: Alles auswählen

function abs_imag($data)
{
if(!isset($data[0][0]))
{
//Falsches Format
return false;
}
$return = array();
foreach($data as $key => $entry)
{
$return[$key] = sqrt($entry[0] * $entry[0] + $entry[1] * $entry[1]);
}
return $return;
} 
Ich möchte das jetzt nicht groß weiter ausführen, aber die Fouriertransformation stellt für eine beliebige Funktion die Frequenzverteilung dar. Das lässt sich daher sehr gut nutzen um die Frequenzen zu bestimmen die in einem Signal enthalten sind. Ein reiner Sinus der ausreichend abgetastet wird produziert beispielsweise idealerweise einen einzigen Peak (bzw. zwei, einen bei der positiven, einen bei der negativen Frequenz). Bei deinem Signal wird das sicher kein einzelner Peak sein sondern du hast mit Sicherheit einen sehr großen Gleichanteil und auch einen etwas größeren Frequenzbereich in deinem Signal (schließlich schwanken die Temperaturwerte ja nicht um Null), aber trotzdem solltest du so die Frequenz mit dem größten Einfluss herausfinden können. Wenn du dir das Ergebnis einer FFT als Plot der Absolutwerte ansiehst dann ist beim Index 0 üblicherweise auch die Frequenz 0 (=Gleichanteil), beim Maximalwert der Indizes liegt dann deine Sampling Frequenz was durch die Eigenschaften der FFT wieder dem Gleichanteil entspricht. Beim halben Maximalwert liegt die maximal erkennbare Frequenz die der halben Sampling Frequenz entspricht.

Diese Methode sollte gegenüber Messrauschen auch relativ robust sein.
Begegnungen mit dem Chaos sind fast unvermeidlich, Aber nicht katastrophal, solange man den Durchblick behält.
Übertreiben sollte man's im Forum aber nicht mit dem Chaos, denn da sollen ja andere durchblicken und nicht nur man selbst.
Antworten

Zurück zu „Coding & Technik“