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

Separate the physical model into a Model class #104

Merged
merged 18 commits into from
Nov 19, 2021

Conversation

BoxiLi
Copy link
Member

@BoxiLi BoxiLi commented Oct 22, 2021

Previously, the Hamiltonian model in Processor is saved as partially initialized pulses. This PR separate the Hamiltonian model from pulse and the Processor class. It can now be defined independently and includes only the information of the Hamiltonian. The pulses will only be generated after the circuit is loaded.

The main changes are in processor.py. In particular in the initialization. The others are either docs change or internal updates to fit this new structure. A bunch of getter functions are added to support the old way of building the Hamiltonians using the Processor. The data is, however, always saved in Model.

In principle ModelProcessor can be merged into Processor, but it is best to wait for another PR.

There are a few FIXME that are used to remind me to revisit some details later in a different PR. They are unrelated to the Hamiltonian model.

@nathanshammah @quantshah

Issue #98

TODO

  • Add more tests
  • Check compatibility with existing notebooks.

Breaking changes

  • The pulse will not be generated before loading the circuit. So inquiring the Hamiltonian operator through pulse will only return an empty list. One should now use e.g. Processor.get_control("sx0") for this.
  • Processor.get_operators_labels() is renamed as get_latex_str for clearity.

@BoxiLi BoxiLi force-pushed the model-class branch 2 times, most recently from eb1e853 to 8db0a2a Compare October 24, 2021 17:58
Previously, the Hamiltonian model in `Processor` is saved as partially initialized pulses. This commit separates the Hamiltonian model from pulse and the `Processor` class. It can now be defined independently and includes only the information of the Hamiltonian. The pulses will only be generated after the circuit is loaded.

Breaking changes:

- processor.pulses will no longer be created while defining the Hamiltonian model. This means that using it to check the available Hamiltonians before loading the circuit will fail. A proper warning will be added in a later commit. Instead, one should use set_coeffs and set_tlist to generate pulses first. Also, because in Model, a dictionary is used to store the Hamiltonian, the order of the generated pulse will also be different than before.
- replace get_operator_labels by get_latex_str. This is just to make the name clearer. A proper warning will be added in later commits.
Rewrite the initialization in subclasses to incorporate the new model class. In each subclass of Processor, a model is first created and passed to the initializer of the Processor class.
The key word argument start was added from python 3.8+
@BoxiLi BoxiLi force-pushed the model-class branch 3 times, most recently from 2f1617d to eb153e6 Compare November 9, 2021 11:44
Model parameters should be defined while initialization and should not be updated in Processor. This is because updating will not trigger the _compute_params method in the model, making the parameters outdated or incomplete.
Copy link
Member

@nathanshammah nathanshammah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments and suggestions.

Actually the code climate issues seem reasonable and could be actioned upon: besides blank spaces, there is a chunk of code involving pulses that maybe could be refactored in a private function.

Great to see these additions and the thorough testing.

@@ -159,19 +159,19 @@ To let it find the optimal pulses, we need to give the parameters for :func:`~qu


# Same parameter for all the gates
qc = QubitCircuit(N=1)
qc = QubitCircuit(1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
qc = QubitCircuit(1)
qc = QubitCircuit(1)

just a question, why did you delete "N=" here and elsewhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to discourage the use of capital N as the number of qubits, and eventually replace it with num_qubits, to be consistent.

But maybe this should not be included here in this PR, I agree. I can revert it if desired.


class CavityQEDModel(Model):
"""
The physical model for a dispersive cavity-QED system.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The physical model for a dispersive cavity-QED system.
The physical model for a dispersive cavity-QED system.

shall we change "system" with "processor"? Is there any other detail to add?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add brief details about the model Hamiltonian (should be the Tavis-Cummings Hamiltonian).

src/qutip_qip/device/cavityqed.py Outdated Show resolved Hide resolved
src/qutip_qip/device/cavityqed.py Outdated Show resolved Hide resolved
src/qutip_qip/device/circuitqed.py Outdated Show resolved Hide resolved
def get_noise(self) -> List[Noise]:
"""
Get a list of :obj:`.Noise` objects.
Single qubit relaxation (T1, T2) are not included here.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are the local T1 and T2 not included here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah there is a trade-off. They are not included here because they are defined just as two numbers and will be handled in the processor. I can add them directly here but then whoever implements their own Model will need to do it themselves.

On the other hand, separating them is indeed a bit strange. Now looking at them again, I think it might be better to include also T1 T2 here. Whoever implements a custom model will need to do their own homework, which should not be that difficult if they are already at this stage.

@BoxiLi
Copy link
Member Author

BoxiLi commented Nov 9, 2021

@nathanshammah

there is a chunk of code involving pulses that maybe could be refactored in a private function.

Which part do you mean?

@nathanshammah
Copy link
Member

Is this ready for review? The part of code I refer to is the one picked by code climate,

  if isinstance(coeffs, dict):
            pulse_dict = self.get_pulse_dict()
            for pulse_name, value in coeffs.items():
                if pulse_name in pulse_dict:
                    self.pulses[pulse_dict[pulse_name]].coeff = value

anyways, this is fixed now.

@BoxiLi
Copy link
Member Author

BoxiLi commented Nov 16, 2021

Is this ready for review?

Yes.

I think it is better to leave a more thorough doc including math equations in a separate PR and get this merged first. We can also update them after the resubmission.

Copy link
Member

@nathanshammah nathanshammah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @BoxiLi.

@nathanshammah nathanshammah merged commit 995f8e3 into qutip:master Nov 19, 2021
@BoxiLi BoxiLi deleted the model-class branch November 25, 2021 08:40
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

Successfully merging this pull request may close these issues.

3 participants