2

Let us define the Legendre–Fenchel transformation of a function $f(s)$ as: $$g(j)=\max_s (js - f(s))\; .$$ I have a list of data $\{ \{s_1 , f(s_1)\} , \{ s_2, f(s_2) \},\cdots \}$. I am looking for a way to do the transformation. Any idea?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Ferhat
  • 124
  • 9
  • 8
    Try Max[data.{j, -1}], where data is your list of pairs. – J. M.'s missing motivation Jan 31 '21 at 12:28
  • 3
    (1) A question like this should have a set of sample inputs in copy-pastable format. (2) If you sort the values f(s_i)/s_i then it is straightforward to figure out, for given j, which of these is furthest. – Daniel Lichtblau Jan 31 '21 at 16:00
  • Thank you so much you all. It works @J. M.'s ennui – Ferhat Jan 31 '21 at 16:48
  • @ Daniel Lichtblau I do have an input list but it contains 8000 pairs. I did not know how to insert it here. – Ferhat Jan 31 '21 at 16:54
  • 2
    Inserting 20 of the pairs, instead of all of them, would probably be enough. Or make up data: data = Table[{s, Exp[s]}, {s, -1., 1., 1./16}] or use a nonconvex function if that is what you are interested in. (Site tip: The SE reply operator @ should not have spaces in the name, even if they are displayed. Thus: @DanielLichtblau.) – Michael E2 Jan 31 '21 at 17:19
  • @Michael-E2 Thank you so much for both comments. I appreciate your contribution. – Ferhat Jan 31 '21 at 17:58

1 Answers1

4

Here is an extension of the Legendre-Fenchel transform from data to the interpolation of data. An important hypothesis in what follows is that the function data is (strictly) convex. The derivative must be strictly increasing or the Interpolation will be faulty. The main advantage is the ability to compute the derivative of the LF transform easily.

solIF = NDSolveValue[{f''[s] == f[s] + Sin[4 f[s]], f[0] == 1, 
    f'[0] == 1}, f, {s, -2, 1}];
(* the function data *)
fcoords = First@solIF@"Coordinates";
fvals = solIF@"ValuesOnGrid";
data = Transpose[{fcoords, fvals}];
(* construction of the Legendre-Fenchel transform *)
lfcoords = solIF'@"ValuesOnGrid";
lfvals = fcoords*lfcoords - fvals;
lfIF = Interpolation[
   Transpose@{ArrayReshape[lfcoords, {Length@lfcoords, 1}],
     lfvals, fcoords}];

The function plot (and data in red):

ListLinePlot[solIF, Mesh -> All, MeshStyle -> Red]

enter image description here

The LF transform, comparing both J.M.'s Max[..] method and the interpolating function:

Plot[{Max[data . {j, -1}], lfIF[j]},
 {j, First@lfcoords, Last@lfcoords},
 PlotStyle -> {AbsoluteThickness[4], AbsoluteThickness[2]}]

enter image description here

The derivative (plotting the derivative of Max[..] takes ~13 sec. for me):

Plot[{D[Max[data . {j, -1}], j], lfIF'[j]} // Evaluate,
 {j, First@lfcoords, Last@lfcoords},
 PlotStyle -> {AbsoluteThickness[4], AbsoluteThickness[2]}]

enter image description here

Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • This can be considered as the best answer to my question. Thanks a lot. – Ferhat Jan 31 '21 at 18:22
  • Could you please tell me how do I find out that solIF@"Coordinates" returns the coordinates? In other words how do I get the properties attached to something like solIF? What are the existing keywords? Thanks! – chris Jan 31 '21 at 18:29
  • 3
    @chris I first learned about it here. You can also find the properties/methods from solIF@"Methods". (Several high-level data structures may be queried this way or through solIF@"Properties".) There is a package [InterpolatingFunctionAnatomy`](https://reference.wolfram.com/language/tutorial/NDSolvePackages.html) that provides interfaces to some of the methods. – Michael E2 Jan 31 '21 at 18:48
  • @Ferhat You're welcome. Thanks for the accept. :) – Michael E2 Jan 31 '21 at 18:55
  • Thanks a lot for the information. I knew about Properties but not Methods – chris Jan 31 '21 at 19:18