Suppose you are given some functional $S$, (with some 'Lagrangian' $L$) $$S[f]=\int_{t_i}^{t_f}L[f(t),f'(t)]dt$$ and you want to find the function $f$ that minimizes it, subject to some boundary conditions at $t_i$ and $t_f$. To be specific I'll consider the following case $$S[f]=\int_{0}^{t_{max}}\left(f'(t)\right)^2dt,$$ where $f(0)=\pi, f(t_{max})=0$. This is just minimized by a linear $f$, but my ultimate goal is to do this for a different problem which I can't solve analytically.

I wanted to discretize the problem and treat $f$ as a list of large number $n-1$ of variables, and then use FindMinimum in Mathematica for this purpose since I saw it implements the quasi-Newton BFGS approximation. But I am new to Mathematica and can't seem to figure out how to do this in practice.

This is what I've tried:

Setting up an initial trial solution f0 (which is just a shifted exponential in this case),

tMax = 10;
n = 100;
dt = tMax/n;
f0 = Table[\[Pi]/(1 - Exp[-tMax]) (Exp[-(i*dt)] - Exp[-tMax]), {i, 1, 
    n - 1}];

Defining a numerical derivative derList, and the functional action,

derList[f_, delta_] := 
  1/delta Join[{1/2  (f[[2]] - \[Pi])}, 
    ListConvolve[{1/2 , 0, -(1/2 )}, f], {-1/2  f[[Length[f] - 1]]}];
action[f_] := derList[f, 1] . derList[f, 1];

where I don't care so much about overall positive factors multiplying the functional, hence the use of 1 in action rather than something more appropriate like dt.

Now I want to use FindMinimum, but I can't seem to figure out the proper syntax. If I use FindMinimum[action[f], {f, f0}] it does not work. How should I set up this problem?

Just to be clear, in the end you can completely forget the motivation for this problem. action[f] is just some positive real-valued function of n-1 variables given by the components of the list f, and I have initial guesses for each one of those variables which are given by components of f0. But I just do not know how to set up FindMinimum to work with lists in this way. I would rather not copy-paste in an explicit expression for action[f] in terms of components, and write out 99 initial guesses, so I'm just looking for a way to avoid that.

  • $\begingroup$ What's wrong with finding the Euler-Lagrange equations and using NDSolve? $\endgroup$
    – Carl Woll
    Sep 21, 2021 at 0:02
  • $\begingroup$ @CarlWoll, For the actual problem I want to eventually solve $L$ actually depends on the second derivative of $f$ and the Euler-Lagrange equations leads to a fourth order non-linear ODE. I tried using NDSolve to solve it but got stiffness or singularity errors. I thought an approach using something like gradient flow might be more robust, and was led to the BFGS approximation as something people use in practice for this kind of problem. $\endgroup$
    – octonion
    Sep 21, 2021 at 0:09
  • $\begingroup$ @octonion Do you suppose that f is complex function? $\endgroup$ Sep 21, 2021 at 3:40
  • $\begingroup$ @AlexTrounev, In principle complex saddle points may be interesting too, but the particular types of $S$ that I am considering have a local minimum given by a real $f$. I have a pretty good guess at an approximate $f_0$ that could be used as an initial condition for the problem I am interested in, so I expect (hope) it will converge to this real solution. $\endgroup$
    – octonion
    Sep 21, 2021 at 3:56
  • $\begingroup$ @octonion This is a typical optimization problem, therefore we need to use NMinimize. $\endgroup$ Sep 21, 2021 at 4:19

1 Answer 1


I figured it out. I needed to make sure that Mathematica understood that action takes vector arguments by defining it explicitly as

action[f_ /; (VectorQ[f])] := derList[f, 1] . derList[f, 1];

That solves the Mathematica question.

But the answer it gives me is 'too good' and takes advantage of the discretization to oscillate every time step rather than being a linear function which is the proper continuum answer. This can be fixed by using a forward difference rather than a symmetric difference. i.e. replace derList by derForward defined as

derForward[f_, delta_] := 
  Module[{v, l}, l = Length[f]; v = ListConvolve[{1, -1}, f]; 
   AppendTo[v, (0 - f[[l]])]; PrependTo[v, (f[[1]] - \[Pi])]; 
   1/delta v];

Then FindMinimum[action[f], {f, f0}] returns the expected linear solution.

  • 2
    $\begingroup$ I think action[f_List] := ... would be simpler. $\endgroup$
    – Carl Woll
    Sep 21, 2021 at 17:51
  • $\begingroup$ @CarlWoll, thanks, I wasn't aware you could do that $\endgroup$
    – octonion
    Sep 21, 2021 at 17:55
  • $\begingroup$ @octonion How you know that your solution minimize your Lagrangian? $\endgroup$ Sep 23, 2021 at 3:19

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.