3
$\begingroup$

I have a list of the components of the gradients, $\partial f/\partial x_i$, of a function $f(x_1,x_2,\cdots)$. Is there some neat way to reconstruct the function $f$?

One approach to doing this would be treat this as a system of PDEs and use DSolve. However, Mathematica is unable to solve PDEs with more than 3 variables – see, for instance here.

Another approach is to integrate the gradients $\int (\partial f/\partial x_i) dx_i $ and then take the Union of the terms from all the integrals. This isn't quite a robust way of doing things as it fails if the expressions for the integrals are not simple enough (ExpandAll does not help). A code for doing this is the following : Table[act[m]=ExpandAll[Integrate[gradient[m],Subscript[x, m]],{m,1,NN}]; f=Fold[Union,act[1],Table[act[m],{m,2,NN}]];

Any better ideas?

$\endgroup$

2 Answers 2

7
$\begingroup$

Problems with code often require the code (or "All unhappy codes are unhappy in their own way"), but here's a somewhat complicated example that works:

vars = {w, x, y, z};
vf = Grad[(Log[w]^2 Sqrt[1 + x^3 y] + y^5 ArcTan[z^7])/Log[1 + x z], vars];
Fold[
 #1 + Integrate[First[#2] - D[#1, Last[#2]], Last[#2],
   Assumptions -> vars \[Element] Reals] &, 
 0, Transpose@{vf, vars}]
(*  (y^5 ArcTan[z^7])/Log[1 + x z] + (Sqrt[1 + x^3 y] Log[w]^2)/Log[1 + x z]  *)

Note: Fold[#1 + Integrate @@ #2 - #1 &, 0, Transpose@{F, vars}] is shorter, but the integrals are more complicated.

Of course I've seen Integrate fail on very complicated expressions, but I don't know what one could expect to work better than it, other than perhaps DSolve which sometimes takes a different route in edge cases.

Alternate method of integration:

Here's a way to use DSolve, which ends with a constant of integration C[5] that is omitted in the Integrate method:

iter[F_, {dF_, vars_, c_}] := 
  F /. First@DSolve[D[F, First@vars] == dF, c @@ vars, vars];
Fold[
 iter,
 C[1] @@ vars,
 Transpose@{
   vf,
   NestList[Rest, vars, Length@vars - 1],
   Array[C, Length@vars]}
 ]

Use FoldList instead of Fold and you see the process mentioned in a comment below:

{C[1][w, x, y, z],
 (Sqrt[1 + x^3 y] Log[w]^2)/
   Log[1 + x z] + C[2][x, y, z],
 (y^5 ArcTan[z^7])/Log[1 + x z] + (Sqrt[1 + x^3 y] Log[w]^2)/
   Log[1 + x z] + C[3][y, z],
 (y^5 ArcTan[z^7])/Log[1 + x z] + (Sqrt[1 + x^3 y] Log[w]^2)/
   Log[1 + x z] + C[4][z],
 (y^5 ArcTan[z^7])/Log[1 + x z] + (Sqrt[1 + x^3 y] Log[w]^2)/
   Log[1 + x z] + C[5]}

Update: Error check

iter::nxact = "The vector field is not conservative: the derivative of `` with respect to `` minus `` depends on ``.";
iter[F_, {dF_, v_, c_}] := F /. First@ DSolve[
     If[Internal`DependsOnQ[#, Complement[vars, v]],
         Message[iter::nxact, F, First@v, dF, Complement[vars, v]];
         Throw[$Failed],
         #
         ] &@ Simplify[D[F, First@v] - dF] == 0,
     c @@ v, v];

Catch@ Fold[
  iter,
  C[1] @@ vars,
  Transpose@{
    vf,
    NestList[Rest, vars, Length@vars - 1],
    Array[C, Length@vars]}
  ]
$\endgroup$
3
  • $\begingroup$ Thanks a lot! This works like a charm for the case I have, in which the gradients are multivariate polynomials in the vars. May I ask what is the logic you are using here: it is iterated integrals and subtracting out something? $\endgroup$ Jul 30, 2019 at 19:07
  • 4
    $\begingroup$ @TheTwistedSector It's how I teach it in Multivariable/Diff Eq. Basically, to find an $F$ such that $\nabla F$ equals a given $\nabla f$, alternate integrating and differentiating w.r.t the variables. First integrate the $w$ component $F=\int f_w\,dw+g(x,y,z)=F^{(1)}+g$; then differentiate w.r.t. $x$: $F^{(1)}_x+g_x=f_x$. Then integrate $g=\int(f_x-F^{(1)}_x)\,dx+h(y,z)=F^{(2)}+h$. And so forth. One should check the integration constants $g,h,\dots$ are free of any dependency on $(w),\,(w,x),\dots$, respectively. The code above does not do that. The answer is $F=F^{(1)}+F^{(2)}+\cdots$. $\endgroup$
    – Michael E2
    Jul 30, 2019 at 19:44
  • 2
    $\begingroup$ One advantage is that the integrations get easier as you go along because of cancelation. You also can tell when the vector field is not conservative/closed/exact. $\endgroup$
    – Michael E2
    Jul 30, 2019 at 19:44
1
$\begingroup$

It is worth pointing out that as of V12.2, DSolve can solve the example in my other answer:

vars = {w, x, y, z};
vf = Grad[(Log[w]^2 Sqrt[1 + x^3 y] + y^5 ArcTan[z^7])/Log[1 + x z], 
   vars];

DSolve[
 Grad[f @@ vars, vars] == vf,
 f, vars]
(*
{{f -> Function[{w, x, y, z}, 
    C[1] + (y^5 ArcTan[z^7])/Log[1 + x z] + (
     Sqrt[1 + x^3 y] Log[w]^2)/Log[1 + x z]]}}
*)
$\endgroup$
2
  • $\begingroup$ Looks like some progress is happening on this front! Does DSolve also work with the examples here? I would have tested this out by myself, but do not have v12.2 yet. $\endgroup$ Feb 14, 2021 at 12:34
  • 1
    $\begingroup$ @TheTwistedSector Yes, it works. I added an answer. $\endgroup$
    – Michael E2
    Feb 14, 2021 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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