2009-11-17 5 views
6

je produis très longues et complexes expressions analytiques de la forme générale:ciblée Simplifier dans Mathematica

(...something not so complex...)(...ditto...)(...ditto...)...lots... 

Lorsque je tente d'utiliser Simplify, Mathematica enraye, je suppose en raison du fait qu'il essaie pour étendre les parenthèses et ou simplifier entre différentes parenthèses. Les parenthèses, tout en contenant de longues expressions, sont facilement simplifiées par Mathematica. Est-il possible de limiter la portée de Simplify à une seule parenthèse à la fois?

Edit: Quelques infos supplémentaires et du progrès.

Donc, en utilisant les conseils de vous les gars que j'ai maintenant commencé à utiliser quelque chose dans la veine de

In[1]:= trouble = Log[(x + I y) (x - I y) + Sqrt[(a + I b) (a - I b)]]; 

In[2]:= Replace[trouble, form_ /; (Head[form] == Times) :> Simplify[form],{3}] 

Out[2]= Log[Sqrt[a^2 + b^2] + (x - I y) (x + I y)] 

Changement Times à une tête appropriée comme Plus ou Power permet de cibler la simplification tout à fait avec précision. Le problème/question qui reste, cependant, est le suivant: Simplify descendra toujours plus profond que le niveau spécifié à Replace, par ex.

In[3]:= Replace[trouble, form_ /; (Head[form] == Plus) :> Simplify[form], {1}] 

Out[3]= Log[Sqrt[a^2 + b^2] + x^2 + y^2] 

simplifie également la racine carrée.

Mon plan était d'utiliser itérativement Replace du bas vers le haut d'un niveau à la fois, mais cela clairement entraîner grande quantité de travail répétée par Simplify et, finalement, aboutir à exactement la même embourber de Mathematica j'ai vécu dans le départ . Y at-il un moyen de limiter Simplify à un certain niveau (s)?

Je me rends compte que ce genre de restriction peut ne pas produire des résultats optimaux, mais l'idée ici est d'obtenir quelque chose qui est « assez bon ».

Répondre

4

Il y a un certain nombre de façons dont vous pouvez faire cela, mais il peut être un peu délicat et dépend de la structure de votre expression réelle.Cependant, généralement un produit d'un certain nombre de termes entre parenthèses aura la tête Times, et vous pouvez utiliser FullForm pour vérifier:

In[1]:= FullForm[(a+b)(c+d)] 
Out[1]= Times[Plus[a, b], Plus[c, d]] 

Vous pouvez utiliser la fonction d'ordre supérieur Map avec des expressions avec tête Times même comme vous l'utilisez avec des expressions avec tête List, et qui peut vous permettre de Simplify l'expression un terme à la fois, comme ceci:

Map[Simplify, yourGinormousExpression] 

vous pouvez utiliser Expand sur le résultat si vous avez besoin d'étendre par la suite o ut les crochets.

EDIT pour ajouter: Si vous souhaitez spécifier les formulaires que vous ne souhaitez simplifier, vous pouvez utiliser Replace ou ReplaceAll au lieu d'un des parents de Map. Replace est particulièrement utile car il prend un level specification, ce qui vous permet d'affecter uniquement les facteurs dans le produit le plus haut. A titre d'exemple simple, considérer les points suivants:

In[1]:= expr = Sqrt[(a + 1)/a] Sqrt[(b + 1)/b]; 

In[2]:= Simplify[expr] 
Out[2]= Sqrt[1 + 1/a] Sqrt[1 + 1/b] 

Si vous ne voulez pas de simplifier les facteurs qui dépendent de a. vous pouvez le faire à la place:

In[3]:= Replace[expr, form_ /; FreeQ[form, a] :> Simplify[form], {1}] 
Out[3]= Sqrt[(1 + a)/a] Sqrt[1 + 1/b] 

Seul le second terme, qui dépend de b, a été modifiée. Une chose à garder à l'esprit cependant est que certaines transformations sont effectuées automatiquement par Times ou Plus; par exemple a + a sera transformé en 2 a même sans utiliser Simplify.

+0

Merci beaucoup (ainsi que les autres réponses). – Timo

1

Vous devriez essayer Map.
En général, Map[foo, G[a, b, c, ...]] donne G[foo[a], foo[b], foo[c], ...] pour une tête G et toute expression foo, donc pour

Map[Simplify, a b c d e] 

donne

Simplify[a] Simplify[b] Simplify[c] Simplify[d] Simplify[e] 

Notez que vous pouvez désigner Map[foo, expr] als foo /@ expr si vous trouvez que plus pratique.

2

Je ne suis pas d'accord avec mes collègues, en utilisant Map pour appliquer Simplify à chaque sous-expression peut ne pas gagner de temps car il sera toujours appliqué à chacun. Essayez plutôt, MapAt, comme suit:

In[1]:= MapAt[f, SomeHead[a,b,c,d], {4}] 
Out[1]:= SomeHead[a, b, c, f[d]] 

La partie la plus délicate consiste à déterminer la spécification de position. Bien que, si l'expression que vous voulez simplifier est au premier niveau, cela ne devrait pas être plus difficile que ce que j'ai écrit plus haut.


Maintenant, si vous voulez toujours tout simplifier, mais que vous souhaitez conserver une certaine structure, essayez d'utiliser l'option ExcludedForms. Dans le passé, je l'ai utilisé pour prévenir cette simplification:

In[2]:= Simplify[d Exp[I (a + b)] Cos[c/2]] 
Out[2]:= Exp[I(a + b + c)](d + d Exp[c]) 

qui Mathematica semble aimer, donc je ne

In[3]:= Simplify[d Exp[I (a + b)] Cos[c/2], ExcludedForms -> {_Cos,_Sin}] 
Out[3]:= d Exp[I (a + b)] Cos[c/2] 

Aussi, ne pas oublier que le second paramètre pour Simplify est pour hypothèses, et peut grandement faciliter vos luttes pour obtenir vos expressions dans une forme utile.

+1

Le conseil ExcludeForms est sympa, merci! Je voudrais juste que Mathematica ait un moyen d'inclure exclusivement des formulaires pour simplifier autres que TransformationFunctions, qui ne peuvent pas être configurés pour des parenthèses ... – Timo