-
Notifications
You must be signed in to change notification settings - Fork 31
Add unknown T₂, Gaussian hyperparameterized models. #146
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good addition.
src/qinfer/derived_models.py
Outdated
## METHODS ## | ||
|
||
def domain(self, expparams): | ||
return [RealDomain()] * len(expparams) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
domain()
Should support "in the case where n_outcomes_constant
is True
, None
should be a valid input".
This requirement is a side-effect of my poor code design IMO, however, we should stick to it until something smoother comes along.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, good catch, thank you. I'll go on and fix that, then.
src/qinfer/derived_models.py
Outdated
# (idx_underlying_outcome, idx_outcome, idx_modelparam, idx_experiment). | ||
# Thus, we need shape | ||
# (idx_underlying_outcome, 1, idx_modelparam, 1). | ||
mu = (modelparams[:, -4:-2].T)[:, None, :, None] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
np.newaxis
is used a bit more consistently elsewhere, I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I was being a bit sloppy here, but np.newaxis
is much easier to read. I'll fix that, then.
src/qinfer/derived_models.py
Outdated
return True | ||
|
||
def are_models_valid(self, modelparams): | ||
orig_mps = modelparams[:, :-4] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI negative indexes (rather than absolute indexes based on underlying_model.n_modelparams
) have occasionally caused me trouble when another decoration model is above. However, I don't think anything in the code base actually cares, and I think other models might use negative indexes too, so don't change it if you don't want to. It mostly comes up when I am manually jiggering things in a notebook, and have many models and many updaters on the go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's easy enough to split things out in a more robust way, which would really help for more complicated model chains. Thanks for pointing that out!
(modelparams[:, -2:].T)[:, None, :, None] | ||
) | ||
|
||
assert np.all(sigma > 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this left-over from prototyping?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very likely, I should either remove it or make it an actual exception.
src/qinfer/test_models.py
Outdated
:modelparam T2_inv: The decoherence strength :math:`T_2^{-1}`. | ||
:scalar-expparam float: The evolution time :math:`t`. | ||
""" | ||
# TODO: add duecredit.cite. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
src/qinfer/derived_models.py
Outdated
|
||
# Now we marginalize and return. | ||
L = (underlying_L * conditional_L).sum(axis=0) | ||
assert not np.any(np.isnan(L)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this left-over from prototyping?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same answer here, sorry for missing them both.
The 4 CI failures look like they have nothing to do with this PR. Are they due to a new numpy thing? |
Thanks for the review, @ihincks! I'll go on and fix those ASAP. As far as the CI failures, I think that's leftover from #135, and is due to NumPy finally making something an error that was a |
Consider throwing a test or two into
|
This looks great. I agree with @ihincks it is a good addition. It seems as we move forward experimentally there is an increasing focus on continuous outcome distributions. Once I find more time I want to focus on explicitly supporting continuous outcomes (right now IIRC it is maybe hinted at in the documentation but left to the user to figure out how to support them). This would also include supporting the branch me and Ian have been working on to support continuous outcomes natively include experiment design in |
Sounds great, @taalexander! Thanks as well for the typo catch, @ihincks. I think this might be good to go once I can get the CI builds working. Would anyone mind if I merge in #135, since CI seems to work there again? That would mean deprecating 3.3 in favor of Python 2.7 or ≥ 3.4. Since 3.3 is now approximately six years old, I don't think that should be a problem... |
src/qinfer/derived_models.py
Outdated
# Next, we sample a bunch of underlying outcomes to figure out | ||
# how to rescale everything. | ||
underlying_outcomes = self.underlying_model.simulate_experiment( | ||
modelparams[:, :-4], expparams |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
repeat=repeat
i think will fix the other shape mismatch bug
src/qinfer/derived_models.py
Outdated
assert np.all(sigma > 0) | ||
|
||
# Now we can rescale the outcomes to be random variates z drawn from N(0, 1). | ||
scaled_outcomes = (outcomes - mu) / sigma |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
outcomes[np.newaxis,:,np.newaxis,np.newaxis]
will fix one of the shape bugs?
i think numpy must have changed how it assigns to fancy dtypes at some point
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Go ahead when ready.
I removed init because it was causing a failure; was unaware of its involvement in dcite mechanics. Thanks for fixing.
Awesome, thanks for everything! 💕 |
This PR adds two new models, one which learns Rabi frequencies with unknown T₂ processes, the other of which decorates two-outcome models with Gaussian hyperparameters based on a latent two-outcome variable. This allows for using QInfer to learn T₂ in cases where single-shot measurements are not directly observed, but are only observed through a secondary process that is Gaussian distributed.