On Thu, Aug 6, 2009 at 6:37 PM, Pierre GM<pgmdevlist@gmail.com> wrote:
>> On Aug 6, 2009, at 6:21 PM, Robert Kern wrote:
>>>> It should be noted that the location parameter changes the support
>> domain *as a consequence* of the above transformation. Changing the
>> support domain (and holding everything else fixed) is not the defining
>> characteristic of the location parameter.
>> Got the point. I'll make a mental note to mention that in the docs.
>> I'm switching to "meh" mode: I still think that allowing for the shift
> can lead to some troubles on the user, and I'd be in favor to modify
> _fix_loc_scale or something like that to force loc=0 on discrete
> distributions with support on positive integers, but I'll certainly
> not lose any sleep other that...
> In any case, thx a lot to y'all for your comments.
>
I agree that loc for distribution with a finite upper or lower support
bound is confusing, at least at the beginning. It took me a while to
figure out why I get some strange results with some distributions when
I ran a fit over all of them until I realized that the support is
shifted when loc is estimated. But I think this is mostly a
documentation problem.
(I still have an unresolved problem with vonmises which doesn't define
it's support points, but I don't know anything at all about circular
distributions.)
Below is a prototype for a semi-frozen class, essentially an adapted
version of the frozen class, that fixes only the location loc. (copy
and paste errors still possible)
However, this doesn't do anything different than the current
implementation if you ignore the loc keyword. It also has the same
uninformative signature which could be improved.
The only real advantage I see, is, when the fit method is adjusted to
take some of the parameters as fixed.
Josef
import numpy as np
from scipy import stats
class rv_frozenloc(object):
def __init__(self, dist, loc=0):
self.loc = loc
self.dist = dist
def pdf(self,x,*args,**kwds):
kwds.update({'loc':self.loc})
return self.dist.pdf(x,*args,**kwds)
def cdf(self,x,*args,**kwds):
kwds.update({'loc':self.loc})
return self.dist.cdf(x,*args,**kwds)
def ppf(self,q,*args,**kwds):
kwds.update({'loc':self.loc})
return self.dist.ppf(q,*args,**kwds)
def isf(self,q,*args,**kwds):
kwds.update({'loc':self.loc})
return self.dist.isf(q,*args,**kwds)
def rvs(self, size=None,*args,**kwds):
kwds.update({'loc':self.loc, 'size':size})
return self.dist.rvs(*self.args,**kwds)
def sf(self,x,*args,**kwds):
return self.dist.sf(x,*args,**kwds)
def stats(self, moments='mv',*args,**kwds):
kwds.update({'loc':self.loc, 'moments':moments})
return self.dist.stats(*args,**kwds)
def moment(self,n,*args,**kwds):
kwds.update({'loc':self.loc})
return self.dist.moment(n,*args,**kwds)
def entropy(self,*args,**kwds):
kwds.update({'loc':self.loc})
return self.dist.entropy(*args,**kwds)
def pmf(self,k,*args,**kwds):
kwds.update({'loc':self.loc})
return self.dist.pmf(k,*args,**kwds)
def freezeloc(dist, loc=0):
return rv_frozenloc(dist, loc=loc)
poiss = freezeloc(stats.poisson)
print poiss.pmf(np.arange(10),5)
print poiss.cdf(np.arange(10),5)
print poiss.cdf(np.arange(10),5, loc=5) #this ignores loc but doesn't
raise warning (yet)
print stats.poisson.cdf(np.arange(10),5, loc=5)
poiss5 = freezeloc(stats.poisson, loc=5)
print poiss5.cdf(np.arange(10),5)
norm0 = freezeloc(stats.norm, loc=1)
print norm0.stats()
norm0.stats(loc=0) # loc is ignored but doesn't raise warning (yet)
print norm0.stats(scale=np.sqrt(2))