Wolfgang Ludwig schrieb:
>
> Liebe Mathematica Spezialisten,
> mir liegt folgendes Problem auf:
> Die Funktion NIntegrate ist in der Lage, eine Funktion func[a,b] so
> abzuarbeiten, daß zuerst die numerischen Werte in die Argumente
> eingesetzt werden, und danach die Funktion evaluiert wird.
> Es sei
> func=Compile[{{a,_Real,1},{b,_Real,1}},Plus@@Flatten[Outer[Times,a,b]]]
> eine compilierte Function mit vektoriellen Argumenten.
> a und b werden z.B. definiert nach
> a={c,d};b={e,f}
>
> für die Werte c bis d gibt es eine Werteanweisung entsprechend
> rpl={c->1.,d->2.,e->3.,f->4.}.
>
> Mit NIntegrate kann ich die Funktion so aufrufen, daß zuerst die
> Argumente, dann die Funktion evaluiert werden.
> NIntegrate[func[a, b], {c, 0, 1}, {d, 0, 1}, {e, 0, 1}, {f, 0, 1}]
> Ergebnis: 1.
> Keine Fehlermeldung!
>
> Ich möchte nun eine Funktion test erzeugen, die in Bezug auf den
> Funktionsaufruf dasselbe leistet.
>
> test[model_, parsNum_, pars_] :=
> Module[{rpl},
> rpl = MapThread[Rule, {pars, parsNum}];
> model /. rpl
> ]
> Der Aufruf
> test[func[a, b], {1, 2, 3, 4}, {c, d, e, f}]
> ergibt jedoch einen Error, weil die complilierte Funktion zuerst die
> Variablen anstelle der Werte bekommt.
> Mir ist bisher keine Möglichkeit bekannt, die Auswertereihenfolge
> herumzudrehen. Auch mit HoldForm und ähnlichen Tricks habe ich es nicht
> geschafft.
>
> Ich würde mich freuen, wenn mir jemand den Trick verraten könnte. Es muß
> gehen, da NIntegrate es ja schafft.
>
> Herzlichen Dank
>
> Wolfgang Ludwig
>
Hallo Wolfgang,
sicherlich verstehe ich dein Problem nicht ganz. Aber vielleicht helfen
dir folgenden Beobachtungen:
In[1]:= Clear[a, b] (* das ist wichtig *)
In[2]:= func = Compile[{{a, _Real, 1}, {b, _Real, 1}},
Plus @@ Flatten[Outer[Times, a, b]]]
Out[2]=
CompiledFunction[{a, b},
Plus @@ Flatten[Outer[Times, a, b]], "-CompiledCode-"]
In[3]:= test[model_, parsNum_, pars_] :=
Module[{rpl}, rpl = MapThread[Rule, {pars, parsNum}];
Unevaluated[model] /. rpl]
In[4]:= test[Unevaluated[func[a, b]], {{1, 2}, {3, 4}}, {a, b}]
Out[4]= 21.
Eine *reelle* 21.!
Die Function func wird solange unevaluiert gehalten, bis die Platzhalter
a, b substituiert sind. Das erste Unevaluated (im Aufruf von test) ist
verzichtbar, wenn test das Attribut HoldFirst hat. Beachte aber das
zweite Unevaluate im Funktionsrumpf von test, das ist entscheidend!
Oder wickle den Ausdruck, der func mit symbolischen Variablen enthält,
in With, wodurch diese (durch textuelle Substitution) Werte bekommen.
In[6]:= With[{x = {1, 2}, y = {3, 4}}, g[{x^2 .y}, func[x, y]]]
Out[6]=
g[{19}, 21.]
Oder in Funktionen wie Plot werden ohnehin erst die Argumente
substituiert, bevor die Funktion gerufen wird:
In[11]:=
Plot[func[{r, r + 1}, {r + 2, r + 3}], {r, 0, 1000}]
Gruß, Hartmut