Skip to content
This repository has been archived by the owner on Sep 26, 2021. It is now read-only.

Commit

Permalink
prevent some overflow exceptions in cot/csc
Browse files Browse the repository at this point in the history
  • Loading branch information
rwst committed Oct 1, 2016
1 parent d48f8e1 commit 08a2781
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions ginac/inifcns_trig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,8 +730,11 @@ REGISTER_FUNCTION(tan, eval_func(tan_eval).

static ex cot_evalf(const ex & x, PyObject* parent)
{
if (is_exactly_a<numeric>(x))
if (is_exactly_a<numeric>(x)) {
if (ex_to<numeric>(x).is_zero())
return UnsignedInfinity;
return tan(ex_to<numeric>(x)).inverse();
}

return cot(x).hold();
}
Expand Down Expand Up @@ -774,6 +777,8 @@ static ex cot_eval(const ex & x)

// cot(float) -> float
if (is_exactly_a<numeric>(x) && !x.info(info_flags::crational)) {
if (ex_to<numeric>(x).is_zero())
return UnsignedInfinity;
return tan(ex_to<numeric>(x)).inverse();
}

Expand Down Expand Up @@ -990,8 +995,11 @@ REGISTER_FUNCTION(sec, eval_func(sec_eval).

static ex csc_evalf(const ex & x, PyObject* parent)
{
if (is_exactly_a<numeric>(x))
if (is_exactly_a<numeric>(x)) {
if (ex_to<numeric>(x).is_zero())
return UnsignedInfinity;
return sin(ex_to<numeric>(x)).inverse();
}

return csc(x).hold();
}
Expand Down Expand Up @@ -1036,6 +1044,8 @@ static ex csc_eval(const ex & x)

// csc(float) -> float
if (is_exactly_a<numeric>(x) && !x.info(info_flags::crational)) {
if (ex_to<numeric>(x).is_zero())
return UnsignedInfinity;
return sin(ex_to<numeric>(x)).inverse();
}

Expand Down

4 comments on commit 08a2781

@paulmasson
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd really like to know what is the point of this commit. Both cot() and csc() have many more poles than the origin. What does this commit fix?

@rwst
Copy link
Member Author

@rwst rwst commented on 08a2781 Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I explained this already. The only exact numeric value that can go into inverse() is zero. All others are inexact. Otherwise the doctest that fails is:

File "src/sage/functions/trig.py", line 268, in sage.functions.trig.Function_cot.__init__
Failed example:
    cot(float(0))
Exception raised:
    Traceback (most recent call last):
      File "/home/ralf/sage/local/lib/python2.7/site-packages/sage/doctest/forker.py", line 498, in _run
        self.compile_and_execute(example, compiler, test.globs)
      File "/home/ralf/sage/local/lib/python2.7/site-packages/sage/doctest/forker.py", line 861, in compile_and_execute
        exec(compiled, globs)
      File "<doctest sage.functions.trig.Function_cot.__init__[16]>", line 1, in <module>
        cot(float(Integer(0)))
      File "sage/symbolic/function.pyx", line 996, in sage.symbolic.function.BuiltinFunction.__call__ (build/cythonized/sage/symbolic/function.cpp:11008)
        res = super(BuiltinFunction, self).__call__(
      File "sage/symbolic/function.pyx", line 488, in sage.symbolic.function.Function.__call__ (build/cythonized/sage/symbolic/function.cpp:6241)
        res = g_function_eval1(self._serial,
    OverflowError: numeric::inverse(): division by zero

@rwst
Copy link
Member Author

@rwst rwst commented on 08a2781 Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I explained this already. The only exact numeric value that can go into inverse() is zero. All others are inexact. Otherwise the doctest that fails is:

File "src/sage/functions/trig.py", line 268, in sage.functions.trig.Function_cot.__init__
Failed example:
    cot(float(0))
Exception raised:
    Traceback (most recent call last):
      File "/home/ralf/sage/local/lib/python2.7/site-packages/sage/doctest/forker.py", line 498, in _run
        self.compile_and_execute(example, compiler, test.globs)
      File "/home/ralf/sage/local/lib/python2.7/site-packages/sage/doctest/forker.py", line 861, in compile_and_execute
        exec(compiled, globs)
      File "<doctest sage.functions.trig.Function_cot.__init__[16]>", line 1, in <module>
        cot(float(Integer(0)))
      File "sage/symbolic/function.pyx", line 996, in sage.symbolic.function.BuiltinFunction.__call__ (build/cythonized/sage/symbolic/function.cpp:11008)
        res = super(BuiltinFunction, self).__call__(
      File "sage/symbolic/function.pyx", line 488, in sage.symbolic.function.Function.__call__ (build/cythonized/sage/symbolic/function.cpp:6241)
        res = g_function_eval1(self._serial,
    OverflowError: numeric::inverse(): division by zero

@rwst
Copy link
Member Author

@rwst rwst commented on 08a2781 Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See Sage ticket, my answer here is silently removed apparently.

Please sign in to comment.