Algorithmus optimierung
-
Ich habe das ganze unten etwas beschrieben. Vll. könntet ihr mir ja einen Tipp geben wie ich das ganze noch schneller gestalten könnte. (Ohne c++)
public static List<Complex> GetEffectiveFFT(Complex[] data, int BarNumber) // 40 { List<Complex> effFFT = new List<Complex>(BarNumber); if (BarNumber >= EFFECTIVEFFT) //Kein Algorithmus anwenden { for (int i = 0; i < EFFECTIVEFFT; i++) effFFT.Add(data[i]); } else { Complex tmp = new Complex(); int cancelR = Convert.ToInt32(Math.Round(EFFECTIVEFFT / (float)BarNumber)); for (int i = 0; i < BarNumber; i++) { for (int j = 0; j <= cancelR; j++) { tmp.X += data[i*cancelR + j].X; tmp.Y += data[i*cancelR + j].Y; } tmp.X = tmp.X / cancelR; tmp.Y = tmp.Y / cancelR; effFFT.Add(tmp); } } return effFFT; } /* * In einem meinem FFT result sind 1024 structs mit einer x und y float Variable. * Wenn diese mit folgender Berechnung berechnet werden und gezeichnet werden sieht das so aus: http://s1.directupload.net/images/110622/d7g3uw2j.png (Rote Striche wegdenken) * Man kann sehen, dass es 1. Spiegelnd ist (Siehe roter Strich in Mitte ist Spiegellinie) und 2. dass die Werte ab dem ersten roter Strich sehr klein werden. * Sprich es rentiert sich nicht mehr diese mit hineinzuberchnen. Außerdem sind es sehr viele Werte. * Deshalb berechnet die Funktion die größe von Blöcken in diese dann immer mehrere Daten zusammengefasst werden. * Dadurch entsteht so etwas: http://s7.directupload.net/images/110626/greg47dz.png * Hier werden 1. nur die linke Hälfte des Spectrums angezeigt + zusammengefasst zu kleineren Linien * * Rechnung um die Y Position des FFT structs zu berechnen public static double CalcYPos(Complex fftData, float yScale) { return Math.Sqrt(fftData.X * fftData.X + fftData.Y * fftData.Y) * yScale; } * * Doch nun ist meine Frage kann man den Algorithmus optimieren und wenn ja wo. * * * Das ganze wird dann so verwendet: (Doch ich denke das ist eher nebensächlich) * * public Bitmap GetImage(Complex[] data) { g.Clear(BackGround); Point point1 = new Point(); Point point2 = new Point(); point1.Y = (int)g.VisibleClipBounds.Height; List<Complex> dataResult = CalcEngine.GetEffectiveFFT(data, BarNumber); for (int i = 0; i < dataResult.Count; i++) { point1.X = (i * ((int)barWidth + space)); point2.X = point1.X; point2.Y = (int)g.VisibleClipBounds.Height - Convert.ToInt32(CalcEngine.CalcYPos(dataResult[i], yScale)); //ComplexCalculation muss noch durchschnitt calculiert werden g.DrawLine(pen, point1, point2); } g.DrawLine(pen, new Point(point1.X, 0), new Point(point1.X, (int)g.VisibleClipBounds.Height)); return map; } */
-
Welchen Datentyp haben X und Y von Deiner Complex-Klasse?
Bei float oder double könntest Du die beiden Divisionen in der Schleife eliminieren.
-
was meinst du mit eliminieren? und ja es ist float
-
a = b / x is das gleiche wie a = b * 1/x;
Also einmalig die Division:
float cancelRf = 1.0f / (float)cancelR ;
Und dann innerhalb der Schleife:
tmp.X = tmp.X * cancelRf; tmp.Y = tmp.Y * cancelRf;
Das spart BarNumber * 2 Divisionen und ersetzt diese durch viel schnellere Multiplikationen.