Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm trying to simplify expressions involving partial derivatives of an abstract functions. To obtain the human readable result, I would like to gather terms of total derivatives and hold on differentiation

$$ \frac{\partial f(x,y)}{\partial y}g(x,y) + f(x,y)\frac{\partial g(x,y)}{\partial y} = \partial_y\left(f(x,y)g(x,y) \right). $$

I've tried to define transformation function

transform[expr_, var_] := 
 With[{int = Integrate[expr, var]}, Defer[D[int, var]]]

which, when applied to some simple cases does exactly what is expected, e.g.

D[f[x, y] g[x, y], y] // 
   TransformationFunctions -> {transform[#, x] &, transform[#, y] &}] &

(* ===> D[f[x, y] g[x, y], y] *)

For a slightly more complicated expression (which is of my interest here) this approach fails

D[f[x, y] g[x, y], y] + D[f[x, y] g[x, y], x] // 
   TransformationFunctions -> {transform[#, x] &, transform[#, y] &}] &

(* ===> D[g[x, y], x]*f[x, y] + D[g[x, y], y]*f[x, y] + 
   D[f[x, y], x]*g[x, y] + D[f[x, y], y]*g[x, y] *)

Is there any other way to deal with such expression simplification? I'm aware of (22029) (22014), but posted answers do not give the full answer in this particular case.

share|improve this question

closed as unclear what you're asking by Kuba, m_goldberg, bobthechemist, Pickett, Oleksandr R. Feb 24 at 2:33

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question.If this question can be reworded to fit the rules in the help center, please edit the question.

The examples all look like you want nothing at all to happen. I don't understand your goal. E.g., what about D[(f[x, y] g[x, y])^2, y]? Do you want that to stay unevaluated, too? –  Jens Jul 23 '13 at 0:11
Just have a look on nontrivial case (the second example). –  mmal Jul 23 '13 at 6:50
add comment

3 Answers 3

Are you looking for this result:

D[f[x, y] g[x, y], y] + D[f[x, y] g[x, y], x] // Simplify[#, 
   TransformationFunctions -> {Automatic, transform[#, x] &, 
     transform[#, y] &}] &

TransformationFunctions replaces the internal rules, so if you want to preserve them you have to add Automatic into the list. Hoping this helps.

share|improve this answer
This only factors out derivative terms (D[g[x, y], x] + D[g[x, y], y])* f[x, y] + (D[f[x, y], x] + D[f[x, y], y])* g[x, y], I would like to get D[f[x, y] g[x, y], y] + D[f[x, y] g[x, y], x] in this example. –  mmal Jul 23 '13 at 15:07
add comment

Would it be acceptable to simplify the expression without evaluating the derivatives in the first place?

SetAttributes[simp, HoldFirst]
simp[expr_] := Block[{D}, Defer @@ {Simplify@expr}]

simp[x^2 + 2 x + 1 + D[f[x, y] g[x, y], y]]
(*  (1 + x)^2 + D[f[x, y]*g[x, y], y]  *)

simp[x^2 + 2 x + 1 + D[f[x, y] g[x, y], y] + D[f[x, y] g[x, y], x]]
(*  (1 + x)^2 + D[f[x, y]*g[x, y], x] + D[f[x, y]*g[x, y], y]  *)

I included the polynomial term to demonstrate that Simplify is working as expected on parts of the expression which are not derivatives.

share|improve this answer
Unfortunately no, simply because expression under consideration has evaluated derivatives yet :/ –  mmal Nov 11 '13 at 16:35
@mmal, I'm not sure what you're trying to do. In both of your examples your desired result is exactly the same as the input. It would be useful to include an example where the transformation actually changes the expression. –  Simon Woods Nov 11 '13 at 19:27
add comment

I am not sure if the solution I proposed is over-complicated. Nevertheless, I have been unsatisfied about the power of TransformationFunctions. It appears to me that give a condition (as assumptions) in Simplify is better than a transformation function. For example,

Simplify[x + y, x + y == z]


However, the conditions as assumptions does not support pattern. Thus if you need the function to be used in general, not only to f[x,y] and g[x,y], but also, say, h[x,y], a list of assumptions must be generated by looking into the expression:

simp[expr_] := Module[{f, g, cond, vars, ZZ, varsTuples, res},
  cond = {g[x, y] D[f[x, y], x] + f[x, y] D[g[x, y], x] == 
     ZZ[][x][f[x, y] g[x, y]], 
    g[x, y] D[f[x, y], y] + f[x, y] D[g[x, y], y] == 
     ZZ[][y][f[x, y] g[x, y]]};
  vars = DeleteCases[#, _Derivative[__]] &@
    Union@(Head /@ Level[expr, {-2}]);
  varsTuples = Tuples[vars, 2];
  res = Simplify[expr, 
    And @@ Flatten[cond /. ({f -> #1, g -> #2} & @@@ varsTuples)]];
  res /. ZZ[][x_][e_] :> Defer[D[e, x]]]

For example,

D[f[x, y] g[x, y], y] // simp

D[f[x, y]*g[x, y], y]

D[f[x, y] g[x, y], y] + D[f[x, y] g[x, y], x] // simp

D[f[x, y]*g[x, y], x] + D[f[x, y]*g[x, y], y]

Side remark: For the Simplify[x + y, x + y == z] trick to work, z must has a lexically greater order than x and y. For example, the following doesn't do anything.

Simplify[x + y, x + y == w]
x + y

This is why I have given a strange name ZZ in the conditions, and later replace that using ZZ[][x_][e_] :> Defer[D[e, x]]]

Further discussions about this issue can be found at Why does Simplify ignore an assumption? and the references therein.

Other possible methods: There is another method, which I have used heavily myself in similar situations: one can make use of ReplaceList, and write our own simplification functions. ReplaceList returns all possible replacements, and we have to look at every of them to select the best, and do further simplications on top of that, until reaching a fixed point.

share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.