I'm trying to solve a basic calculus of variations problem numerically, by minimizing an integral over an Interpolating Function.
Basically this:
data = {1, x2, x3, 1};
f = Interpolation[data];
obj = Integrate[f[x]^2, {x, 1, 4}];
NMinimize[obj, {x2, x3}]
But I get an error
NMinimize::nnum: The function value [...] is not a number at {x2,x3} = {0.918621,0.716689}.
The function seems to be ok:
Block[{x2 = 0, x3 = 0.5}, f[2.5]]
0.15625
What am I doing wrong?
Edit:
Thank you for the answers, but I still don't understand what I'm doing wrong, only how I can change my code so Mathematica won't throw an error.
In particular:
f[1.5]^2 /. {x2 -> 1, x3 -> 2}and((f /. {x2 -> 1, x3 -> 2})[1.5])^2both evaluate without error, so why do I need to square my data instead of theInterpolationFunction?- Why does converting from an
InterpolatingFunctionto a piecewise polynomial fix the problem?
Also note that the code is just a MWE. The objective function would in general be a complicated function of f and its derivatives. For example
$$obj = f \sqrt{1+f'[x]^2}.$$
Now, I suppose I could resample that and generate a new InterpolationFunction
and then extract a piecewise polynomial of that. But why do I have to tie myself in knots like this? I can evaluate my objective at every point, so NMinimize should be able to do so as well, shouldn't it?
I'd like to treat the InterpolationFunction as I would any continuous function. I thought that was the point.
As I mentioned I'm trying to numerically approximate a continuous solution, so the solution needs to be practical for having n variables instead of just 2. The approximation would of course improve as n becomes larger.
I suspect this has something to do with evaluation order, but none of I'm doing violates what I know about the Wolfram Language.
Edit #2:
Here is the actual (non-MWE) problem I'm trying to solve:
npts = 10;
vars = Unique[Table[x, npts]];
data = {1, Splice[vars], 1};
f = Interpolation[data, InterpolationOrder -> 3];
f2 = FunctionInterpolation[
f[x] Sqrt[1 + f'[x]^2], {x, 1, Length[data]}];
obj = Integrate[f2[x], {x, 1, Length[data]}];
cons = Flatten[Table[{0 < x, x < 1}, {x, vars}]];
min = NMinimize[{obj, Splice[cons]}, vars];
ListPlot[data /. min[[2]]]
The solution should approximate a Catenary.
InterpolationFunction. Try something likedata1 = data^2; f1 = Interpolation[data1]; obj1 = Integrate[f1[x], {x, 1, 4}]; NMinimize[obj1, {x2, x3}]. – bbgodfrey Aug 02 '21 at 12:51