3
$\begingroup$

NIntegrate does not seem to like Intervals as regions. Consider the following example function defined for a parameter "a":

f[a_, t_?NumericQ] := t^3;

Let us integrate the function over an interval:

a = 3;
NIntegrate[f[a, t], t ∈ Interval[{2, 4}]]

Guess what... The classical error "The integrand f[a,{NIntegrate`XR[1]}] has evaluated to non-numerical values for all sampling points in the region with boundaries {{2,4}}". Now, let us re-write the integral:

NIntegrate[f[a, t], {t, 2, 4}]

and suddenly there are no problems with the integrand, and the integral correctly evaluates to 60. Interval is also a geometric region:

RegionQ[Interval[{2, 4}]]
True

Does anyone understand what the problem is?

Update

I was asked by rhermans to provide more background on the problem: I want to use NMinimize to set parameters defining the integration region in order to find a region minimising an integral. The region can potentially consist of several regions. The nice thing about the Interval function is that it merges overlapping intervals into longer intervals.

An obvious workaround in my case is to split the integral into several integrals, one for each continuous interval using the range form of NIntegrate that works, and then add them together:

Apply[Plus, 
 Map[ NIntegrate[ f[a, t], Prepend[#, t] ] &, 
      Apply[List, ComputedInterval[AssignedParameters] ]
 ]];

The computed interval is based on the parameters set by NMinimize, and since a discontinuous interval is just a list of sub-intervals, the last Apply simply turns the interval into a list of continuous ranges that can be passed to NIntegrate. Not very elegant, but it bypasses the issue.

$\endgroup$
3
$\begingroup$

You are defining t as numeric (t_?NumericQ) and a region is not numeric, as the error message explained.

Mathematica graphics

Let's check

NumericQ[Interval[{2, 4}]]
False

This works

 f[a_, t_] := t^3;
 NIntegrate[f[a, t], t \[Element] Interval[{2, 4}]]
{60.}
$\endgroup$
  • 1
    $\begingroup$ This puzzles me for three reasons: First of all, the documentation for NIntegrate says that regions are supported and Interval[{2,4}] is a geometric region; second the error message actually does not complain about the interval but the non-numerical values of the integrand; thirdly, explicit indication of Numeric often makes NIntegrate work and here it does not. $\endgroup$ – Geir Dec 1 '14 at 11:10
  • $\begingroup$ @Geir Probably you could get the attention of more knowledgeable users to clarify your puzzlement. Update your post if you have further questions. remember taking the tour $\endgroup$ – rhermans Dec 1 '14 at 15:16
0
$\begingroup$

Every region has an embedding dimension that specifies the dimensions of the coordinates that make up the region. For example, a Circle object has embedding dimension 2:

RegionEmbeddingDimension[Circle[]]

2

and consequently every coordinate that is a member of a circle has dimension 2, e.g.

RegionMember[Circle[], {x, y}]

(x | y) ∈ Reals && x^2 + y^2 == 1

If we tried to check for membership with a coordinate with dimension 3:

RegionMember[Circle[], {x, y, z}]

RegionMember::realnl: {x,y,z} should be a real-valued point or list of points in dimension 2.

RegionMember[Circle[{0, 0}], {x, y, z}]

The exact same thing happens with Interval objects, which have region dimension 1:

RegionEmbeddingDimension[Interval[{2, 4}]]

1

and so every coordinate should have dimension 1:

RegionMember[Interval[{2, 4}], {x}]

x ∈ Reals && 2 <= x <= 4

It is also possible to test a symbolic coordinate:

RegionMember[Interval[{2, 4}], x]

Indexed[x, {1}] ∈ Reals && 2 <= Indexed[x, {1}] <= 4

Notice how Indexed[x, 1] is used in the result instead of just x. This is an indication that x actually represents a coordinate with dimension 1, i.e., something like {2}, and not just a plain number.

Now, it should be clear what is going wrong with your example. You are telling NIntegrate that t is a vector of length 1, and NIntegrate is expecting that t is a number instead. The fix is simple, either fix the membership condition:

a = 3;
NIntegrate[f[a, t], {t} ∈ Interval[{2, 4}]]

60.

or use Indexed in the integrand:

a = 3;
NIntegrate[f[a, Indexed[t, 1]], t ∈ Interval[{2, 4}]]

60.

$\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.