Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: special: allow for more fine-tuned error handling #6753

Merged
merged 5 commits into from
Feb 12, 2017

Conversation

person142
Copy link
Member

Add new functions geterr and seterr and a context manager
errstate that control how special-function errors are handled. There
are now several categories of errors:

  • singular
  • underflow
  • overflow
  • slow
  • loss
  • no_result
  • domain
  • arg
  • other

which can each individually be set to 'ignore', 'warn', or
'raise'. This allows one to e.g. raise on interesting errors like loss
of precision while ignoring fairly routine errors like underflow.

The new functions/context manager work similarly to the eponymous
NumPy functions/context manager.

Closes gh-6681.

Example:

>>> import scipy.special as sc
>>> from numpy.testing import assert_raises
>>> sc.gammaln(0) # default error state is to ignore everything
inf
>>> with sc.errstate(singular='raise'):
...     with assert_raises(sc.SpecialFunctionError):
...         sc.gammaln(0) # raises
...     sc.spence(-1) # doesn't raise because this is a domain error
...
nan
>>> sc.gammaln(0) # original error state has been restored
inf

@person142 person142 added enhancement A new feature or improvement scipy.special labels Nov 2, 2016
@person142
Copy link
Member Author

@ev-br when you have the chance, I wonder if you could comment on whether you find this more pleasant to use than the current errprint + warnings.simplefilter way?

# Match to clpmn; DLMF 14.9.13
fixarr = where(mf > nf, 0.0, gamma(nf-mf+1) / gamma(nf+mf+1))
sv = errprint(sv)
with ufuncs.errstate(all='ignore'):
Copy link
Member

Choose a reason for hiding this comment

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

Minor, non-blocking: what's the reason to import it from private _ufuncs rather than public from scipy.special import errstate?

Copy link
Member Author

Choose a reason for hiding this comment

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

Probably not a good one. The imports at the top also import things from _ufuncs and I was trying to be consistent, but probably everything should just be cleaned up to use special instead. There are a couple of other spots like that lurking in the special tests. I wonder what the history is?

Copy link
Member

Choose a reason for hiding this comment

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

OK, I looked at git blame a bit down to

a6270c97 Lib/special/basic.py   (Travis Oliphant     2005-10-06 03:09:02 +0000   6) from _cephes import *

then on to

f41c1dae scipy/special/basic.py (Warren Weckesser    2010-11-20 16:49:57 +0000   8) from _cephes import ellipk, mathieu_a, mathieu_b, iv, jv, gamma, psi, zeta, \

and

da453dca scipy/special/basic.py (Martin Teichmann    2011-08-11 09:17:31 +0200   8) from _cephes import ellipkm1, mathieu_a, mathieu_b, iv, jv, gamma, psi, zeta, \

and then _cephes becomes _ufuncs:

08b56a03 scipy/special/basic.py (Pauli Virtanen      2012-10-07 04:07:09 +0300   9) from _ufuncs import ellipkm1, mathieu_a, mathieu_b, iv, jv, gamma, psi, zeta, \

followed by the Python 3 transition where the import becomes from ._ufuncs import ... also in 2012.

So yeah, it has always been like that :-), and I'm not sure there's much point messing with it. Scratch my comment above :-).

@ev-br
Copy link
Member

ev-br commented Nov 16, 2016

The errstate context manager definitely makes it nicer for a user in me!

I'm not sure if it's worth it to add a pair of geterr and seterr. I'd guess that numpy only has this pair because it predates the introduction of context managers in python. However I don't have a very strong opinion here, and I defer to you and Pauli on this and on whether to formally deprecate errprint or just ignore it.

The changes to sf_error I cannot meaningfully comment on, since I just don't understand it :-).

@person142
Copy link
Member Author

I do think there's one use case for seterr--doing something like sc.seterr(loss='raise') at the beginning of a script.

@ev-br
Copy link
Member

ev-br commented Nov 16, 2016

I do think there's one use case for seterr--doing something like sc.seterr(loss='raise') at the beginning of a script.

Indeed.

@ev-br
Copy link
Member

ev-br commented Jan 19, 2017

Can you rebase it please @person142

@ev-br ev-br added this to the 0.19.0 milestone Jan 19, 2017
@person142
Copy link
Member Author

Will do, but need to fix #6972 first.

Add new functions `geterr` and `seterr` and a context manager
`errstate` that control how special-function errors are handled. There
are now several categories of errors:

- singular
- underflow
- overflow
- slow
- loss
- no_result
- domain
- arg
- other

which can each individually be set to 'ignore', 'warn', or
'raise'. This allows one to e.g. raise on interesting errors like loss
of precision while ignoring fairly routine errors like underflow.

The new functions/context manager work similarly to the eponymous
NumPy functions/context manager.

Closes scipygh-6681.
@person142
Copy link
Member Author

Rebased; hopefully nothing breaks.

@ev-br
Copy link
Member

ev-br commented Feb 12, 2017

Merging, thanks Josh!

@ev-br ev-br merged commit 6607b47 into scipy:master Feb 12, 2017
@person142 person142 deleted the special-seterr branch March 12, 2017 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement A new feature or improvement scipy.special
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants