5
$\begingroup$

I have a Check of the form

Check[expr,failexpr, {NIntegrate::slwcon}]

If expr throws slwcon, I would like to redo the calculation with higher precision by instead evaluating failexpr. But if there is still a problem even with higher precision (while evaluating failexpr), I need the error message to show so that I am aware of this. On the other hand, if expr throws slwcon, it should not show that error, since it is already handled and if it shows, I won't know if it's an error I already handled or not without explicitly checking the stack trace for every error, and that sucks!

There seems to be no solution to this using just Quiet[]:

If I try Quiet[expr, {NIntegrate::slwcon}] the check never activates and it never evaluates failexpr.

But if I put Quiet around the whole Check, then if the failexpr still fails, I get no error message so I never know about it. That is bad.

It seems like Check[] should just have the option (if not by default!) to quiet only expr, but not failexpr. But it's just not there. Is there a simple solution?

$\endgroup$
  • $\begingroup$ does this give what you need: Catch@Check[expr,Throw[failexpr], {NIntegrate::slwcon}]? $\endgroup$ – kglr Feb 28 at 10:58
  • $\begingroup$ Doesn't seem like it would. I still get an error if expr is handled by check, at least in a test case: Catch[Check[1/0, 23.1, {Power::infy}]] still shows the Power::infy error from the 1/0. I can't check my actual integral right now because it takes 6 hours of cpu time to get up to that computation. $\endgroup$ – doublefelix Feb 28 at 11:47
  • $\begingroup$ how about: quietRest = Function[{exp, failexp, ms}, Check[On[ms]; exp, Off[ms]; failexp, {ms}], HoldAll]; quietRest[1/0, {2/0, 3/4, 3/0}, Power::infy]? $\endgroup$ – kglr Feb 28 at 12:57
  • $\begingroup$ Still get quietRest[1/0, 23.1, Power::infy] giving Power::infy error, on mathematica 12.0. $\endgroup$ – doublefelix Feb 28 at 13:05
  • 1
    $\begingroup$ @kglr Perhaps Catch@Quiet[ Check[expr, Throw[Unevaluated@ failexpr], {NIntegrate::slwcon}], {NIntegrate::slwcon}]? The trick here is to keep failexpr from evaluating until it's outside Quiet. $\endgroup$ – Michael E2 Feb 28 at 13:23
6
$\begingroup$

Mmm, something like this?

ClearAll[try]
SetAttributes[try, HoldAllComplete]
try[expr_, failexpr_, messages : {___MessageName} | PatternSequence[]] := Module[
  {tag},
  ReleaseHold @ Catch[
    Quiet[
     Check[
      HoldComplete[#]& @ expr,
      Throw[HoldComplete[failexpr], tag],
      messages
     ],
     messages
    ],
    tag
   ]
 ]
| improve this answer | |
$\endgroup$
  • $\begingroup$ This works. I don't know how, because the syntax is kind of beyond me haha, but it works. I guess I should understand why, though. So now I am looking up a whole lot of syntax. $\endgroup$ – doublefelix Feb 28 at 14:03
  • $\begingroup$ Having a lot of trouble with message: {___MessageName} | PatternSequence[]. If you could give a brief general idea of what this should do it would be really helpful, even just a sentence or two $\endgroup$ – doublefelix Feb 28 at 14:10
  • 2
    $\begingroup$ @doublefelix That defines an argument called messages, (see :), that can be one of two things (see |): Either, a list of zero or more (see ___) MessageName expressions, or an empty sequence of arguments (see PatternSequence[]), meaning the argument can be left away $\endgroup$ – Lukas Lang Feb 28 at 14:59
  • $\begingroup$ Now I am trying to understand, if I use this function multiple times, do I have to keep setting the attribute to HoldAllComplete after each use or does it suffice to do so once before the initial definition? Sorry I am new (2 weeks) to mathematica. $\endgroup$ – doublefelix Feb 28 at 15:57
  • 1
    $\begingroup$ It is enough to evaluate these lines just once and then simply use try[foo, bar, ...]. $\endgroup$ – Anton.Sakovich Feb 28 at 16:38
2
$\begingroup$

A simple way to achieve the desired effect would be to write:

Quiet@Check[expr, $Failed, {NIntegrate::slwcon}] /. $Failed :> failexpr

If we are worried about a collision with the symbol $Failed, we can choose a different symbol or generate a new one, e.g.

Module[{failed}
, Quiet@Check[expr, failed, {NIntegrate::slwcon}] /. failed :> failexpr
]
| improve this answer | |
$\endgroup$
  • $\begingroup$ This is most likely the best answer and I only didn't test or implement it yet because I was in a time crunch and already had the other option implemented. Just to make other readers of the answer aware.. $\endgroup$ – doublefelix Apr 25 at 12:01

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.