API comments
msricher opened this issue · 5 comments
Inputs to a Model Hamiltonian instance can be arbitrary, so I won't worry about those now.
Outputs are well-defined; one and two -particle integrals, and overlaps, in some file format (or in memory as an array?).
I think the best way to implement this is to have functions for outputting results in the following formats:
FCIDUMP
dense arrays
sparse arrays
whatever else we can think of
(other Python APIs, like PySCF? <- my idea)
These should be free functions, which can use methods of our Model Hamiltonian objects, written according to a well-defined interface, to generate the appropriate one or two -particle integral entries when writing the file/array. The interface should also allow us to determine the symmetry of the integrals and write them according to that (if the format supports it... FCIDUMP supports it, dense arrays don't, etc).
Hamiltonian types themselves can be written with the appropriate class hierarchy: PPP -> Hubbard -> Ising, or however it goes.
The important part is, the abstraction should go:
output writer functions
<--(used by)-- HamiltonianInterface
<--(subclass)-- SpecificHamiltonianSuperclass
<--(subclass)-- SpecificHamiltonianSubclass
The Python abc library can be used to write the Hamiltonian interface.
This would then allow us enough separation to split the work between writing output types and developing specific model Hamiltonians.
Anyone else want to comment on the API?
class HamiltonianInterface:
methods:
- integral_one_p(i, j, type) | type ϵ (overlap, hamiltonian, maybe (kin, nuc))
- integral_two_p(i, j, k, l, type) | type ϵ (hamiltonian, maybe (eri,))
- symmetry() | ϵ (2-fold, 4-fold, 8-fold)
Just a mock up.
Another idea is to have:
- integral_one_p(type)
- integral_two_p(((i, j)?), type)
each of which return a numpy array and a symmetry indicator, which would allow some degree of vectorization in the output writer functions.
Useful things to know from other people here would be:
- Which Ns (as in N-particle integrals) do we need?
- How much fine control do we need over which integrals we're outputting? Are the one and two -electron Hamiltonian operator integrals, and overlap integrals, sufficient? Or should we use this
type
idea in my proposed interface? - Any weird symmetries we'll need besides two, four, or eight -fold?
Finally, something quantum chemistry -specific; there's this convention of either using Restricted, Unrestricted, or Generalized integrals. Should we specifically support writing output files for those conventions? It should probably be an option for at least the FCIDUMP format, since it supports the RHF and UHF mode.
If people approve of this, the best way to proceed would probably be something like this:
- let's meet and solidify the API
- split into groups and make A) a mock-up of an output writer function and B) the Hamiltonian Interface superclass and a mock-up subclass
- split into groups and make A) more output writers and B) more concrete Hamiltonian subclasses
And we should all write tests along the way. The mock subclasses and mock output writer will help, allowing us to test one thing at a time. The mock subclass can return (iN + j | iN^3 + jN^2 + kN + l) for every integral and have arbitrary symmetry; and the mock output writer can be a text file or something.
EDIT: Since we're using IOData, let's use the IOData FCIDUMP writer as the mock-up output writer.
Thanks @msricher . I'd steer clear of "weird" symmetries at this point. It is relatively easy to support 1- and 2-electron integrals for restricted, unrestricted, and generalized I think.
For 1-electron (2-index) integrals I'd focus on overlap and (core) Hamiltonian. No need to have separate kinetic and potential integrals, though it is nice to be able to (optionally) specify an external magnetic field and adjust (spin)-integrals accordingly.
For 2-electron (4-index) integrals, I think only the electron-repulsion-integral and the (contracted) Hamiltonian are very important. The (contracted) Hamiltonian (where the 1-electron term is expanded into its 2-electron format) can be a stretch goal.
With only 2 1-electron-type and (at most) 2 2-electron-type integrals to support, I'd say it is borderline about how useful abstracting "types" are (provided I'm understanding Michael's suggestion correctly). We could go either way.....
Should the HamiltonianInterface class (or maybe it is the SpecificHamiltonianSuperclass one) have an addition method defined?
I'm thinking on the ability to build combined spin and occupation number Hamiltonians (those like the t-J-U-V model in the API documentation pdf) without having to specify a separate class for those.
In this case, having some type
label associated to the one and two-body interaction terms of the model Hamiltonians may be useful.
class HamiltonianInterface: methods:
- integral_one_p(i, j, type) | type ϵ (overlap, hamiltonian, maybe (kin, nuc))
- integral_two_p(i, j, k, l, type) | type ϵ (hamiltonian, maybe (eri,))
- symmetry() | ϵ (2-fold, 4-fold, 8-fold)
Just a mock up.
Another idea is to have:
- integral_one_p(type)
- integral_two_p(((i, j)?), type)
each of which return a numpy array and a symmetry indicator, which would allow some degree of vectorization in the output writer functions.
Useful things to know from other people here would be:
- Which Ns (as in N-particle integrals) do we need?
- How much fine control do we need over which integrals we're outputting? Are the one and two -electron Hamiltonian operator integrals, and overlap integrals, sufficient? Or should we use this
type
idea in my proposed interface?- Any weird symmetries we'll need besides two, four, or eight -fold?
Finally, something quantum chemistry -specific; there's this convention of either using Restricted, Unrestricted, or Generalized integrals. Should we specifically support writing output files for those conventions? It should probably be an option for at least the FCIDUMP format, since it supports the RHF and UHF mode.
So far there are implemented (still requires some tweaks tho) zero-,one- and two- electron integrals in the generalized Hamiltonian for PPP, Hubbard and Huckel hamiltonians. Input parameters are the ones that are described at API documentation pdf. Output are regular Numpy arrays, however it might be useful to use sparse arrays.
Because of potential memory limits we might also implement output for two electron integrals taking into account only indices such as p<q and r<s, but I think it relates to the symmetry that Michael suggested.