Formel während der Laufzeit 'rein

Hallo Freunde,

kann mir jemand (falls irgend möglich: in deutscher Umgangssprache)

  • entweder erklären, wie man eine mathematische Formel in eine fertige und mit programmierten Beispielen einwandfrei laufende Anwendung eingeben kann,
  • oder mir wenigstens Literatur (auf low level) zu dieser Frage nennen?

Im Detail:

Ich habe zum Vergnügen in C++ ein schmuckes kleines Konsolenprogramm geschrieben, das einfache und doppelte bestimmte Integrale nach der SIMPSON-Regel berechnet. Klappt wunderschön, solange ich eine Handvoll typischer Formeln via „switch“ in den Quellcode schreibe und nur noch die Werte von (mathematisch:smile: Konstanten in der Laufzeit eingeben muß (im Programmierdeutsch sind es natürlich Werte von „Variablen“).

Was aber, wenn erwartungsgemäß eine Formel auftaucht, die in dieser Bibliothek fehlt?

In ungefähr derselben Zeit, da ich den Quellcode umbaue oder ergänze und die Anwendung neu kompiliere, habe ich die Rechnung zu Fuß erledigt. (Doch darum geht es nicht. Was meine Steckenpferde betrifft, nehme ich mir Zeit haufenweise.) Nein, ich bin einfach neugierig, ob

  • C++
  • oder eine andere Programmiersprache

irgendein mit vernünftigem Aufwand zu verwendendes Werkzeug anbieten, mit dem man sozusagen einen Teil des Quellcodes während der Laufzeit ins Programm pfriemeln kann.

Obwohl es sich hier nach meiner Überzeugung um eine sehr häufige Programmieraufgabe handelt, finde ich in keinem meiner klugen Bücher Lösungsvorschläge oder gar ein beispielhaftes Listing. Sie verzetteln sich in Datenbanken, Klassen, Handles, und haben eine eigentümliche Scheu vor der Mathematik. Mag freilich sein, daß ich nur zu dumm bin, derartige Vorschläge zu erkennen, falls vorhanden.

Ich danke Euch im voraus für Euere Hinweise.

Mit freundlichem Gruß
Klaus Schneider

Hallo,
du musst die Formel parsen (http://de.wikipedia.org/wiki/Parser), d.h. den Eingabestring in eine für dein Programm leichter zu verarbeitende Datenstruktur (meistens ein Baum oder eine Formel in Postfix-Notation) umwandeln. Z.B. wird aus einer Formel wie „x+3*(7-y)“ dann so ein Baum:

 +
 / \
 x \*
 / \
 3 - 
 / \
 7 y

Um einen Parser zu schreiben, braucht man erstmal eine formale Grammatik für die Eingaben (http://de.wikipedia.org/wiki/Formale_Grammatik). Aus der kann man dann entweder mit einem Parser-Generator wie yacc oder bison autimatisch den Quellcode fuer einen Parser erzeugen lassen, oder man bastelt daraus von Hand einen Parser. Wie das geht, müßte in diversen Compilerbau-Büchern stehen, z.B. im Drachenbuch (Aho, Sethi, Ullman: Compilers). Hier ist ein Vorlesungsskript, das was dazu enthält (Kapitel 2): http://uebb.cs.tu-berlin.de/lehre/2005WVpss/files/ps…

Viele Grüße, Daniel

Hallo Freunde,

kann mir jemand (falls irgend möglich: in deutscher
Umgangssprache)

  • entweder erklären, wie man eine mathematische Formel in eine
    fertige und mit programmierten Beispielen einwandfrei laufende
    Anwendung eingeben kann,

Hallo Klaus,

Mathematische Programme wie MathCad, Mathematica usw. können das: du tippst deine Formel ein und sagst „rechne“.

Der Aufwand dahinter ist allerdings gewaltig: das Programm muss ja zuerst einmal alles verstehen, was du eingeben kannst bzw. darfst. Der erwähnte Parser ist dazu die erste Stufe.

Für die von dir fest eingebauten Funktionen (Formeln) erledigt das der Compiler für dich (der fängt auch mit einem Parser an). Praktisch musst du also die Fähigkeiten deines Compilers (der ja deine Formeln - hoffentlich - versteht) noch einmal in dein eigenes Programm einbauen.

Die Beschäftigung mit Compilerbau ist dafür zweifellos sehr nützlich.

Gruss Reinhard

Hallo Klaus,

irgendein mit vernünftigem Aufwand zu verwendendes Werkzeug
anbieten, mit dem man sozusagen einen Teil des Quellcodes
während der Laufzeit ins Programm pfriemeln kann.

Obwohl es sich hier nach meiner Überzeugung um eine sehr
häufige Programmieraufgabe handelt, finde ich in keinem meiner
klugen Bücher Lösungsvorschläge oder gar ein beispielhaftes
Listing. Sie verzetteln sich in Datenbanken, Klassen, Handles,
und haben eine eigentümliche Scheu vor der Mathematik. Mag
freilich sein, daß ich nur zu dumm bin, derartige Vorschläge
zu erkennen, falls vorhanden.

Entweder musst du dir einen Interpreter für die Formel bauen oder due verwendest eine Preogrammiersprache welche auf einem Interpreter ausgeführt wird, z.B. gab es bei den meisten BASIC-Interpretern die Möglichkeit COde durch das Programm selbst zu erstellen.

Als dritte Variante wäre noch die Möglichkeit ein KI-Sprache, wie z.B. LISP, zu verwenden. Im Prinzip kann LISP Daten nicht von Programm-Code unterscheiden, also eine Variable kann auch ein Unterprogramm enthalten.

MfG Peter(TOO)

Hallo, Ihr drei!

Ich danke Euch herzlich. Möchte nicht verhehlen, daß ich so etwas erwartet habe. Mir graut; verspreche aber, Eueren Fingerzeigen zu folgen. Wenn’s ganz dicke kommt - was ich befürchte - rechne ich womöglich doch lieber zu Fuß oder kaufe mir einen HP48.

Mathematica kenne ich vom Hörensagen, Maple aus einer Demo-Version.
Von daher auch meine Überzeugung, irgendwie müsse es gehen.

mf
Klaus

hi,
du kannst mit der Formel auch einfach mal google füttern :wink:.
Falls es sich nicht um allzu exotische Funktionen handelt, sollte das google lösen könnnen.

lg

georg

Hallo Mars,

du kannst mit der Formel auch einfach mal google füttern :wink:.
Falls es sich nicht um allzu exotische Funktionen handelt,
sollte das google lösen könnnen.

Ich denke, er meint sowas wie:

 double integral\_v;

 integral\_v = integrator(double func\_wert, double(\*formel)(double) )

wobei „*formel“ ein Zeiger auf eine Funktion wie

 double my\_sin\_2(double xval) { return square( sin(x) ); }

oder sowas ist.

Und noch dazu soll der Inhalt dieser Funktion
„zur Laufzeit“ aus einer Angabe

 cin \>\> eingabe;
 // eingabe jetzt; "sin(x) / PI \* tan(x)^3"

gelesen werden.
Jetzt soll also diese Funktion ‚on the fly‘ erzeugt
werden, die folgendes macht:

 double my\_temp\_func(double xval)
{
 double temp\_1 = sin(x);
 double temp\_2 = tan(x) \* tan(x) \* tan(x);
 double temp\_3 = 3.1415 \* temp\_2;
 double temp\_4 = temp\_1 / temp\_3;
 return temp\_4;
}

Diese Funtion soll dann in den Integrator
geschickt werden:

 for(x=xmin; x... wenn ich das richtíg verstanden habe.

Letztlich muss er, wie bereits gesagt,
einen kleinen Parser schreiben und die 
Resultate in einer Opcode- Ausführungstabelle 
speichern und dann eben ausführen. 
Für jeden Funktionswert.

Sicher gint es genug Links im "Zwischengewebe",
aber er wird wohl einen "einfachen Zugang"
benötigen :wink:

Grüße

CMБ

Hallo CMB,

richtig!

Ich denke, er meint sowas wie:

double integral_v;
integral_v = integrator(double func_wert,
double(*formel)(double) )

wobei „*formel“ ein Zeiger auf eine Funktion wie

double
my_sin_2(double xval) { return square( sin(x) ); }

oder
sowas ist.

Etwas in dieser Art hatte ich mir gewünscht.

mfg
Klaus