Diskretisieren von Messwerten (optimieren)
-
Hi,
ich habe mir folgendes Stückchen Code zurecht gebastelt um damit Messwerte in ein Feld zu sortieren.int diskret(double in, double min, double max, int slots) { //in Messwert //min, max Intervall //slots Maximaler Index if((in >= min) && (in < max)) { double b = (max - min) / (slots + 1); double tmp = in - min; tmp = tmp / b; return int(tmp); } else return -1; }Ich erhalte jetzt zu einem eingegebenen Wert den Feldindex.
Mich würde nun interessierem, ob man hier noch etwas mehr Geschwindigkeit rausholen kann und wie.
Danke
-
du könntest die Zwischenvariablen weglassen und die ganzen Zwischenschritte zu einer Rechnung zusammenfassen:
return (slots+1)*((in - min) / (max - min));Sonst sieht das in meinen Augen schon recht optimal aus.
-
Ok, danke.
Ich dachte da evtl noch an den if-Block, aber da gibt es wohl eine Möglichkeit oder?
-
Du könntest den if() natürlich auch weglassen und stattdessen einen Kommentar "das Verhalten ist undefiniert, wenn in außerhalb des Intervalls [min,max] liegt" in die Dokumentation aufnehmen

-
daishi schrieb:
Mich würde nun interessierem, ob man hier noch etwas mehr Geschwindigkeit rausholen kann und wie.
Hallo Daishi,
Du kannst Berechnungen, die nicht mit jedem neuen Messwert gemacht werden vorher machen und das Zwischenergebnis abspeichern.
Ich unterstelle mal, dass sich weder die Anzahl der slots noch das Intervall [min,max) ändert, während die Messwerte reinkommen.Dann ist Dir mit dieser Klasse vielleicht geholfen
class Diskretisierer { public: Diskretisierer( int nSlots, double minVal, double maxVal ) : m_nSlots( nSlots ) , m_min( minVal ) , m_max( maxVal ) , m_b( (m_max - m_min) / m_nSlots ) {} int idx( double x ) const { const int idx = int( (x - m_min) / m_b ); // s.Kommentar unten if( x < m_min || idx >= m_nSlots ) return -1; return idx; } private: int m_nSlots; double m_min; double m_max; double m_b; };Die Anwendung ist so ähnlich wie hier:
int main() { using namespace std; Diskretisierer dis( 7, 5.0, 12.0 ); for( double x = 4.6; x < 13.0; x += 0.4 ) cout << x << " idx: " << dis.idx( x ) << endl; return 0; }Der Wert 'm_b' wird nur einmal berechnet und entspricht Deinem 'b' in 'diskret'. Dann habe ich noch 'slots' maximaler Index durch 'bSlots' =Anzahl der Slots ersetzt - also nSlots = slots + 1.
Weiter ist mir aufgefallen, dass das 'min' bei der Berechnung des slot-Indexes nicht berücksichtigt wird. Ich meine, dass Dein Prog nicht wie gewünscht funktioniert, falls 'min' einen Wert !=0 annimmt.Die Abfrage
if( x < m_min || idx >= m_nSlots )ist ernst gemeint. Ein
if( idx < 0 || idx >= m_nSlots )liefert falsche Werte für ein 'x' knapp unterhalb von 'min', da z.B. int( -0.5 ) auch wieder 0 ist.
Gruß
Werner
-
Danke erstmal an die beiden fleißigen Helfer.
Die Idee mit der Klasse war echt klasse.
Bei der Performance konnte ich ca. 3% gut machen.Ein Fehler ist mir noch aufgefallen, das +1 bei slots muß weg.
Dann ist aber noch eine Sache, die ich nicht verstehe.
Werner Salomon schrieb:
Der Wert 'm_b' wird nur einmal berechnet und entspricht Deinem 'b' in 'diskret'. Dann habe ich noch 'slots' maximaler Index durch 'bSlots' =Anzahl der Slots ersetzt - also nSlots = slots + 1.
Weiter ist mir aufgefallen, dass das 'min' bei der Berechnung des slot-Indexes nicht berücksichtigt wird. Ich meine, dass Dein Prog nicht wie gewünscht funktioniert, falls 'min' einen Wert !=0 annimmt.Die Abfrage
if( x < m_min || idx >= m_nSlots )ist ernst gemeint. Ein
if( idx < 0 || idx >= m_nSlots )liefert falsche Werte für ein 'x' knapp unterhalb von 'min', da z.B. int( -0.5 ) auch wieder 0 ist.
Ich habe deine Klasse und meine Funktion mal laufen lassen. Beide liefern die gleichen Ergebnisse und der von dir beschriebene Fehler tritt nicht auf.
Deshalb hänge ich hier nochmal den voll kommentierten Quelltext rein.int diskret(double in, double min, double max, int slots) { //in Messwert //min, max Intervall //slots Maximaler Index if((in >= min) && (in < max)) //Probe ob Wert im Intervall { double b = (max - min) / (slots); //Groesse eines Slots im Wertebereich double tmp = in - min; //Werte auf das Intervall [0..max-min) bringen tmp = tmp / b; //Index ermitteln return int(tmp); } else return -1; //in ausserhalb des Intervalles }
-
Werner Salomon schrieb:
Weiter ist mir aufgefallen, dass das 'min' bei der Berechnung des slot-Indexes nicht berücksichtigt wird. Ich meine, dass Dein Prog nicht wie gewünscht funktioniert, falls 'min' einen Wert !=0 annimmt.
Guck doch mal ganz genau hin - min wird verwendet
(besonders durlich siehst du das, wenn du meine zusammengekürzte Version betrachtest)
-
CStoll schrieb:
min wird verwendet
Stimmt - hast Recht! ich hatte mich vertan.
Gruß
Werner