2009-09-29 7 views
4

J'ai un opérateur différentiel qui agit sur deux fonctions. Pour simplifier le problème, disons que mon opérateur estÉvaluation partielle dans Mathematica

A[F_,G_] := D[F,x] D[G,y] 

Je veux être en mesure, si je sais que F, pour définir un opérateur différentiel AF tel que AF [G] est égale à A [F, G]. La manière évidente est

AF[G_] := A[F,G] 

qui fonctionne sans aucun problème. Mais ce que j'aimerais vraiment, c'est arranger les choses de telle sorte que lorsque j'appelle AF avec différents arguments G1, G2, ... la dérivée D [F, x] n'est pas recalculée à chaque fois, mais seulement une fois. De plus, j'aimerais que la définition de AF ne dépende pas de la forme particulière de A, puisque A est passé comme argument à ma fonction.

J'ai lu l'aide sur Hold, HoldAll, Evaluate etc. mais je ne peux pas mettre ces choses ensemble pour obtenir ce que je veux. Je ne sais même pas si ce que je veux est possible dans Mathematica.

Répondre

4

Avec le problème que vous décrivez, je ne vois pas une façon simple de le faire. Une chose que vous pourriez faire pour le refondre pour le rendre beaucoup plus facile serait de redéfinir A donc c'est une fonction des dérivés de F et G. Si vous avez

A[{dFdx_,dFdy_}, {dGdx_,dGdy_}] := dFdx*dFdy 

vous serez dans une très bonne position pour calculer les dérivés de F que vous avez besoin et ensuite définir AF d'une manière qui est générique par rapport à A, comme ceci:

With[{ dFdx = D[F,x], dFdy = D[F,y] }, 
    AF[G_] := A[{dFdx, dFdy}, {D[G, x], D[G, y]}]] 

Vous pouvez utiliser With pour substituer des pièces évaluées dans le côté droit non évalué d'un formulaire SetDelayed (une définition utilisant ": =") comme indiqué. Cependant, si vous ne pouvez pas faire ce changement, les choses vont devenir poilues, et vous devrez faire quelques suppositions sur ce que A est.

Si A est un symbole DownValues ​​défini pour elle, et a une définition simple, vous pouvez faire l'évaluation partielle que vous voulez en utilisant un Hold, faire des substitutions de règles, et puis en faisant un ReleaseHold, comme ceci:

ReleaseHold[ 
    Hold[AF[G_] := A[F, G]] /. DownValues[A] /. 
    HoldPattern[D[F, var_]] :> With[{eval = D[F, var]}, eval /; True]] 

le bit With[...] dans la deuxième règle est une astuce pour forcer l'évaluation de quelque chose correspondant à un modèle dans un Hold appelé "Trott-Strzebonski method", ce qui est obscur, mais extrêmement utile pour des tâches comme celle-ci. Cependant, cela va vraiment limiter votre interface, ce qui signifie que vous ne pouvez pas, par exemple, passer une fonction pure pour A, et avec une définition plus compliquée, cette astuce ne fonctionnera probablement pas non plus. Si vous parvenez à spécifier que votre forme différentielle sera une fonction des dérivées réelles, je vous recommande fortement de le faire.

EDIT: J'ai pensé à une manière plus générale et plus robuste de le faire.

L'astuce est alors de supprimer temporairement la définition de D (l'opérateur dérivé) en utilisant Block, de sorte que les dérivés dans la définition de A restent non évalués, puis utilisez-le remplacement de la règle de remplacer les valeurs pour les dérivés de F tout en enveloppant tout dans une pure fonction pour obtenir le remplacement de bon nom, comme ceci:

With[{fRules = 
{HoldPattern[D[F, x]] :> Evaluate[D[F, x]]}}, 
    Block[{D}, 
    With[{fn = Function[G, Evaluate[A[F, G] /. fRules]]}, 
     AF[G_] := fn[G]]]] 
+0

Merci! Cela a fonctionné parfaitement. J'ai cependant fait quelques changements non-essentiels pour prendre en compte la possibilité d'avoir plus d'une variable x, y, etc. Donc le code que j'ai utilisé est AF = With [{fRules = {HoldPattern [D [F, x_]]:> Evaluer [D [F, x]]}}, Bloquer [{D}, Fonction [G, Evaluer [A [F, G] /. fRules]]]]; – cefstat

0

Pouvez-vous pas le faire:

A[F_] := With[{DF = D[F, x]}, Function[{G}, DF D[G, y]]] 

Cela ressemble à currying dans un vrai langage de programmation fonctionnel comme F #, où vous écrivez:

let a f = 
    let df = d f x 
    fun g -> df * d g y 
+0

Si 'A' est connu et casté sous la forme d'une fonction des dérivées de' F' et 'G' à l'avance, cela fonctionne bien. Mais si ce n'est pas le cas, vous devez retarder l'évaluation des dérivées de 'G' tout en forçant l'évaluation des dérivées de' F', ce qui nécessite des étapes supplémentaires. – Pillsy

Questions connexes