Avoiding the suppression of messages by NIntegrate
The answer below is for the first version of the question:
I'd really like to receive the messages from the integrand. How can I stop
NIntegrate
from suppressing the messages?
There are several reasons for this behavior. Generally speaking, NIntegrate
pre-evaluates and localizes the integrands in order to facilitate different symbolic pre-processing and numerics algorithms.
If we redefine the integrand with Piecewise
we will get the message once, when PiecewiseNIntegrate
does the preprocessing:
In[142]:= ClearAll[Test, test]
test[x_] := Piecewise[{{Message[Test::message]; x^2, 1 < x < 2}}, x];
NIntegrate[test[x], {x, 0, 3}]
During evaluation of In[142]:=
Test::message: -- Message text not found --
Out[144]= 5.33333
Further, we can prevent the symbolic processing with _?NumericQ
and use Print
or Echo
. (Note that the integral converges too slowly.)
ClearAll[Test, test]
test[x_?NumericQ] :=
If[1 < x < 2, (Echo[Row[{Test::message, " : ", x}]]; x^2), x];
NIntegrate[test[x], {x, 0, 3}, PrecisionGoal -> 2]
(*
Test::message : 1.08055
Test::message : 1.5
Test::message : 1.91945
...
5.34841 *)
I am not sure what kind of testing you want to do. You might consider using EvaluationMonitor
or IntegrationMonitor
instead.
I finally found a workaround to the message suppression that still allows the subdivision of the interval of integration $[0,3]$ at $x = 1, 2$. You have to protect the message-generating code sufficiently deep so that the symbolic processing takes care of the singularities. Then inside a ?NumericQ
protected function, turn on messages again by resetting $Messages
.
ClearAll[test, ftrue];
With[{$m = $Messages},
ftrue[x_?NumericQ] := Block[{$Messages = $m}, Message[Test::message]; x^2];
];
test[x_] := If[1 < x < 2, ftrue[x], x];
NIntegrate[test[x], {x, 0, 3}]
Message::msgl
:$MessageList
$MessageList
not a list; reset to{}
.
Test::message
: -- Message text not found --
Test::message
: -- Message text not found --
Test::message
: -- Message text not found --
General::stop
: Further output ofTest::message
will be suppressed during this calculation.
Out[56]= 5.33333
The extra message
There's an extraneous Message::msgl
that is the fault of NIntegrate
. (It doesn't seem to matter or wasn't detected, since messages are turned off.) It seems easy enough just to ignore it, but if that's unacceptable, you could reset $MessageList
yourself, or Quiet
the message:
If[! ListQ[$MessageList], $MessageList = {}]; (* OR *)
Quiet[Message[Test::message], Message::msgl];
Using this definition of ftrue
, you can see the message generation, even though the messages themselves are not printed:
ftrue[x_?NumericQ] := (
If[Length@$MessageList < 4, Print[$MessageList]];
Message[Test::message]; x^2);
NIntegrate[test[x], {x, 0, 3}]
$MessageList
{Message::msgl,Test::message}
{Message::msgl,Test::message,Test::message}
Out[69]= 5.33333
A glimpse at the symbolic processing
It may be of interest to inspect how NIntegrate
breaks down the integrand.
With the OP's test[]
, it looks like the following. We get three integration regions
NIntegrate[test[x], {x, 0, 3}, IntegrationMonitor :> ((regions = #) &), MaxRecursion -> 0];
Column[regions /. r_NIntegrate`GeneralRule :> Short[r], Dividers -> All]
With my version of test[]
, the x^2
in the first region in the table (from 1
to 2
) is replaced with ftrue[x]
.
Updated to issue a General::stop message
Maybe the following does what you want?
handler[Hold[Message[Test::message], True]] := With[
{stop = Flatten@Position[$MessageList, HoldForm[General::stop]]},
Which[
FreeQ[$MessageList[[stop-1]], HoldForm[Test::message]],
CellPrint @ Cell[
BoxData[Internal`MessageTemplate[Test, "message", "Test message", StandardForm]],
"Message","MSG"
];
If[Count[$MessageList, HoldForm[Test::message]] > 2,
CellPrint @ Cell[
BoxData[Internal`MessageTemplate[General, "stop", StringForm[General::stop, HoldForm[Test::message]], StandardForm]],
"Message", "MSG"
]
]
]
]
test[x_] := If[1<x<2, Message[Test::message];x^2, x];
Internal`HandlerBlock[{"Message", handler}, NIntegrate[test[x], {x,0,3}]]
Test::message: Test message
5.33333