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

Can't instantiate priors #503

Open
aplavin opened this issue May 12, 2017 · 7 comments
Open

Can't instantiate priors #503

aplavin opened this issue May 12, 2017 · 7 comments

Comments

@aplavin
Copy link

aplavin commented May 12, 2017

Many priors from 'GPy.priors' don't work at all:

In [2]: GPy.priors.Uniform()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-157dba2fded5> in <module>()
----> 1 GPy.priors.Uniform()

/home/aplavin/anaconda3/lib/python3.6/site-packages/GPy/core/parameterization/priors.py in __new__(cls, lower, upper)
    102                 if instance().lower == lower and instance().upper == upper:
    103                     return instance()
--> 104         o = super(Prior, cls).__new__(cls, lower, upper)
    105         cls._instances.append(weakref.ref(o))
    106         return cls._instances[-1]()

TypeError: object() takes no parameters
In [3]: GPy.priors.Uniform(0, 1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-33389462e27b> in <module>()
----> 1 GPy.priors.Uniform(0, 1)

/home/aplavin/anaconda3/lib/python3.6/site-packages/GPy/core/parameterization/priors.py in __new__(cls, lower, upper)
    102                 if instance().lower == lower and instance().upper == upper:
    103                     return instance()
--> 104         o = super(Prior, cls).__new__(cls, lower, upper)
    105         cls._instances.append(weakref.ref(o))
    106         return cls._instances[-1]()

TypeError: object() takes no parameters

same issue with Exponential. On the other hand, some priors do work:

In [5]: GPy.priors.Gamma(1, 2)
Out[5]: Ga(1, 2)

but only with explicitly specified parameters, otherwise:

In [3]: GPy.priors.Uniform(0, 1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-33389462e27b> in <module>()
----> 1 GPy.priors.Uniform(0, 1)

/home/aplavin/anaconda3/lib/python3.6/site-packages/GPy/core/parameterization/priors.py in __new__(cls, lower, upper)
    102                 if instance().lower == lower and instance().upper == upper:
    103                     return instance()
--> 104         o = super(Prior, cls).__new__(cls, lower, upper)
    105         cls._instances.append(weakref.ref(o))
    106         return cls._instances[-1]()

TypeError: object() takes no parameters
@michalisfrangos
Copy link

michalisfrangos commented Sep 13, 2017

Just commenting to mention I have tried your examples and I confirm the issue

For uniform, perhaps you can set a bound instead?

model.kern.variance.constrain_bounded(1,2)

@OwenThomas
Copy link

Hello,

Another bump for this issue, I am also experiencing it.

@ermeel86
Copy link

Same problem here with version 1.9.8 and InvGamma. Gamma works with two parameters but not InvGamma.

@JasperKirton
Copy link

HalfT doesn't work either... Anyone have trouble with Gamma fitting non-modal values under the log prior? seems to be out by a factor of 3 or so

@isaacmasher
Copy link

I got this issue as well (just upgraded to Python 3.8). Seems to be due to an issue in the __new__ method. InverseGamma has this (in GPy/core/parameterization/priors.py) and fails:

o = super(Prior, cls).__new__(cls, a, b)

Whereas Gamma has this and works:

newfunc = super(Prior, cls).__new__
if newfunc is object.__new__:
    o = newfunc(cls)  
else:
    o = newfunc(cls, a, b)

By swapping out I got InverseGamma to work. Probably similar for other priors.

@yeahyelina
Copy link

Did anyone solve this problem? I have the exactly same issue.
I tried the above one, but it fixed nothing.

@daniel-spies
Copy link

daniel-spies commented Apr 3, 2024

I got this issue as well (just upgraded to Python 3.8). Seems to be due to an issue in the __new__ method. InverseGamma has this (in GPy/core/parameterization/priors.py) and fails:

o = super(Prior, cls).__new__(cls, a, b)

Whereas Gamma has this and works:

newfunc = super(Prior, cls).__new__
if newfunc is object.__new__:
    o = newfunc(cls)  
else:
    o = newfunc(cls, a, b)

By swapping out I got InverseGamma to work. Probably similar for other priors.

this got it running for me though as it's called from another package (DP_GP) that is re-setting priors on each update with the shape and rate parameter I'm not sure if this is doing exactly what it' supposed to, so I also added the property blocks that are present in the Gamma class which seem to have been updated to handle this type of error:

class InverseGamma(Gamma):
    """
    Implementation of the inverse-Gamma probability function, coupled with random variables.

    :param a: shape parameter
    :param b: rate parameter (warning: it's the *inverse* of the scale)

    .. Note:: Bishop 2006 notation is used throughout the code
    """
    domain = _POSITIVE
    _instances = []
    def __new__(cls, a=1, b=.5): # Singleton:
        if cls._instances:
            cls._instances[:] = [instance for instance in cls._instances if instance()]
            for instance in cls._instances:
                if instance().a == a and instance().b == b:
                    return instance()
        newfunc = super(Prior, cls).__new__
        if newfunc is object.__new__:
            o = newfunc(cls)
        else:
            o = newfunc(cls, a, b)
        #o = super(Prior, cls).__new__(cls, a, b)
        cls._instances.append(weakref.ref(o))
        return cls._instances[-1]()
    
    @property
    def a(self):
        return self._a

    @property
    def b(self):
        return self._b

    def __init__(self, a, b):
        self._a = float(a)
        self._b = float(b)
        self.constant = -gammaln(self.a) + a * np.log(b)

    def __str__(self):
        return "iGa({:.2g}, {:.2g})".format(self.a, self.b)

    def lnpdf(self, x):
        return self.constant - (self.a + 1) * np.log(x) - self.b / x

    def lnpdf_grad(self, x):
        return -(self.a + 1.) / x + self.b / x ** 2

    def rvs(self, n):
        return 1. / np.random.gamma(scale=1. / self.b, shape=self.a, size=n)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants