English 中文(简体)
Targeted Simplify in Mathematica
原标题:

I generate very long and complex analytic expressions of the general form:

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

When I try to use Simplify, Mathematica grinds to a halt, I am assuming due to the fact that it tries to expand the brackets and or simplify across different brackets. The brackets, while containing long expressions, are easily simplified by Mathematica on their own. Is there some way I can limit the scope of Simplify to a single bracket at a time?

Edit: Some additional info and progress.

So using the advice from you guys I have now started using something in the vein of

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)]

Changing Times to an appropriate head like Plus or Power makes it possible to target the simplification quite accurately. The problem / question that remains, though, is the following: Simplify will still descend deeper than the level specified to Replace, e.g.

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

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

simplifies the square root as well.

My plan was to iteratively use Replace from the bottom up one level at a time, but this clearly will result in vast amount of repeated work by Simplify and ultimately result in the exact same bogging down of Mathematica I experienced in the outset. Is there a way to restrict Simplify to a certain level(s)?

I realize that this sort of restriction may not produce optimal results, but the idea here is getting something that is "good enough".

最佳回答

There are a number of ways you can do this, but it can be a little tricky and depends on the structure of your actual expression. However, usually a product of a number of terms in brackets will have the head Times, and you can use FullForm to verify this:

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

You can use the higher-order function Map with expressions with head Times the same way you use it with expressions with head List, and that may allow you to Simplify the expression one term at a time, like so:

Map[Simplify, yourGinormousExpression]

You can use Expand on the result if you need to subsequently expand out the brackets.

EDIT to add: If you want to specify the forms that you do want to simplify, you can use Replace or ReplaceAll instead of one of the relatives of Map. Replace is particularly useful because it takes a level specification, allowing you to only affect the factors in the topmost product. As a simple example, consider the following:

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]

If you don t want to simplify factors that depend on a. you can do this instead:

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

Only the second term, which depends on b, has been changed. One thing to bear in mind though is that some transformations are done automatically by Times or Plus; for instance a + a will be turned into 2 a even without use of Simplify.

问题回答

I beg to differ with my colleagues, in that using Map to apply Simplify to each subexpression may not save any time as it will still be applied to each one. Instead try, MapAt, as follows:

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

The tricky part is determining the position specification. Although, if the expression you want to simplify is at the first level, it shouldn t be any more difficult then what I ve written above.


Now if you would still like to simplify everything, but you wish to preserve some structure, try using the option ExcludedForms. In the past, I ve used to prevent this simplification:

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

which Mathematica seems to like, so I do

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

Also, don t forget that the second parameter for Simplify is for assumptions, and can greatly ease your struggles in getting your expressions into a useful form.

You should try Map.
In general, Map[foo, G[a, b, c, ...]] gives G[foo[a], foo[b], foo[c], ...] for any head G and any expression foo, so for

  Map[Simplify, a b c d e]

it gives

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

Note you can denote Map[foo, expr] als foo /@ expr if you find that more convenient.





相关问题
Solving vector equations in Mathematica

I m trying to figure out how to use Mathematica to solve systems of equations where some of the variables and coefficients are vectors. A simple example would be something like where I know A, V, and ...

Introspection of messages generated in Mathematica

Is there any way to get at the actual messages generated during the evaluation of an expression in Mathematica? Say I m numerically solving an ODE and it blows up, like so In[1] := sol = NDSolve[{x [...

Connecting points in Mathematica

I have a collection of points displayed in a graphic: alt text http://img69.imageshack.us/img69/874/plc1k1lrqynuyshgrdegvfy.jpg I d like to know if there is any command that will connect them ...

Mathematica, PDF Curves and Shading

I need to plot a normal distribution and then shade some specific region of it. Right now I m doing this by creating a plot of the distribution and overlaying it with a RegionPlot. This is pretty ...

Targeted Simplify in Mathematica

I generate very long and complex analytic expressions of the general form: (...something not so complex...)(...ditto...)(...ditto...)...lots... When I try to use Simplify, Mathematica grinds to a ...

热门标签