Klasse für Nullstellenfindung


  • Mod

    Mikomi schrieb:

    Welche Bezeichner meinst du damit?

    Die Regeln gelten auch für Makros.



  • SeppJ schrieb:

    Mikomi schrieb:

    Welche Bezeichner meinst du damit?

    Die Regeln gelten auch für Makros.

    Hmm, komisch, gerade bei den Makros habe ich das in dem Beispiel gesehen, aber nun gut. Lässt sich ja schnell ändern, danke für den Hinweis 🙂



  • Mikomi schrieb:

    SeppJ schrieb:

    Warum eine Nullstellensuche überhaupt eine Klasse sein sollte, kann dir wohl nur dein Lehrer erklären. Oder auch nicht. Denn es sollte keine Klasse sein.

    Die Klasse zu erstellen ist erst der Anfang meines Projekts. Im späteren Teil soll ich einmal mittels friend-Funktion und anhand eines Beispiels die Klasse testen, allerdings ist die Klasse richtig zu programmieren derzeit mein größtes Problem an dem Projekt :S

    Es sollte trotzdem keine Klasse sein. Der Lehrer tippt in C++ aber denkt in Java.



  • Allerdings gibt mir das Programm eine Fehlermeldung, wenn ich (double *fp)(double) hinschreibe, weil es mit den vielen Klammern irgendwie nicht klar kommt...

    Stimmt, sorry kleiner Tippfehler. 🙂

    Es sollte trotzdem keine Klasse sein. Der Lehrer tippt in C++ aber denkt in Java.

    Die Philosophie von C++ und speziell die damit verbundene Objektorientierung ist eine Sache, das Vermitteln der Funktionalität eine andere.
    Wenn es jetzt darum ginge darüber zu diskutieren, ob man für Nullstellen eine Klasse anlegen sollte würden du und SeppJ mir ordentlich in den Hintern treten. Nach dem Lesen der Aufgabenstellung habe ich mir auch erst mal an den Kopf gefasst, trotzdem lassen sich die gelernten Funktionalitäten letztendlich Problemlos auf andere Klassen übertragen und das ist es, was für Anfänger zählt.



  • Fernbedienung schrieb:

    trotzdem lassen sich die gelernten Funktionalitäten letztendlich Problemlos auf andere Klassen übertragen und das ist es, was für Anfänger zählt.

    Kochkurs:
    So, wir machen jetzt Spaghetti. Holt mal die Pfannen raus.

    Aber meine Mutter benutzt dazu einen Topf!

    Ja, aber das Gelernte könnt ihr später auf Schnitzel übertragen.

    Das funktioniert nicht.



  • Kochkurs:
    So, wir machen jetzt Spaghetti. Holt mal die Pfannen raus.

    Aber meine Mutter benutzt dazu einen Topf!

    Ja, aber das Gelernte könnt ihr später auf Schnitzel übertragen.

    Hier geht es erst mal darum den Herd zu bedienen mein Freund. Man kann dir noch so viele Töpfe und Pfannen um die Ohren hauen. Wenn du nicht weißt wie der Herd bedient wird musst du dir wohl weiterhin Hamburger in die Mikrowelle schieben.



  • Finde die Diskussion über die Aufgabenstellung sehr interessant 😃 Leider habe ich nicht die Wahl, ob ich es mit oder ohne Klasse programmiere, andernfalls wäre ich die Aufgabe auch anders angegangen 🙂

    Habe jetzt versucht die Vorschläge einzubauen, bin mir hier und da allerdings noch etwas unsicher, ob ich es richtig gemacht habe. Ist folgender Code besser?

    #ifndef NULLSTELLE_H
    #define NULLSTELLE_H
    class Nullstelle {
    
    	private:
    	double *NullstellenFunktion (double);                                //Zeiger auf Funktion f; f liegt in [a,b] und ist daher von Typ double
        double Untergrenze, Obergrenze;                                      //Intervallränder eines abgeschlossenen Intervalls [a,b]
        double epsilon;                                                      //Genauigkeitsschranke epsilon
        int i_max;                                                           //maximale Anzahl Iterationen i_max für Nullstellensuche
    
        public:
        	                                                                 //Deklaration des Konstruktors
        Nullstelle(double *NullstellenFunktion(double), double Untergrenze, double Obergrenze, double epsilon, int i_max);
    
        void set_NullstellenFunktion(double *NullstellenFunktion(double));   //geeignete Set- und Get- Methoden
        double get_Nullstellen();
        void set_Untergrenze(double a);
        double get_Untergrenze() const;
        void set_Obergrenze(double b);
        double get_Obergrenze() const;
    	void set_epsilon(double epsilon);  
        double get_epsilon() const;
    	void set_i_max(int i_max);
        int get_i_max()const;
    
    };
    
    #endif
    

  • Mod

    Deine Funktionszeiger sind keine.
    double *NullstellenFunktion(double) deklariert eine Funktion namens NullstellenFunktion mit double als Argument und double* als Rückgabewert.

    get_Nullstellen war nirgendwo verlangt. Und sollte wohl mindestens const sein.

    Außerdem ist es verwirrend: "Nullstellen"? Sind das nun eine oder mehrere? Wie gibst du mehrere zurück? Warum heißt die Klasse dann "Nullstelle"? Die Ursache dieser Probleme liegt natürlich darin, dass die Aufgabenstellung Mist ist; eine zufriedenstellende Lösung innerhalb der Vorgaben wird schwer zu finden sein.

    PS: Was, wenn es keine Nullstelle gibt?



  • Mach ein using und nenn die klasse um wenn du darfst:

    using Function = double(*)(double);
    
    class BoundedFunction
    {
        Function f;
        double lowerBound, upperBound, eps;
        unsigned int maxIter;
    
    public:
        BoundedFunction(Function f, double lowerBound, double upperBound, double eps, unsigned int maxIter);
        // Getter/Setter hier
    
        // Für beliebig viele Nullstellen kannst du z.B. std::vector nehmen
        // "find" ist da auch besser, weil nicht nur ein simpler Getter
        // "Roots" statt "Nullstellen" um nicht Deutsch und Englisch zu mischen
        std::vector<double> findRoots();
    };
    

    dann gibts weniger Logikprobleme und das lebeln wird leichter.



  • Es soll nur eine Nullstelle gefunden werden. Sorry, das war vermutlich etwas unverständlich formuliert.
    @SeppJ: Wie könnte ich den Funktionszeiger denn richtig formulieren?

    @Denglisch: Danke für den Vorschlag, leider ist bereits in den Nachfolgenden Teilen vorgegeben wie ich an die Nullstelle gelangen soll 🙂

    Der nächste Aufgabenteil ist auch ein wenig komplexer:
    Man ergänze die Klasse um eine Memberfunktion, die für eine gegebene Funktion f die Bedingung f(a) · f(b) < 0 überprüft und im positiven Fall eine Nullstelle nach folgender Vorschrift (Regula falsi) annähert:
    setze c = a - f(a)((a-b)/(f(a)-f(b)))
    setze i = 0
    wiederhole solange |b - a| > eps und f(c) /= 0 und i < imax
    falls (f(a) · f(c) < 0)
    ersetze b durch c
    sonst
    ersetze a durch c
    setze c = a - f(a)
    ((a-b)/(f(a)-f(b)))
    erhöhe i = i + 1
    Ist f(a) · f(b) = 0 so soll entweder a oder b als Nullstelle gefunden werden. Im Fall f(a) · f(b) > 0 soll die Berechnung ausgesetzt werden und eine entsprechende Meldung am Bildschirm ausgegeben werden (Das würde SeppJs Frage entsprechen was ist, wenn keine Nullstelle gefunden wird)

    Mein erster Ansatz (vermutlich voller Fehler) wäre:

    void Regula_Falsi(double epsilon, int i_max, double a, double b) {   //Regula Falsi Bedingung
        	int i = 0;                                                       //Starte mit i=0 = #Iterationen
        	double c; 
        	while (i < i_max, f(c)!= 0, abs(b-a) >= epsilon) {               // f:=NullstellenFunktion (später ändern)
        		if (f(a)*f(b) < 0) {
        			c = a - ((a - b)/(f(a) - f(b)))*f(a);
        		}
        		if (f(a)*f(c) < 0) {
        			b = c;                                         // Ersetze b durch c, a wie zuvor
        		}
        		else {
        			a = c;                                         // Ersetze a durch c, b wie zuvor (noch nicht sicher, ob es so funktioniert)
        		}
        		i++                                                // Setze i=i+1
    
        		if (f(a)*f(b) > 0)                                 // Fallunterscheidung, nicht sicher ob man das so in eine while Schleife bauen kann
        		cout << "Berechnung wird ausgesetzt" << endl;
        		if (f(a)*f(b) = 0) {                               // Bei =0 ist entweder a oder b Nullstelle von f
        			f(a) = 0 oder f(b)=0                           // Nicht sicher wie man dieses entweder-oder schreiben soll
        		}
    
        	}
        }
    

  • Mod

    Mikomi schrieb:

    @SeppJ: Wie könnte ich den Funktionszeiger denn richtig formulieren?

    double (*wie_auch_immer_das_ding_heißen_soll)(double);
    

    @Denglisch: Danke für den Vorschlag, leider ist bereits in den Nachfolgenden Teilen vorgegeben wie ich an die Nullstelle gelangen soll 🙂

    Schade, denn der Vorschlag war gut und ist eine der Möglichkeiten, der Aufgabenstellung noch einen Sinn zu entlocken. Aber wenn ich solche Anforderungen lese, bekomme ich eher das Würgen und bemitleide dich:

    Ist f(a) · f(b) = 0 so soll entweder a oder b als Nullstelle gefunden werden. Im Fall f(a) · f(b) > 0 soll die Berechnung ausgesetzt werden und eine entsprechende Meldung am Bildschirm ausgegeben werden (Das würde SeppJs Frage entsprechen was ist, wenn keine Nullstelle gefunden wird)



  • @SeppJ: Freut mich zumindest, dass ich nicht der einzige bin, dem diese Aufgabenstellung zuwider ist. Leider habe ich keine Wahl als der Aufgabenstellung zu folgen. Andere Lösungswege werden nicht akzeptiert.
    Und leider muss ich letzten Endes mit der vorgegebenen "Klassen"-Methode ein fehlerfreies Programm schreiben um den Einführungskurs abzuschließen...


Anmelden zum Antworten