math. Ableitung



  • Hallo!
    Ich möchte gerne von Funktionen die Ableitungen berechnen können. Ich bräuchte von euch bitte ein paar Stichwörter wie man diesen Algorithmus am besten implemeniert.
    Oder anders gefragt: GIbt es nur die Möglichkeit Ableitungen zu bilden wie man da auch "per Hand" macht? Oder eröffnet der Computer vielleicht eine mächtigere Alternative? Ansonsten stelle ich mir das äußerst schwer vor die ganzen Sonderfälle und Ausnaßmen umzusetzen....

    Ich hoffe das ist einigermaßen verständlich ausgedrückt.

    Danke.

    P.S: Mir geht es wirklich nur darum Abzuleiten, Formeln zu parsen sei hier uninteressant!



  • Ja, das geht mit dem Computer. Allerdings wirst du ihm sämtliche Ableitungsregeln plus eine Sammlung elementarer Ableitungen beibringen müssen, und das stelle ich mir nicht gerade einfach vor. Aber du kannst ja mal mit einfachen Dingen wie Polynomen anfangen und dann immer etwas mehr machen. Für eine voll funktionsfähige Differentiation brauchst du wahrscheinlich sehr viel Zeit, falls du das überhaupt schaffen solltest.

    Du musst dir nämlich, bevor du überhaupt ans Differenzieren denken kannst, eine Datenstruktur für arithmetische Ausdrücke bzw. mathematische Funktionen überlegen, auch wenn du keinen Parser implementierst. Naheliegend wäre dafür sowas wie ein Operatorbaum. Dann wäre es wohl noch praktisch, du könntest Ausdrücke vereinfachen (z.B. Brüche kürzen, Ausklammern etc.), sonst wirst du oft sehr hässliche Terme erhalten, mit denen du kaum etwas anfangen kannst. Allein das gibt genügend zu tun und ist wohl nicht ganz trivial...

    Edit: Willst du sowas überhaupt selbst in C++ realisieren, oder geht es dir nur ums Ausrechnen? Für letzteres gibt es genügend Programme.



  • Also was sich am Computer sicher anbietet, ist die Funktion iterativ zu berechnen, was ja auf Blatt recht mühsam ist, aber am Computer sich recht leicht machen lässt.

    Also wenn du die Ableitung aus einer Formel berechnen willst, dann kommst du ums parsen nicht rum. 😉

    Die komplexität so einen Ausdruck dann wirklich zu berechnen ist halt abhängig von der Komplexität der Funktion..

    Also so mal ganz straight-forward und ohne andere Bibliotheken würde ich sagen, dass du direkt iterativ am schnellsten zu ein paar Ergebnissen kommst.

    Ansonsten kannst du mal hier ansetzen:
    http://de.wikipedia.org/wiki/Computeralgebrasystem

    Da gibt es ja auch Open Source Sachen, wo du rein schauen kannst, wie die das gelöst haben.



  • mathe schrieb:

    Mir geht es wirklich nur darum Abzuleiten, Formeln zu parsen sei hier uninteressant!

    http://de.wikipedia.org/wiki/Numerische_Differentiation



  • Vielen Dank erst einmal. Ich werde mir die Links ansehen.

    Ja, ich habe bereits einen Operatorbaum und kann Formeln auch "parsen", jedoch wollte ich nur damit verdeutlichen um was es mir in diesem Thread ging... ich werde bei Gelgenheit den code posten, falls es jemanden interessieren sollte...

    Auf ein OpenSource Lösung werde ich wohl zurückgreiffen wenn es um den Produktiven Einsatz geht, bis dahin möchte ich mich jedoch um eine eigene Implementierung bemühen - auch wenn sie nie fertig wird - um hinter die Kulissen zu blicken.

    Achja und mit Polynomen wäre ich zu Beginn schonmal recht glücklich!

    Numerische Differentation ist sicher praktisch, jedoch wollte ich nach möglichkeit den Kompletten Ableitungsterm und nicht nur den Wert an einer Stelle ....



  • Polynome scheinen mir recht trivial im Vergleich zu anderen Termen. 🙂



  • Symbolisches ableiten ist trivial, einfach die Ableitungsregeln implementieren. Wo ist das Problem?
    Wenn das Ergebnis auch noch hübsch sein soll ist es freilich komplizierter.



  • Bashar schrieb:

    Symbolisches ableiten ist trivial, einfach die Ableitungsregeln implementieren. Wo ist das Problem?
    Wenn das Ergebnis auch noch hübsch sein soll ist es freilich komplizierter.

    Ja aber bei partieller Differentiation gibts oft nur Intuition, Glück und Fehlschläge. Ich hätte gedacht dass es dafür irgendwelche invariante Algorithmen gibt... 😕



  • mathe schrieb:

    Ja aber bei partieller Differentiation gibts oft nur Intuition, Glück und Fehlschläge. Ich hätte gedacht dass es dafür irgendwelche invariante Algorithmen gibt... 😕

    Verwechselst du grad partielle Integration mit partiellen Ableitungen?
    Integration ist eine ganz andere Geschichte und partielle Ableitungen sind trivial.



  • otze schrieb:

    mathe schrieb:

    Ja aber bei partieller Differentiation gibts oft nur Intuition, Glück und Fehlschläge. Ich hätte gedacht dass es dafür irgendwelche invariante Algorithmen gibt... 😕

    Verwechselst du grad partielle Integration mit partiellen Ableitungen?
    Integration ist eine ganz andere Geschichte und partielle Ableitungen sind trivial.

    Ich glaube ich muss dir da zustimmen. Sorry ...ich implementiere erst einmal ein wenig und melde mich wieder^^



  • Es gibt noch einen bequemen Mittelweg zwischen symbolischer Differentiation und numerischer Differentiation: Automatische Differentiation.

    Man kann sich zB in C++ eine Klasse bauen, die neben Funktionswerten auch die Ableitung speichert (als Wert) und dann mit entsprechend überladenden Operatoren, die die Kettenregel anwenden, rechnen.

    Man bekommt dabei nicht die Ableitung als Funktion/Formel, sondern als einen Wert an einem bestimmten Punkt. Der Wert wird aber "richtig" ausgerechnet und nicht wie bei numerischer Differenzierung approximiert. Es tritt bei AD also nicht so schnell das Problem der numerischen Auslöschung auf.

    Also, wenn man eigentlich nur Funktionswert + Ableitung an bestimmten Punkten und nicht in Formel-Form braucht, ist AD sehr geeignet.

    Gruß,
    SP



  • Aber die Jacobi Matrix beinhaltet doch sämtliche partielle Ableitungen!? Somit ist doch die automatische Differenziation eher eine Anwendung und kein Mittel zur Differenziation?!



  • Theodor schrieb:

    Aber die Jacobi Matrix beinhaltet doch sämtliche partielle Ableitungen!?

    Ja und?

    Theodor schrieb:

    Somit ist doch die automatische Differenziation eher eine Anwendung und kein Mittel zur Differenziation?!

    1. Wo ist denn da der Zusammenhang?
    2. Wie kommst Du darauf?



  • So ich habe mich ein wenig eingelesen und so ganz schlau werde ich noch nicht daraus:

    1. Was hat es mit der Verkettung auf sich?! Warum ist u.a. im o.g. Script von 2 Verketteten Funktkionen die Rede? Geht das nicht mit zB f(x)=x²?
    2. Sehe ich das richtig dass bei der Berechnung (S10) einfach nur ein Operatorbaum durchlaufen wird?
    3. Seite 12 veranlasst mich zu fragen: Was genau ist die Vorteil der automatischen Ableitung? Schließlich werden da ja auch rudimentäre Ableitungsregeln umgesetzt.

    Leider verstehe ich nicht so recht was AD aus macht ... 😞

    BTW: Mittlerweile ist de rThread endgültig im falschen Forum? 😉

    @Theodor: Wie bitte?



  • mathe schrieb:

    1. Was hat es mit der Verkettung auf sich?! Warum ist u.a. im o.g. Script von 2 Verketteten Funktkionen die Rede? Geht das nicht mit zB f(x)=x²?

    Der Punkt ist, Deine Funktion "f", die Du berechnen und ableiten willst, kannst Du aus ganz vielen kleinen elementaren Operationen zusammensetzen, zB so: f(x) = g4(g3(g1(x),g2(x)). Das können Multiplikation, Addition, Subtraktion, etc etc etc. Die führst Du hintereinander aus --> Kettenregel anwenden.

    Hier mal eine vereinfachte Skizze, wie so etwas in C++ aussehen könnte:

    #include <iostream>
    #include <cmath>
    
    class fpad // forward propagating automatic differentiation
    {
      double value_;
      double deriv_;
    public:
      fpad(double v, double d=0) : value_(v), deriv_(d) {}
    
      double value() const {return value_;}
      double derivative() const {return deriv_;}
    
      const fpad& equalsTransform(double newVal, double outer_deriv)
      { deriv_ = deriv_ * outer_deriv; // Kettenregel
        value_ = newVal;
      }
    
      const fpad& operator+=(fpad const& x)
      { value_ += x.value_;
        deriv_ += x.deriv_;
        return *this;
      }
    
      const fpad& operator-=(fpad const& x)
      { value_ -= x.value_;
        deriv_ -= x.deriv_;
        return *this;
      }
    
      const fpad& operator*=(fpad const& x)
      { // Produkt-Regel:
        deriv_ = deriv_ * x.value_ + value_ * x.deriv_;
        value_ *= x.value_;
        return *this;
      }
    
      friend const fpad operator+(fpad const& a, fpad const& b)
      { fpad r(a); r+=b; return r; }
    
      friend const fpad operator-(fpad const& a, fpad const& b)
      { fpad r(a); r-=b; return r; }
    
      friend const fpad operator*(fpad const& a, fpad const& b)
      { fpad r(a); r*=b; return r; }
    };
    
    fpad sin(fpad t)
    {
      using std::sin;
      using std::cos;
      double v = t.value();
      t.equalsTransform(sin(v),cos(v)); // Verkettung
      return t;
    }
    
    int main()
    {
      fpad x (0.123, 1.0); // Identitaet für x=0.123
                           // 1.0 ist die Ableitung der Identitaet
      fpad y = x*x - 3*sin(x) + 2;
      std::cout << "f(x) = x*x - 3*sin(x) + 2\n"
                   "fuer x=0.123 ist f (x) = " << y.value() << "\n"
                   "             ist f'(x) = " << y.derivative() << "\n";
    }
    

    Vereinfacht ist das Beispiel deswegen, weil "fpad" nur eine einzige Ableitung speichert und keine Division besitzt -- die kann ich nicht aus dem Kopf auf die Schnelle ;). Das Prinzip sollte jetzt aber klar sein.

    Diese Variante von AD, in der die Ableitungen an einem Punkt "mitgeschleift" werden, nennt sich "forward propagation". Es gibt dann noch "backward propagation", bei der während man rechnet ein Baum aufgebaut wird, über den man hinterher die Ableitungen berechnet.

    Gruß,
    SP



  • Das "Problem" an dem Ansatz ist allerdings, dass man nicht beliebige Ableitungen berechnen kann.



  • otze schrieb:

    [...]dass man nicht beliebige Ableitungen berechnen kann.

    Was meinst Du? Ableitungen beliebigen Grades? Müsste eigentlich mit einer Erweiterung der Klasse funktionieren. Sonst gibt's ja noch "backward propagation". Dies könnte man sowohl dynamisch als auch per Expression-Templates machen.

    Gruß,
    SP


Log in to reply