mathematische Funtkion einer Funktion übergeben



  • Hallo zusammen!

    Ich will ein Programm schreiben, dass mir die Nullstellen einer Funktion mittels dem Newton-Verfahren löst. Grundsätzlich kein Problem, aber ich will das Newton-Verfahren in eine Funktion schreiben, die als Argument die math. Funktion und deren Ableitung übergeben bekommt. Doch wie kann ich der "Nullstellen-Funktion" ein mathematische Funtkion übergeben?

    mfg
    Frank



  • Da du sowieso ein Näherungsverfahren benutzt reicht es wohl, wenn du das entweder mit Funktionspointern oder als Template machst.

    double f (double x)
    {
        return std::pow (x, 3);
    }
    
    double f_ (double x)
    {
        return 3 * (x * x);
    }
    
    typedef double (*Function) (double); // stimmt das so?
    
    std::vector<double> newton (Function fun, Function abl)
    {
        // tu was mit fun und abl
    }
    

    Wenn du die Funktionen eingeben lassen willst oder die Ableitung dynamisch bestimmen willst wird das ganze ungleich komplizierter. Das müsste man dann wohl mit Expression Templates (ähnlich wie in Boost.Spirit) bauen.



  • Danke!
    für die schnelle Antwort,leider hab ich bis jetzt noch nichts mit Templates gemacht, gerade diese Zeile :

    std::vector<double>
    

    sagt mit noch nicht viel, werd mich aber mal mit dem Ansatz auseinandersetzen und mich gegebenenfalls nochmal melden.

    Gruß Frank



  • typedef double (*Function) (double); // stimmt das so?
    

    Nein. Ich vermute, dass mit Funktion in dem Kontext nicht die Funktion aus C++ gemeint ist, sondern eine Funktion aus mathematischer Sicht...
    f:x -> f(x) = ax^2 +bx + c (c konstanter Anteil, b linearer Anteil und a bestimmt die Streckung bzw. Stauchung der Parabel)

    z.B.: f:x -> f(x) = -2x^2 -3x +15

    Deshalb ist der gebrauch von Zeigern auf Funktionen schwachsinnig. 🙂

    Ein altes Codebsp. ...

    #include <iostream>
    using namespace std;
    
    /* Eine Funktion in der allgemeinen Form
       f:x -> f(x) = ax^2 +bx +c
    
       c konstanter Anteil
       b lineare Anteil
       a bestimmt Streackung bzw. Stauchung der Parabel
    
       (Normalform wenn a=1 gilt) */
    
    struct Fkt {
      int a;
      double b;
      double c;
    
      Fkt();
    };
    
    // Liefert Normalparabel
    Fkt::Fkt()
      : a(1), b(0), c(0)
    {}
    
    /* Typ repräsentiert die Lösungsmenge. Man bedenke es gibt max. 2
       Nullstellen */
    typedef double L_t[2];
    
    /**
     * @brief Ermittelt die Lösungsmenge aus einer Funktion nach der
     * Lösungsformel für quadratische Funktionen
     * @param f Funktion in allgemeiner Form (s.o.)
     * @param result Ausgabe der Lösungsmenge
     *
     * Weshalb dieser Name? Unter Schülern wird die Funktion auch als
     * PQ-Formel bezeichnet. :)
    
     */
    
    int pq_formel(const Fkt& f, L_t& result)
    {
      fill(&result[0], &result[1], 0);
      double p, q;
    
      try { p=f.b/f.a; }
      catch(...) { p=0; }
    
      try { q=f.c/f.a; }
      catch(...) { q=0; }
    
      double D=pow(p/2, 2)-q;
      if (errno)
        D=-1;
    
      if (D==0)
        result[0]=-p/2;
    
      else if (D>0) {
        result[0]=-p/2 +sqrt(D);
        result[1]=-p/2 -sqrt(D);
        return 2;
      }
      else if (D<0)
        return 0;
    
      return static_cast<int>(D);
    }
    
    int main()
    {
      // f:x -> f(x) = x^2 -3x -15
      Fkt f;
      f.b=-3;
      f.c=-15;
    
      L_t res;
      int n=pq_formel(f, res);
    
      switch (n)
        {
        case 1:
          cout << "|L = { " << res[0] << " }\n";
          break;
        case 2:
          cout << "|L = { " << res[0] << "; "
    	   << res[1] << " }\n";
          break;
        default:
          cout << "|L = { }\n";
        }
    }
    


  • @.filmor:

    wenigstens einer, der die Templates nicht scheut 🙂 Habe mich seit längerem mit der Metaprogrammierung beschäftigt - super interessant das Thema 😉 Lange Rede kurzer Sinn, ich würde es vorziehen die Funktion (... da kommt man ja ganz durcheinander ... die aus C++ 🙂 als Funktionsobjekt zu übergeben, ist deutlich übersichtlicher und vorallendingen flexibler; die Funktion wäre dann auch im Zusammenhang mit der STL verwendbar.



  • lucky_tux schrieb:

    typedef double (*Function) (double); // stimmt das so?
    

    Nein. Ich vermute, dass mit Funktion in dem Kontext nicht die Funktion aus C++ gemeint ist, sondern eine Funktion aus mathematischer Sicht...
    f:x -> f(x) = ax^2 +bx + c (c konstanter Anteil, b linearer Anteil und a bestimmt die Streckung bzw. Stauchung der Parabel)
    [/cpp]

    Das "stimmt das so?" bezog sich nur auf die Syntax. Mir ist schon klar, was gemeint war, aber wie gesagt, wenn er die Funktionen zur Compile-Zeit kennt und ein Näherungsverfahren anwendet, dann kann er sie auch als C++-Funktionen implementieren. Dynamisch ist das ganze extrem kompliziert wenn es flexibel sein soll. Es gibt schließlich nicht nur ganzrationale Funktionen, die über einfache Parameter bestimmt werden können.

    lucky_tux schrieb:

    ich würde es vorziehen die Funktion (... da kommt man ja ganz durcheinander ... die aus C++ 🙂 als Funktionsobjekt zu übergeben, ist deutlich übersichtlicher und vorallendingen flexibler; die Funktion wäre dann auch im Zusammenhang mit der STL verwendbar.

    Schon klar, die Möglichkeit hatte ich ja auch angedacht. Aber erstens sind auch normale Funktionen mit der STL verwendbar (ich weiß nicht wie du darauf kommst, dass nur Funktoren damit funktionieren) und zweitens wollte ich die Syntax nicht unnötig verkomplizieren (und das tuen Templates leider, was du auch gemerkt haben solltest, wenn du dich mit Metaprogrammierung beschäftigt hast (noch komplizierter sind nur noch Compilerfehler bei größeren Metakonstrukten :()).


Anmelden zum Antworten