0
$\begingroup$

I have a boundary condition for a problem, which contains around 100 terms! I have no trouble getting Mathematica to compute it, but the terms are sorted in a seemingly random order and I would like to organise them to make it a bit easier to deal with without having to manual.

Consider the following expression:

\begin{align*} & \dfrac{\partial A_{1}}{\partial x}\dfrac{\partial A_{2}}{\partial y}+\dfrac{\partial A_{2}}{\partial x}\dfrac{\partial A_{3}}{\partial z}+\dfrac{\partial A_{3}}{\partial y}\dfrac{\partial A_{1}}{\partial z}\\ & +\dfrac{\partial A_{1}}{\partial x}\dfrac{\partial B_{2}}{\partial y}+\dfrac{\partial A_{2}}{\partial x}\dfrac{\partial B_{3}}{\partial z}+\dfrac{\partial A_{3}}{\partial y}\dfrac{\partial B_{1}}{\partial z}\\ & +\dfrac{\partial B_{1}}{\partial x}\dfrac{\partial C_{2}}{\partial y}+\dfrac{\partial B_{2}}{\partial x}\dfrac{\partial C_{3}}{\partial z}+\dfrac{\partial B_{3}}{\partial y}\dfrac{\partial C_{1}}{\partial z}\\ & +\dfrac{\partial B_{1}}{\partial x}\dfrac{\partial C_{2}}{\partial y}+\dfrac{\partial C_{1}}{\partial x}\dfrac{\partial C_{1}}{\partial z}+\dfrac{\partial C_{1}}{\partial y}\dfrac{\partial C_{1}}{\partial z}\\ & +\dfrac{\partial A_{1}}{\partial x}C_{1}+\dfrac{\partial A_{2}}{\partial y}C_{2}+\dfrac{\partial A_{3}}{\partial z}C_{3} \end{align*}

I am very new to patterns/matching, but could somebody please explain how I can use these to extract all terms from the above expression which contain:

  • $\dfrac{\partial A_i}{\partial x_k}\dfrac{\partial A_j}{\partial x_\ell }$
  • $\left(\dfrac{\partial A_i}{\partial x_k}\right)^2$
  • $C_i\dfrac{\partial A_j}{\partial x_k}$

where $i,j,k,\ell\in\{1,2,3\}$ and $x_1=x,x_2=y,x_3=z$.

Obviously the way I have specified the terms above lends itself to the use of a Table command, but I would like to be able to do this in such a way which is independent of the choice of subscripts, and can be picked up from whatever the expression is. How can I elegantly answer the above questions?

$\endgroup$
0
$\begingroup$

Note, do not use capitalized variable names, those are used by the system. E.g. "C" is used for integration constants.

To be able to choose the functions by index, we use indexed function names. I assume that you are dealing with code that can be evaluated. Unfortunately, in MMA we need to write functions with arguments, what makes it a bit clumsy.

Further, to minimize my effort in writing a complicated test expression, I use a helper function that creates the complicated derivatives:

f[a1_, a2_, x1_] := D[a1[x, y, z], x1] a2[x, y, z];
f[a1_, a2_, x1_, x2_] := D[a1[x, y, z], x1] D[a2[x, y, z], x2];

With this we create some teste expression:

ex = f[a[1], a[2], x, y] + f[a[1], a[2], y, z] + f[a[1], b[3], x, y] +
   f[a[1], c[3], x]

![

We can now pick out e.g. all terms that are derivatives from a[1] and a[2]:

Cases[ex, Derivative[_, _, _][a[1]][x, y, z]  Derivative[_, _, _][a[2]][x, y, z]]

![

Or cases with a derivative of a[1] and c[3]:

Cases[ex, Derivative[_, _, _][a[1]][x, y, z]  c[3][x, y, z]]

enter image description here

Or all terms that contain a derivative relative to x:

Cases[ex, Derivative[1, _, _][_][x, y, z]  _ ]

![enter image description here

To make life easier we may define a function that helps us pick terms. The first 2 arguments are the function names, the next 2 arguments are 1,2,3, indicating the derivative relative to x,y,z. 0 means no derivative:

pick[a1_, a2_, x1_ : 0, x2_ : 0] := (der = {_, _, _}; 
  der1 = If[x1 > 0, der1 = der; 
    der1[[x1]] = 1; (Derivative @@ der1)[a1], a1]; 
  der2 = If[x2 > 0, der2 = der; 
    der2[[x2]] = 1; (Derivative @@ der2)[a2], a2]; 
  Cases[ex, der1[x, y, z] der2[x, y, z]])

Now we can say, e.g.:

pick[a[1], b[3], 1, 2]

enter image description here

Or all terms with a x derivative of a[1]

enter image description here

$\endgroup$
6
  • $\begingroup$ Thank you so much, this answer is really clear. There is a question I have which extends upon this - is it possible to create a command which returns terms which are functions of the variable being specified, rather than just the derivative? As a test example, consider exprTest = f[x] g[x] + g[x]^2 + f[x] g[x]^2 + g[x]^3 + Sqrt[f[x]]. What I would like to do is write a function which extracts the terms involving f[x] or any term that is a function of it. The output should be $\{f(x)g(x),f(x)g(x)^2, \sqrt{f(x)}\}$. So is there any equivalent of Derivative which is a general function? $\endgroup$ Mar 12 at 9:58
  • 1
    $\begingroup$ Try: Cases[exprTest, a_ /; ! FreeQ[a, f[x]]] But I do not understand what you mean by: ". So is there any equivalent of Derivative which is a general function?" $\endgroup$ Mar 12 at 10:11
  • $\begingroup$ That works perfectly, thank you! I meant whether there existed something like Function[___][a[1]][x, y, z] which extracted terms involving functions of a[1]. $\endgroup$ Mar 12 at 10:18
  • $\begingroup$ In your expression, what do the ! and /; do? I am not completely familiar with all of Mathematica's syntax. $\endgroup$ Mar 12 at 10:19
  • 1
    $\begingroup$ ! means NOT and /; is a condition on a pattern.. In the above case we are looking for pieces a_ so that the pattern a is not free of f[x] $\endgroup$ Mar 12 at 10:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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