0
$\begingroup$

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.

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

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}}}, 
 Method -> "ConjugateGradient"]

Mathematica graphics

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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