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

Types/labels indicating quantum pictures #8

Open
i2000s opened this issue Jan 6, 2015 · 5 comments
Open

Types/labels indicating quantum pictures #8

i2000s opened this issue Jan 6, 2015 · 5 comments

Comments

@i2000s
Copy link

i2000s commented Jan 6, 2015

As discussed in #7, we may want to define types/labels to denote quantum pictures of the workspace. Transformation of propagators and states between different pictures may be also helpful.

@i2000s i2000s added this to the Initial Release milestone Jan 6, 2015
@jrevels
Copy link
Contributor

jrevels commented Jan 7, 2015

Hmmm. We're talking about the same types of quantum objects no matter which picture we're in - what changes is those objects' dynamical behavior with respect to each other. In that sense, I'm not sure that a picture is a "property" of any quantum object, but rather a specification on how we define that object's dynamic relationship to other objects.

Perhaps the solution, then, is to namespace picture-specific functions by putting them in submodules; then you could define Schrodinger.schrodinger_version_of_an_evolution(state::QuVector) and Heisenburg.heisenburg_version_of_an_evolution(operator::QuMatrix).

The above is a pretty silly example, since if that's all we were going to do we could just utilize multiple dispatch to have an_evolution(state::QuVector), and an_evolution(operator::QuMatrix)...what is the use case for disambiguating the "picture" to which special constructors and evolution functions belong that can't already be done through multiple dispatch?

(Note: when I say quantum object, I mean states and operators.)

@i2000s
Copy link
Author

i2000s commented Jan 8, 2015

The idea of tagging pictures makes sense only when we have propagator or evolution operator defined in a quantum dynamics calculation. We can consider the following scenario that a user defines the Hamiltonian with a Schrodinger picture tag, then the evolutionary operator or the propagator as a function of a given time list can be generated, then he can define all the other quantum operators he needs in the Schrodinger picture simply and clearly without involving any time-dependent parts. After that, he wants to calculate the time evolution of the expectation value of the particle number operator in the Heisenberg picture, and hence he can just switch the picture label and plug the initial state, the propagator and the number operator into an equation of motion solver and retrieve the result in the Heisenberg picture. Now he wants to calculate how the state of the system evolve in the Interaction picture. He can just point out to the computer the propagator and the bare Hamiltonian for the system, and switch the workspace to be Interaction picture, the transformation relationship between Heisenberg and Interaction picture is uniquely defined by the QuBase.jl he is using. When he inserts the input operators and states into some dynamics solver, he just use the operators and states that have been defined initially in the Schrodinger picture and the output objects will be automatically aligned to the Interaction picture as he wants. In the last step, the solver just recall QuBase.jl to do the switching work. In this way, users of the programs do not need to redefine operators and states separately when switching representations as a result of tagging picture labels to the workspace. Do you guys think this is useful and implementable?

It hasn't been clear to me how should we easily implement this feature. The label may not necessarily be a global variable, it could be just attached to particular quantum objects. But here are the things in my mind we need to work out for the minimum of work/requirements:

  • Define a specific type for propagators or evolution operators. Set a default picture to this type.
  • Define&Distinguish Hamiltonian operator as a particular type for system, environment and anything else. This can be optional.
  • Define some transformation rules for switching between basic pictures. The core function can be defined separately for the transformation rules for types including vector states, density operators, Hamiltonians, propagators and other operators using the dispatch feature of Julia. From this part, you may see some benefit that we clearly distinguish basic types for quantum objects in Julia.
  • Let the picture label and transformation rules customizable so that users can define their own representations. This makes this feature extensible to arbitrary rotation frames and phase spaces beyond the basic quantum picture representations.

@acroy
Copy link
Contributor

acroy commented Jan 8, 2015

Like you both said, the different pictures only make sense if you have information about the time evolution. A quantum object given by a QuArray doesn't know about this. My ad hoc idea would be to have types, which contain a state or an operator (a QuArray) and a propagator. Additionally, we would need (a) time label(s). Roughly,

type HeisenbergPic{QA,P}
    qa::QA
    p::P
    t::Real
end

Then you could for instance define multiplication, such that HeisenbergPic(a,p,t)*HeisenbergPic(b,p,t)=HeisenbergPic(a*b,p,t) and so on. A function evaluate could return the QuArray representing the operator at time t. The advantage of having "Picture" types would be that we can possibly reduce the number of propagations, which are costly.

@jrevels
Copy link
Contributor

jrevels commented Jan 9, 2015

What about the following?

abstract Picture
abstract Heisenberg <: Picture
abstract Schrodinger <: Picture

type PicturedObj{P<:Picture, PR, Q}
    prop::PR
    obj::Q
end

PicturedObj{P<:Picture,Q,PR}(::Type{P}, prop::PR, obj::Q) = PicturedObj{P,Q,PR}(obj, prop)
# default to Heisenberg picture; this might make more sense as
# an actual default arg but I wanted the argument order to match the
# type parameter order
PicturedObj(prop, obj) = PicturedObj(Heisenberg, obj, prop) 

typealias HeisenbergPic{Q, PR} PicturedObj{Heisenburg, Q, PR}
typealias SchrodingerPic{Q, PR} PicturedObj{Schrodinger, Q, PR}

# Easily dispatch operations for same-picture args
*{P, PR}(a::PicturedObj{P, PR}, b::PicturedObj{P, PR}) = PicturedObj(P, a.obj*b.obj, a.prop*b.prop)

Parameterizing the picture type would also allow users to easily define new subtypes of Picture and define their behavior without needing to construct a wrapper type for each pictuce. This also means that the wrapper type can easily fall back to default behaviors if users do not properly define behaviors with new subtypes of Picture.

Would having efficient composable propogators as the above multiplication implies be out of the question for modern solvers? It would be really cool if we could realize a tensor product structure for propogators, though my knowledge here is weak (i.e. tensor(A(x,t;x't'), B(y,t;y',t')) -> AB(x,y,t;x',y',t')).

@acroy
Copy link
Contributor

acroy commented Jan 9, 2015

Using a Type parameter seems to be a better solution. But in any case we need to have a propagator type before we can work out the details.

Note that composability of propagators is a different issue. If you have an operator in the Heisenberg picture A(t) it is connected to the Schroedinger picture operator A via A(t)=U'(t,t0) A U(t,t0), where U(t,t0) is the propagator. If you "multiply" two Heisenberg operators at the same time you get

A(t)B(t)=U'(t,t0)AU(t,t0)U'(t,t0)BU(t,t0)=U'(t,t0)ABU(t,t0)

since U'(t,t0)U(t,t0)=I. In this case one can "save" one propagation and only propagate the product of the Schrödinger operators. You can also see that this is basically independent of the implementation of the propagtor itself (although the two versions, propagating separately and multiply or propagating the product, could give different numerical results because the propagtor might not be exactly unitary).

The tensor product of the two Heisenberg operators would amount to (denoting the tensor product by x)

A(t)xB(x) = U_A'(t,t0)xU'_B(t,t0) AxB U_A(t,t0)xU_B(t,t0)

Where I added subscripts to the propagators to distinguish them. I am not sure one can in general implement the tensor product of individual (numerical) propagations, but this is a question of realizing the propagators.

@jrevels jrevels removed this from the Initial Release milestone Sep 22, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants