# Is there a message for functions evaluating to infinity?

Everyone has perhaps been irritated by the Power::infty message:

Cos[0]/Sin[0]


Power::infy: Infinite expression 1/0 encountered. >>

(*  ComplexInfinity  *)


But I want such a message in case like this:

Cos[x]/Sin[x] /. x -> 0
(*  ComplexInfinity  *)


There is no message because Cos[x]/Sin[x] evaluates to Cot[x], and Cot[0] evaluates to ComplexInfinity without a warning. Similarly Log[0] evaluates to -Infinity without warning.

Is there a system option or message that can be turned on so that expressions like Cot[0] and Log[0] give a warning?

Notes:

• These functions may be embedded in larger expressions.
• It is possible that the infinity will eventually generate an error as it propagates through a computation. But it's also possible that a finite number will be divided by infinity and evaluate to 0, like 1/ComplexInfinity, in which case it might be a disaster:

1 + 1/(1 + Log[0])
(*  1  *)

• Limit[Cos[x]/Sin[x], x -> 0] or FullSimplify[Cos[x]/Sin[x]] /. x -> 0? No errors. – David G. Stork Mar 9 '16 at 16:28
• On the flip side, when I had an application dealing with ratios of gamma functions, it was convenient that the reciprocal of a gamma function evaluated at a nonpositive integer evaluated to 0… – J. M. will be back soon Mar 9 '16 at 16:29
• @J.M. Yes, I meant it only might be a disaster. – Michael E2 Mar 9 '16 at 16:32
• For example, docs for Log[ ] states Zero and infinite arguments give symbolic results: So if you want error messages you'll need to redefine to your own functions – Dr. belisarius Mar 9 '16 at 16:33
• @DavidG.Stork Maybe it wasn't clear: I want to get an error. – Michael E2 Mar 9 '16 at 20:00

### Redefinition of DirectedInfinity

One way would be to add a DownValue to DirectedInfinity (the final form suggested by MicahelE2):

Unprotect[DirectedInfinity];
Clear[DirectedInfinity];
DirectedInfinity::infy = "Infinite Expression encountered";
DirectedInfinity /: call_DirectedInfinity /; ! TrueQ[inInf] :=
Block[{inInf = True},
Update[DirectedInfinity];
Message[DirectedInfinity::infy];
call
];
Protect[DirectedInfinity];


So that, for example

1 + 1/(1 + Log[0])


During evaluation of In[67]:= DirectedInfinity::infy: Infinite Expression encountered >>

During evaluation of In[67]:= DirectedInfinity::infy: Infinite Expression encountered >>

1

The call to Update is necessary to prevent an internal optimization, that would otherwise result in the messages being suppressed on subsequent calls of DirectedInfinity.

### A safer version using local environment

Note that this isn't a safe modification, since it globally modifies a built-in function. As such, it may have unanticipated consequences. A safer way to do this would be to use InternalInheritedBlock, and a dynamic environment to wrap around a piece of code you want to evaluate in this mode.

First, we have to remove the changes we made:

Unprotect[DirectedInfinity];
Clear[DirectedInfinity];
Protect[DirectedInfinity];


Here is a reasonably general generator of such dynamic environments:

ClearAll[withRedefined];
SetAttributes[withRedefined, HoldRest];
withRedefined[f_Symbol,beforeCall_,afterCall_, extraCode_]:=
Function[code,
InternalInheritedBlock[{f},
Module[{inF, dv=DownValues[f]},
With[{protected = Unprotect[f]},
DownValues[f]={};
extraCode;
(call:f[args___])/;!TrueQ[inF]:=
Block[{inF=True},
beforeCall[args];
With[{res = call},
afterCall[args, res];
res
]
];
DownValues[f]=Join[DownValues[f],dv];
Protect[protected];
];
code
]
],
HoldAll
];


With this function, we can create our custom dynamic environment easily:

withMessageOnInfinity =
withRedefined[
DirectedInfinity
,
Function[
Update[DirectedInfinity];
Message[DirectedInfinity::infy]
]
,
Function[Null]
,
DirectedInfinity::infy = "Infinite Expression encountered";
];


So now we have without dynamic environment just the usual behavior:

1 + 1/(1 + Log[0])

(* 1 *)


while using the environment we get:

withMessageOnInfinity[1 + 1/(1 + Log[0])]


During evaluation of In[21]:= DirectedInfinity::infy: Infinite Expression encountered >>

1

• Thank you. I always learn something from your code generation examples. – Michael E2 Mar 13 '16 at 12:10
• @MichaelE2 Glad to help, as always. Thanks for the accept. – Leonid Shifrin Mar 13 '16 at 15:52