MathGroup Archive 2005

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Simplify and FullSimplify

  • To: mathgroup at
  • Subject: [mg58553] Re: [mg58547] Simplify and FullSimplify
  • From: "David Park" <djmp at>
  • Date: Thu, 7 Jul 2005 05:35:42 -0400 (EDT)
  • Sender: owner-wri-mathgroup at


The example you give doesn't quite rise to the requirements of the answer I
am going to give because there are simple ways to do the manipulation.
Nevertheless, I am going to take the question as a generic question on how
one can manipulate expressions to the precise form that one may want. The
trouble with Simplify and FullSimplify is that although they are very
powerful and often give one a useful form, they are still a little beyond
the control of the user.

One can often control simplifications and manipulations much easier by
working on only parts of expressions. So one could use MapAt to work on only
a subpart of an expression. But Mathematica has a missing feature here.
Sometimes one might want to work on only a subset of level parts, especially
level parts of a sum or product. There is no routine to do that. One could
write replacement rules for this, but if the expressions are long this can
be time consuming.

The following routines, MapLevelParts and MapLevelPatterns, are part of the
Tensorial tensor calculus package. I have found them very useful in
manipulating complex expressions.

MapLevelParts::usage =
    "MapLevelParts[function, {topposition, levelpositions}][expr] will map \
the function onto the selected level positions in an expression. \
Levelpositions is a list of the selected parts. The function is applied to \
them as a group and they are replaced with a single new expression. Other \
parts not specified in levelpositions are left unchanged.\nExample:\na + b +
c + d + e // MapLevelParts[f, {{2,4,5}}] -> a + c + f[b + d + e]";
      part : {toppart___Integer?Positive,
          subp : {_Integer?Positive, eprest__Integer?Positive}}][expr_] :=
  Module[{work, subparts, npos, null, i, nnull = Length[{eprest}]},
    work = func@Part[expr, Sequence @@ part];
    subparts = Thread[{toppart, subp}];
    newparts = {work, Table[null[i], {i, 1, nnull}]} // Flatten;
    npos = Partition[Range[nnull + 1], 1];
    ReplacePart[expr, newparts, subparts, npos] /. null[_] -> Sequence[]

MapLevelPatterns::usage =
    "MapLevelPatterns[function, {topposition, {pattern}}][expr] will map the
function onto the selected level positions at topposition that match the \
pattern in an expression. The function is applied to these positions as a \
group and they are replaced with a single new expression. Other parts not \
specified in the level are left unchanged.\nExample:\nf[1] + f[2] + f[3] + \
f[4] // MapLevelPatterns[g, {{f[_?EvenQ]}}] -> f[1] + f[3] + g[f[2] +
MapLevelPatterns::nomatch = "There were no matches for `` in ``";
MapLevelPatterns[func_, {toppart___Integer?Positive, {pattern_}}][expr_] :=
  Module[{work, levelpos},
    work = Part[expr, toppart];
    levelpos = Flatten@Position[work, pattern, {1}];
    If[Length[levelpos] == 0,
      Message[MapLevelPatterns::nomatch, pattern, work]; expr,
      expr // MapLevelParts[func, {toppart, levelpos}]]]

Let's try your expression. Simplify did not give the desired form,
FullSimplify did. One could also use collect.

expr = q - q Exp[-a x] + c Exp[-a x];

Collect[expr, Exp[-a x]]

One could also use MapLevelParts to apply Simplify to only the Exp terms.

expr // MapLevelParts[Simplify, {{1, 3}}]
(c - q)/E^(a*x) + q

Here is a more complicated expression.

expr2 = Cos[t]^2 + 1/((Exp[a*t] + 1/Sqrt[h])*Cos[t]^2 +
     (-a + Exp[a*t] + 1/Sqrt[h])*Sin[t]^2 + c);

Suppose we just want to simplify the common (Sin[t]^2 + Cos[t]^2) factor
leaving a Sin[t]^2 term. FullSimplify does not give us that form. But by
mapping Simplify onto just two of the terms we get the answer we want.

expr2 // FullSimplify
% // MapLevelParts[Simplify, {2, 1, {1, 5}}]
Cos[t]^2 + 1/(-(a/2) + c + E^(a*t) + 1/Sqrt[h] + (1/2)*a*Cos[2*t])
Cos[t]^2 + 1/(c + E^(a*t) + 1/Sqrt[h] - a*Sin[t]^2)

Or we could have expanded expr2 and then mapped Simplify to the desired

expr2 // ExpandAll
% // MapLevelParts[Simplify, {2, 1, {2, 3, 5, 6}}]
Cos[t]^2 + 1/(c + E^(a*t)*Cos[t]^2 + Cos[t]^2/Sqrt[h] - a*Sin[t]^2 +
    E^(a*t)*Sin[t]^2 + Sin[t]^2/Sqrt[h])
Cos[t]^2 + 1/(c + E^(a*t) + 1/Sqrt[h] - a*Sin[t]^2)

We could also have simplified this using two MapAt statements. Here Simplify
took a different path because we factored out the trig identity. We could
also have mapped right onto the trig identity.

MapAt[Collect[#1, E^(a*t) + 1/Sqrt[h]] & , expr2, {{2, 1}}]
MapAt[Simplify, %, {{2, 1, 3, 2}}]
Cos[t]^2 + 1/(c - a*Sin[t]^2 + (E^(a*t) + 1/Sqrt[h])*
     (Cos[t]^2 + Sin[t]^2))

Cos[t]^2 + 1/(c + E^(a*t) + 1/Sqrt[h] - a*Sin[t]^2)

In any case, simplifying specific parts of an expression, or selected terms
in a sum or factors in a product gives a much more controllable situation.

David Park
djmp at

From: fizzy [mailto:fizzycist at]
To: mathgroup at

A result of a calculation I was doing generated this expression....

q-q Exp[-a x] + c Exp[-a x]

naturally my next step was Simplify and I thought I'd  get the Exp[- ax] my complete surprize I got the following:

Exp[-a x] (c + (-1+ Exp[a x]) q

How on Earth did Mathematica come up with this?   I checked FullSimplify
which did collect Exp[-a x]....

On re-reading my question before I submitted it, I see that with
Simplify Mathematica  'collected' using Exp[- a x] q.....of course,
visually this expression seems quite complex and would seem to take much
more 'thinking' to get ......why do Simplify and FullSimplify have such
a vast difference in what is considered 'Simpler'?

Thanks....Jerry Blimbaum

  • Prev by Date: Re: Wrong Integral result for a Piecewise function
  • Next by Date: BKK-bound
  • Previous by thread: Re: Simplify and FullSimplify
  • Next by thread: Wrong Integral result for a Piecewise function