Currently, S<:AbstractStructure is pretty vaguely defined (my own fault), and I think in light of upcoming development goals (e.g. GSoC proposal) we should give it a review. To close this issue, I would like to either:
clearly define its purpose, and give it a better name if we can think of one, or
get rid of it, and use a type hierarchal structure for bases instead of parameterization to define the properties we want.
To begin, I'll describe what I was initially thinking when I proposed the S<:AbstractStructure type family.
My idea was that we could use type parameterization + dispatch to "easily" define the behavior of the wave functions that form the basis for a given QuArray, without having to implement new concrete subtypes of AbstractBasis/QuArray. What do I mean by this? I think an example might work best. Using the hydrogen atom, a potential use case would be defining types like this:
Here, wavefunc is overloaded to return the basis wave function for hydrogen atom in spherical coordinates corresponding to the ith position in a QuVector. In other words, each index i maps to a unique quantum number tuple (n,l,m) which specifies the basis wave function for the ith coefficient in the QuVector.
What does this buy us?
First, since HydrogenSphPos <: Orthonormal, we know we can skip actually processing the basis wave functions when evaluating products of objects like QuArray{FiniteBasis{HydrogenSphPos}}.
Second, we could provide a method like the below, which would allow evaluation of the superposed state given by the QuArray at the given args:
waveeval{S}(qv::QuVector{FiniteBasis{S}}, args...) = sum([qv[i] * wavefunc(S, i)(args...) for i=1:length(qv)]
Obviously, more optimization could be done so as to not use a temporary array, but you get my drift. When we move forward to v.04, we could overload call and have beautiful syntax for evaluating states:
Base.call(qv::QuVector, args...) = waveeval(qv, args...)
#now, we can say the following:
Ψ = # some QuVector{FiniteBasis{HydrogenSphPos}}
r, θ, ϕ = # positional parameters
Ψ(r, θ, ϕ) # evaluate entire state at positional parameters
Since the above example doesn't cover it, let's say a user defines a structural type that is notS<:Orthonormal. Then, we could a provide a function like the following that could be overloaded for arbitrary type S<:AbstractStructure:
inner_rule{S}(::Type{S}, i, j) = # provides an evaluation of the inner product of wavefunc(::Type{S}, i) and wavefunc(::Type{S}, j)
...which could then be used in the evaluation of products of non-orthonormal objects.
In conclusion, the above proposal exposes a couple of functions to the user (wavefunc and inner_rule) that allows them to define/extend the behavior of QuArrays without having to dig into the internals.
Key points for this issue:
The main problem I see with the above approach is that the amount of closures/functionals involved would probably result in poor performance for certain operations, specifically what I called waveeval above.
Does anybody here know how other libraries handle this kind of functionality? I'm not familiar with the methods used for simulation of this sort, and always kind of assumed that the basis functions were either hard-coded or were able to be abstracted away for the systems people are interested in simulating. If anybody can point me to documentation I could learn from, I'd be grateful.
If we do continue to use S<:AbstractStructure, what would be a better name for it? "AbstractStructure" is terribly vague, but I haven't been able to think of any better. "BasisFunction", maybe? I'd be worried it might get confused for a subtype of Function, then...
Any thoughts with regard to this? I'd like to settle this issue (either by addressing the key points, or figuring out an alternative) before we go too far down the road.
Currently,
S<:AbstractStructure
is pretty vaguely defined (my own fault), and I think in light of upcoming development goals (e.g. GSoC proposal) we should give it a review. To close this issue, I would like to either:To begin, I'll describe what I was initially thinking when I proposed the
S<:AbstractStructure
type family.My idea was that we could use type parameterization + dispatch to "easily" define the behavior of the wave functions that form the basis for a given QuArray, without having to implement new concrete subtypes of AbstractBasis/QuArray. What do I mean by this? I think an example might work best. Using the hydrogen atom, a potential use case would be defining types like this:
Here,
wavefunc
is overloaded to return the basis wave function for hydrogen atom in spherical coordinates corresponding to the ith position in a QuVector. In other words, each index i maps to a unique quantum number tuple (n,l,m) which specifies the basis wave function for the ith coefficient in the QuVector.What does this buy us?
First, since
HydrogenSphPos <: Orthonormal
, we know we can skip actually processing the basis wave functions when evaluating products of objects likeQuArray{FiniteBasis{HydrogenSphPos}}
.Second, we could provide a method like the below, which would allow evaluation of the superposed state given by the QuArray at the given args:
Obviously, more optimization could be done so as to not use a temporary array, but you get my drift. When we move forward to v.04, we could overload
call
and have beautiful syntax for evaluating states:Since the above example doesn't cover it, let's say a user defines a structural type that is not
S<:Orthonormal
. Then, we could a provide a function like the following that could be overloaded for arbitrary typeS<:AbstractStructure
:...which could then be used in the evaluation of products of non-orthonormal objects.
In conclusion, the above proposal exposes a couple of functions to the user (
wavefunc
andinner_rule
) that allows them to define/extend the behavior of QuArrays without having to dig into the internals.Key points for this issue:
waveeval
above.S<:AbstractStructure
, what would be a better name for it? "AbstractStructure" is terribly vague, but I haven't been able to think of any better. "BasisFunction", maybe? I'd be worried it might get confused for a subtype ofFunction
, then...