9

Can some one please explain why

 f[x_?NumericQ] := {{x, 2}, {-1, -x}}
 NIntegrate[ f[S], {S, 0, 1}]
 (*->NIntegrate::inum: Integrand f[S] is not numerical at {S} = {0.00795732}. >> *)

A possible work around is

f1[x_?NumericQ][part__] := {{x, 2}, {-1, -x}}[[part]]

then use something like

ArrayReshape[ NIntegrate[ f1[S][#[[1]], #[[2]]] & /@  {{1, 1}, {1, 2}, {2, 1}, {2, 2}}, {S, 0, 1}], {2, 2}]

but this is ugly, and does it evaluate f1 four times?

This type of problem appears when f involves matrix calculations and a numerical component (can not be done symbolically). This way, one is always forced to calculate all elements, even if you need only one. So it would advantages if NIntegrate did not evaluate f more times than necessary.

I thank any assistance in advance.

Possible related questions 1, 2 and 3.

Art Gower
  • 586
  • 2
  • 11
  • Am I the only one to see a missing } over there? – Peltio Oct 22 '13 at 14:18
  • Haha yes a } was missing, but that doesn't change the question. – Art Gower Oct 22 '13 at 17:33
  • I can't think out a work-around with the existence of _?NumericQ, but what do you really want? Just a explanation for the failure? A numerical integration without symbolic processing for a list of expressions? Or something else? – xzczd Oct 25 '13 at 11:24
  • Hi @xzczd, basically yes, I want "A numerical integration without symbolic processing for a list". I've added a short explanation at the end of the post. Thanks for thinking on this. Cheers – Art Gower Oct 26 '13 at 12:49
  • Er… Sorry but I can't understand the added explanation very well 囧, and I just noticed that the listPart isn't actually used in your work-around… BTW, have you considered something like Method->{Automatic, "SymbolicProcessing"->False"}? – xzczd Oct 26 '13 at 13:48
  • I'm not completely sure, but it appears to me that NIntegrate wants to integrate a list/matrix componentwise, by mapping NIntegrate onto the parts. It might not integrate matrices as such. – Michael E2 Oct 26 '13 at 16:58
  • @xzczd sorry, defining listPart was useless, I've removed it. – Art Gower Oct 26 '13 at 20:59
  • @MichaelE2 Yes I could map NIntegrate onto the parts, but would that not be very inefficient? For to accesse each component, all components are calculated. Cheers – Art Gower Oct 26 '13 at 21:01
  • @ArturGower I would think so, unless each part was an InterpolatingFunction or something similar and independently accessible. I hope was clear earlier: NIntegrate tries to map itself onto the parts, not that you should. The problem seems to arise from the fact that f[1] is an array and f[S] is not. It seems to do just those two evaluations (in that order) and bails out -- with a misleading error message, if I'm right. – Michael E2 Oct 26 '13 at 23:32

1 Answers1

7

Perhaps someone who knows can address the actual limitations of NIntegrate. It seems to me that, despite a couple of examples in the documentation, NIntegrate does not integrate vectors, matrices, and other arrays as arrays per se. Instead it integrates their components individually, effectively mapping NIntegrate onto the components.

The main evidence is the following. If I make f[S] return four component expressions, NIntegrate gets mapped onto each one. Note the f[1] is evaluated first, which would tell NIntegrate that the value of f is a 2x2 array. In the OP's code, f[S] is a single expression, which NIntegrate does not like.

ff[x_?NumericQ] := {{x, 2}, {-1, -x}};
ff[x_] = Array[ff[x, ##] &, {2, 2}];
f[x_] := (Print[ff@x]; ff[x]);
NIntegrate[f[S], {S, 0, 1}]

{{1, 2}, {-1, -1}}

{{ff[S,1,1], ff[S,1,2]}, {ff[S,2,1], ff[S,2,2]}}

NIntegrate::inumr: The integrand ff[S,1,1] has evaluated to non-numerical values for all sampling points in the region with boundaries {{0,1}}. >>
...
General::stop: Further output of NIntegrate::inumr will be suppressed during this calculation. >>

(* {{NIntegrate[ff[S, 1, 1], {S, 0, 1}], 
     NIntegrate[ff[S, 1, 2], {S, 0, 1}]},
    {NIntegrate[ff[S, 2, 1], {S, 0, 1}],
     NIntegrate[ff[S, 2, 2], {S, 0, 1}]}} *)

I don't claim this is conclusive evidence, but I have not found a way to use NIntegrate to integrate the OP's f.

Workaround

NIntegrate and NDSolve are not equivalent, not in functionality, speed, or accuracy. In this case, NDSolve can address the OP's problem on it's own terms -- that is, it can integrate a matrix differential equation in terms of matrices.

ClearAll[a, f];
f[x_?NumericQ] := {{x, 2}, {-1, -x}};

asol = NDSolveValue[{a'[t] == f[t], a[0] == {{0, 0}, {0, 0}}}, a, {t, 0, 1}];
asol[1]

(* {{0.5, 2.}, {-1., -0.5}} *)

It seems (to me) that if the component functions of the matrix function f could be integrated separately, then NIntegrate is likely to do a superior job finding the integrals. But when the components cannot be integrated independently, one can use NDSolve.

Michael E2
  • 235,386
  • 17
  • 334
  • 747