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

Unexpected behaviour of Stochastics/Deterministic variables in an 'if' statement. #103

Open
mar-ses opened this issue Apr 4, 2016 · 2 comments

Comments

@mar-ses
Copy link

mar-ses commented Apr 4, 2016

def forward_radius(Flux, Mass, A_const=A, C_const=C, sw=log_switchpoint):
    if(Flux < 10**sw.value):
        muR = C_const
        print('THERE')
    else:
        muR = A_const*log10(Flux) + C_const - A_const*sw
        print('HERE')
    return muR

R = np.empty(N, dtype=object)

for i in range(N):
    R[i] = pymc.Normal('R_%i' %i, mu = forward_radius(F[i], M[i], A, C, log_switchpoint), tau=tauR)

Hello, in the above example is an excerpt of my code. I was having a problem so I simplified the code to see exactly what was wrong and I figured it out.
R, F and M are arrays of length N containing pymc.Stochastic objects. A and C are hyperparameters (also pymc.Stochastic objects with a prior distribution).
The forward model is R[i] ~ Norm( mu = f(M[i], F[i], A, C, switchpoint), tau = ... )

The problem is that when the forward_radius() function is entered, the else: clause never seems to be activated. I put the print statements there to check when each is entered and when. Apparently what happens is that the condition only seems to be evaluated at the start of the run (persumably with the initial value of the Flux F[i]). The initial values seem to always be less than the switchpoint and so only the first if clause is every activated.
Is there something that I'm doing wrong which makes it so that the if-else clause is never evaluated during the actual sampling run?

@fonnesbeck
Copy link
Member

Can you prove that the condition ever evaluates to False to trigger the else condition? Also, what is Flux? Data?

@mar-ses
Copy link
Author

mar-ses commented Apr 6, 2016

Yes I believe so, I checked the traces of the F[i]. The Flux = F[i] are just variables that vary as a SkewNormal distribution dependent on i. Most of them should have had the condition evaluate to True.

Also, when I put the print('HERE/THERE') statements in, they only triggered during the first sample and then no more (and all were from True).

I fixed the problem by just making the whole thing a single Stochastic. When I did this, the condition did get evaluated every time and it now works.


def R_logp(value, Flux, A_const, C_const, tauR):
    sw=switchpoint
    if(Flux < sw):
        muR = C_const
    else:
        muR = A_const*log10(Flux) + C_const - A_const*log10(sw)
    return pymc.normal_like(x=value, mu=muR, tau=tauR)

def R_random(Flux, A_const, C_const, tauR):
    return np.random.normal(1.1,0.15)

R = np.empty(N, dtype=object)
for i in range(N):
    R[i] = pymc.Stochastic( logp = R_logp, 
                name = 'R_%i' %i,
                parents = {'Flux':F[i], 'A_const':A, 'C_const':C,
                    'tauR':tauR},
                random = R_random,
                trace = True,
                dtype = float,
                observed = False,
                plot = True, 
                doc = 'Forward modelled radius i') 

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

2 participants