-
Notifications
You must be signed in to change notification settings - Fork 12
Description
I've been thinking a lot about interfaces as I keep working on #40 where among many other things, I've been trying to figure out the best interface for conversion among superoperators. I realized the design issues there are similar to the design issues for express, which is also in some sense, an interface for conversions between types. The julia docs also document conversion patterns which either use a type's constructor T(x) or Base.convert. I think the main issue in conversion is how to specify "additional" information necessary for conversion. For example the fock cutoff, or in the superoperator case, the precision with which the spectrum of a superoperator is obtained to convert to the kraus representation.
So I wanted to ask a few questions about how the express interface is or isn't supposed to handle the following hypothetical scenarios:
- Say I have a
ket = QuantumSymbolics.CoherentState(α)whereαis a symbolic number. Then I want a symbolic matrix representation ofketin the fock basis with a cutoff, so I wantKet(FockBasis(cutoff), exp(-{|α|^2/2}) * [1,α, α^2/sqrt(2),..., α^cutoff/sqrt(cutoff!)]. Would this be some hypotheticalexpress(ket, SymbolicMatrixRepr(cutoff))? What if I explicitly want dense versus sparse representations? - What if I want this
ketexpressed inPositionBasisorMomentumBasis? It seems like just adding thexmin, xmax, Norpmin, pmax, Nfields toQuantumOpticsReprwon't specify which ofFockBasis,PositionBasis, orMomentumBasisone would want?
Perhaps I'm totally misunderstanding the intended interface for express, but as it is, I'm not sure how it will capture all the types of conversions and the parameters they might need. In order to do this, it seems like combinations of AbstractRepresentation and AbstractUse will end up just being stand ins for a T(x) type constructor and it might be better just to use that pattern? For example Ket(FockBasis(cutoff), ket) where ket is as defined as above.
On the other hand, the type T(x) constructor method wouldn't seem to be able to handle the other use of express which converts expressions containing multiple terms. This is mainly relevant for QuantumSymbolics expressions and for Lazy* that can actually represent multiple terms. For example conversion of the symbolic ket⊗ket to LazyKet(FockBasis(cutoff)⊗FockBasis(cutoff), [ket,ket]). However, I think a more flexible design might be to have AbstractRepresentation be essentially just a set of conversion rules for how to call T(x) type constructors. Sensible sets can be provided but it should be easily to define one's own rules depending on what exactly on wants. For example, something schematically like
QuantumOpticsRepr(cutoff) = Dict(
CoherentState => ket -> Ket(FockBasis(cutoff), ket),
STensor => LazyTensor
)Hopefully this would make it easier for a user to modify existing sets if they largely cover what one wants but want slight differences like only using LazyProduct or something. I'm imagining that, somewhat like SymbolicUtils.toexpr which build_function uses, we could traverse the expression tree starting from leaves and calling the appropriate T(x) conversion to build up the converted expression.
Something I'm also worried about is that express has preferred defaults, for example the current fock cutoff of 2 is way to low for any coherent state and won't give normalized states (which seems like another option express ought to have).