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

Simulating Pulse Trains #213

Open
adriendilonardo opened this issue Oct 11, 2022 · 4 comments
Open

Simulating Pulse Trains #213

adriendilonardo opened this issue Oct 11, 2022 · 4 comments
Assignees
Labels
enhancement Requesting improvements to an existing functionality

Comments

@adriendilonardo
Copy link
Collaborator

Please describe the expected enhancement

Context

  • Simulating some pulse trains by simulating every single time step is inefficient
  • Some pulse segments can be simulated in a single step with a unique analytical unitary form/creation method
    • e.g. single qubit rotation gates or Jaynes-Cummings unitaries
  • Some pulse segments are simulated using ordinary simulations of time-dependent systems
    • e.g. simulating a transmon under a drag pulse field
  • Some pulse segments will be repeated in a pulse train while others will be differ from prior segments by only some single-step post-processing
    • e.g. the unitary of the falling edge of a smooth trapezoidal pulse is the transpose of the rising edge unitary

Suggested Implementations

Instead of using nested simulations to simulate these pulse trains, we should use nested protocols:

risingEdge = qg.pulse(system=total_sys, simulation=simulation)
flatTop = qg.protocol(system=total_sys, createUnitary=qg.UJC)
fallingEdge = risingEdge.transpose

pulseTrain = qg.protocol(steps=[risingEdge, flatTop, fallingEdge])

There are some key points to this implementation:

  • The pulseTrain protocol generates its unitary in a single step, getting the unitaries from each of the protocols nested within it
  • Here risingEdge is a special protocol class: a pulse object. These objects generate their unitaries using their own simulation
  • The flatTop protocol generates its unitary in a single step using any user-defined function. Here, its unitary creation method points at the built in UJC function
  • The fallingEdge object is a copyStep whose superSys is the risingEdge pulse object. The unitary is generated and stored within itself by applying any user defined function to the unitary of the risingEdge object. Here, the function is a transpose function, however, risingEdge.fnName for any arbitrary user-defined function fnName will suffice.

Note the unitary for fallingEdge should be stored within ITSELF

@adriendilonardo adriendilonardo added the enhancement Requesting improvements to an existing functionality label Oct 11, 2022
@github-actions
Copy link

Branch 213-Simulating_Pulse_Trains created!

github-actions bot pushed a commit that referenced this issue Oct 11, 2022
@github-actions
Copy link

Could not create PR (Update is not a fast forward)

@cahitkargi
Copy link
Collaborator

cahitkargi commented Oct 13, 2022

Let's discuss and divide it into tasks that we can individually implement. we want:

  • to be able to create the unitary of a protocol/step by running its internal simulation (I think this will be implemented as part of Changing simulation structure #211 ?). we may not need a new class for this.
  • to be able to use user-defined methods for unitary creation instead of simulation
  • a generic method to be able to apply any matrix operation on protocol unitary to use it as another step of the protocol
    • to store the transformed unitary in the copy-step but still be _paramUpdated aware.

Is this list complete?

@adriendilonardo
Copy link
Collaborator Author

adriendilonardo commented Oct 17, 2022

Yes, this list is complete :)

Just some notes in response to the first dot point:

  • I think the use of a protocols own simulation object to generate its unitary falls outside of issue Changing simulation structure #211
  • Issue Changing simulation structure #211 is less of a priority for simulating pulse trains, since Changing simulation structure #212 now completely encompasses the tools needed to do this
  • Although creating a new class may not be necessary for the implementation of issue Simulating Pulse Trains #213, I think it makes it clear to users how the unitary will be generated for any given set of nested protocols
    • In fact, I think it is more conceptually consistent to create a new child class (perhaps called "pulse")
    • Any implementation where the protocol uses its own simulation to generate the unitary requires that the _createUnitary method point to some function where the protocol's simulation object is run
    • Currently, all protocol child classes are more specialised protocol classes which generate specific types of unitaries
    • The main difference between these child classes is what function their _createUnitary method points to
    • It makes sense to me that we should have a new protocol child class which specialises in generating unitaries from their simulation objects

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

No branches or pull requests

2 participants