# What is the correct way to use NIntegrate inside the FindMinimum function?

I'm having minor issues with the FindMinimum function when using NIntegrate inside. The functions work perfectly well but I get warning messages and I was wondering if maybe I could be enlightened on the correct usage of these two functions together.

For the sake of illustration I provide the full set of functions I used on a simple example.

phi[t_, k_, h_] := (1/h)^3*
Piecewise[{{(h (1 - k) + t)^2 (h (1 + 2 k) - 2 t), (k - 1) h <= t <=
k*h}, {(h (1 + k) - t)^2 (h (1 - 2 k) + 2 t),
k*h <= t <= (k + 1) h}}];
psi[t_, k_, h_] := (1/h)^3*
Piecewise[{{(t - k*h) (h + t - k*h)^2, (k - 1) h <= t <=
k*h}, {(t - k*h) (h - t + k*h)^2, k *h <= t <= (k + 1)*h}}] ;
phipp[t_, k_, h_] := (1/h)^3*
Piecewise[{{2 (h (1 + 2 k) - 2 t) - 8 (h (1 - k) + t), (k - 1) h <=
t <= k*h}, {-8 (h (1 + k) - t) + 2 (h (1 - 2 k) + 2 t),
k*h <= t <= (k + 1) h}}];
psipp[t_, k_, h_] := (1/h)^3*
Piecewise[{{2 (-h k + t) + 4 (h - h k + t), (k - 1) h <= t <=
k*h}, {-4 (h + h k - t) + 2 (-h k + t),
k*h <= t <= (k + 1) h}}];
alpha[t_, k_, h_] := phi[t, k, h] + phipp[t, k, h];
beta[t_, k_, h_] := psi[t, k, h] + psipp[t, k, h];
T = Pi;
n = 2;
h = T/n;
FindMinimum[
NIntegrate[(h*beta[t, 0, h] - h*beta[t, n, h] +
a.Table[alpha[t, i, h], {i, 1, n - 1}] +
b.Table[h*beta[t, i, h], {i, 1, n - 1}])^2, {t, 0,
T}], {{a, {0.76}}, {b, {0.4}}}, Method -> "ConjugateGradient"]


I get the following warning message :

NIntegrate::inumr: "The integrand (a.{(8 Piecewise[{<<2>>},0])/\[Pi]^3+(8 Piecewise[{<<2>>},0])/\[Pi]^3}+b.{1/2\\[Pi]\(8\Power[<<2>>]\Piecewise[<<2>>]+8\Power[<<2>>]\Piecewise[<<2>>])}-1/2\\[Pi]\((8 Piecewise[{{<<2>>},{<<2>>}},0])/\[Pi]^3+(8 Piecewise[{{<<2>>},{<<2>>}},0])/\[Pi]^3)+1/2\\[Pi]\((8 Piecewise[{{<<2>>},{<<2>>}},0])/\[Pi]^3+(8 Piecewise[{{<<2>>},{<<2>>}},0])/\[Pi]^3))^2 has evaluated to non-numerical values for all sampling points in the region with boundaries {{0,3.14159}}"


I ask about this because FindMinimum takes unexpectedly long time to converge to the solution (which is a right one). But I thought that maybe using the functions correctly will accelerate the process.

• Try defining your functions as phi[t__?NumericQ,..] and so on for all arguments. Mar 27, 2013 at 18:18
• @b.gatessucks Tried it, I'm still getting the warnings... Mar 27, 2013 at 18:26
• maybe a.Table[alpha[t, i, h], {i, 1, n - 1}] isn't the best way to go here.
– acl
Mar 27, 2013 at 18:45
• Is this a smaller version of a bigger problem ? If not, you can do the integration symbolically, it's a very simple function. Mar 27, 2013 at 18:48
• @b.gatessucks It is indeed a smaller version of a bigger problem... Mar 28, 2013 at 8:55

The problem is indeed that Mathematica tries to do numerical operations before the symbols have value. You can fix this as follows.

Preliminary definitions, unchanged from yours

phi[t_, k_, h_] := (1/h)^3*
Piecewise[{{(h (1 - k) + t)^2 (h (1 + 2 k) - 2 t), (k - 1) h <=
t <= k*h}, {(h (1 + k) - t)^2 (h (1 - 2 k) + 2 t),
k*h <= t <= (k + 1) h}}];
psi[t_, k_, h_] := (1/h)^3*
Piecewise[{{(t - k*h) (h + t - k*h)^2, (k - 1) h <= t <=
k*h}, {(t - k*h) (h - t + k*h)^2, k*h <= t <= (k + 1)*h}}];
phipp[t_, k_, h_] := (1/h)^3*
Piecewise[{{2 (h (1 + 2 k) - 2 t) - 8 (h (1 - k) + t), (k - 1) h <=
t <= k*h}, {-8 (h (1 + k) - t) + 2 (h (1 - 2 k) + 2 t),
k*h <= t <= (k + 1) h}}];
psipp[t_, k_, h_] := (1/h)^3*
Piecewise[{{2 (-h k + t) + 4 (h - h k + t), (k - 1) h <= t <=
k*h}, {-4 (h + h k - t) + 2 (-h k + t),
k*h <= t <= (k + 1) h}}];
alpha[t_, k_, h_] := phi[t, k, h] + phipp[t, k, h];
beta[t_, k_, h_] := psi[t, k, h] + psipp[t, k, h];
T = Pi;
n = 2;
h = T/n;


Pull the integral out of the FindMinimum and make it only evaluate for numerical lists

Here's the integral, defined so as to only evaluate for numeric lists. This is cumbersome because of the way a is defined (to be a list).

ClearAll[fn];
fn[a_?(VectorQ[#, NumericQ] &), b_?(VectorQ[#, NumericQ] &)] :=
NIntegrate[(h*beta[t, 0, h] - h*beta[t, n, h] +
a.Table[alpha[t, i, h], {i, 1, n - 1}] +
b.Table[h*beta[t, i, h], {i, 1, n - 1}])^2, {t, 0, T}]


And now FindMinimum has no problem:

FindMinimum[fn[a, b], {{a, {0.76}}, {b, {0.4}}}, 