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.


Anmelden zum Antworten