[Scipy-tickets] [SciPy] #766: inconsistent behavior of scipy.stats.distributions.rv_continous.isf

SciPy scipy-tickets@scipy....
Thu Oct 30 12:22:28 CDT 2008


#766: inconsistent behavior of scipy.stats.distributions.rv_continous.isf
-------------------------+--------------------------------------------------
 Reporter:  pbrod        |       Owner:  somebody
     Type:  enhancement  |      Status:  new     
 Priority:  normal       |   Milestone:          
Component:  scipy.stats  |     Version:          
 Severity:  normal       |    Keywords:          
-------------------------+--------------------------------------------------
 In the documentation of rv_continous class in the scipy.stats.distribution
  it says that for speed and/or accuracy you can over-ride

      _cdf, _ppf, _rvs, _isf, _sf

 However, it is not possible to override _isf method because it is never
 called from the isf method. The isf method calls the _ppf method instead.
 This means that it is not possible to increase the accuracy in eg. upper
 tail/ probabilities.

 In extreme value statistics this is important because one is interested in
 the extreme tails.

 Here is an example showing that the inverse survival function for the
 generalized pareto distribution is inaccurate for small probabilities:
 {{{
 genpareto.isf(genpareto.sf(300,0.1),0.1)
 299.97003226143124
 }}}



 To fix this inconsistency replace the current isf and _isf methods in the
 rv_continous class with
 {{{
  def isf(self,q,*args,**kwds):
         loc,scale=map(kwds.get,['loc','scale'])
         args, loc, scale = self.__fix_loc_scale(args, loc, scale)
         q,loc,scale = map(arr,(q,loc,scale))
         args = tuple(map(arr,args))
         cond0 = self._argcheck(*args) & (scale > 0) & (loc==loc)
         cond1 = (q > 0) & (q < 1)
         cond2 = (q==1) & cond0
         cond = cond0 & cond1
         output = valarray(shape(cond),value=self.b)
         place(output,(1-cond0)*(cond1==cond1), self.badvalue)
         place(output,cond2,self.a)
         goodargs = argsreduce(cond, *((q,)+args+(scale,loc)))
         scale, loc, goodargs = goodargs[-2], goodargs[-1], goodargs[:-2]
         place(output,cond,self._isf(*goodargs)*scale + loc)
         if output.ndim == 0:
             return output[()]
         return output

     def _isf(self, q, *args):
         return self._ppf(1.0-q,*args)
 }}}

-- 
Ticket URL: <http://scipy.org/scipy/scipy/ticket/766>
SciPy <http://www.scipy.org/>
SciPy is open-source software for mathematics, science, and engineering.


More information about the Scipy-tickets mailing list