"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

Methoden und Algorithmen zur diskreten (Punkt-für-Punkt-)Integration

jives 08.03.2008 - 11:17 848 1
Posts

jives

And the science gets done
Avatar
Registered: Sep 2001
Location: Baden
Posts: 3548
Eine Frage an die Mathe- und Informatikgurus hier im Forum ;)

Ich muss im Zuge eines größeren Projektes einen PID-Regler auf einem 8Bit-µC implementieren, und möchte dafür Funktionen zur Berechnung des Differentials und des Integrals schreiben. Offensichtlich handelt es sich hierbei um ein diskretes System (mit konstantem dt). Die Berechnung des Differentials lässt kaum Fragen offen:
Code:
x'[n] = (x[n] - x[n-1]) / dt
Eine Variable die von einer auf die nächste Iteration gerettet werden muss ist - glaube ich - das Optimum, das man hier erreichen kann. Kleines Detail am Rande: Ich habe hier undokumentierte Implementierungen von solchen Funktionen (siehe auch weiter unten), bei der
Code:
x'[n] = (x[n] - x[n-2]) / (2 * dt)
gerechnet wird. Was für einen Sinn hat das? Aus meiner Sicht hat das keine Vorteile, und man hängt mehr oder weniger mit der Berechnung unnötig einen Punkt hinten nach.

Das Integral ist naturgemäß schwerer, und und ich bin nun auf der Suche nach einem möglichst schnellen und speichersparenden Algorithmus dafür. Die Implementierung (nicht in C) zu der ich Zugang habe, wählt dafür Simpson:
Code:
y[n] = ((x[n] + 4 * x[n-1] + x[n-2]) / 6) * dt
bzw. für die Initialisierung
Code:
 y[n] = x[n] * 0.5 * dt
In C implementiert habe ich das Ganze jetzt vorerst so
Code:
float function integral(float x, float dt, bool init)
{
    static float y;
    static float x1;    // x[n-1]
    static float x2;    // x[n-2]
    
    if (init)
    {
        y = x * 0.5 * dt;
        
        x2 = 0;
        x1 = x;
        
        return y;
    }
    else
    {
        y += ((x + 4. * x1 + x2) / 6.) * dt;
        
        x2 = x1;
        x1 = x;
                
        return y;
    }
}
Ich brauche hier allerdings drei static-Variablen, noch dazu alle mit 32Bit, was auf meinem µC nicht ganz so optimal ist. Gibt es einen besseren Algorithmus bzw. eine bessere Methode diesen zu Implementieren?

Würde mich über jeglichen Input sehr freuen - tia :)
Bearbeitet von jives am 08.03.2008, 11:25

v2.1

Bloody Newbie
Registered: Jan 2008
Location: at
Posts: 3
Kann mich zwar dunkel an die Simpsons Rule erinnern (aus der Schulzeit), bin allerdings kein Mathematiker und frage mich warum du die da überhaupt brauchst?

Frage jetzt nur mal interesse halber, warum würde denn folgende naive Methode nicht funktionieren:

Code: PHP
float function integral(float x, float dt, bool init)
{
    static float y;
    
    if (init)
    {
        y = x * dt;
    }
    else
    {
        y += x * dt;
    }
        return y;
}

Wenn Du dt=1 setzen kannst solltest Du überlegen ob es nicht mit Integern realisierbar wäre.
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz