Comments (6)
I also see a need for this. Along these lines, we may also want to implement InteractionTensor in a more general way at some point so that we can optionally support higher body terms. While these are unlikely to come up often for InteractionOperator, there are many reasons why one is sometimes interested in the 3-RDM, for instance, and thus should come up sometimes for InteractionRDM.
from openfermion.
What if instead of one_body_tensor
and two_body_tensor
, we stored a dictionary called n_body_tensors
? n_body_tensors[n]
would be the tensor corresponding to n-body interactions, and n_body_tensors.keys()
would contain the types of interactions that the object describes.
from openfermion.
So, for instance, in your implementation my_tensor.n_body_tensors[3][3, 4, 5, 6, 7, 8] would correspond to the coefficient (if InteractionOperator) or expectation value (if InteractionRDM) of a^\dagger_3 a^\dagger_4 a^\dagger_5 a_6 a_7 _a_8. Right? That is a reasonable solution. Perhaps a little on the ugly side but it's at least "explicit" and fairly clear what is going on.
One thing I've been thinking about is that we could make a lot of OpenFermion cleaner by using get/set magic methods. Internally, we could implement the solution you mention but we could provide an exceptionally clean way to access elements by writing __get__
and __set__
methods so that one need only to type my_tensor[3, 4, 5, 6, 7, 8] and __get__
would automatically see that there are 6 elements so you must be looking for the 3-RDM and then it returns the appropriate thing. But this might be over-engineering a bit. Either way, the solution you propose would be a reasonable start.
But another thing we might want to think about is whether to support sparse arrays. In a lot of cases where one is dealing with 3-body terms (for instance), those interactions will be sparse. But again, it probably makes sense to make the change you mention above before getting more fancy.
Finally, if one goes to the trouble of implementing this change, it might be a good opportunity to change the name of the class. I've never liked the names InteractionTensor/InteractionOperator/InteractionRDM.
Also, I want to loop @jarrodmcc and @ncrubin into this thread since those guys are working on projects that use these classes.
from openfermion.
Maybe rename InteractionTensor to PolynomialOperator. From the fact that it stores the coefficients of a polynomial in the creation and annihilation operators (the n-body interactions correspond to the coefficients of monomials with degree 2n). Would double as a reminder that it's a special class of operators that have a polynomial-size description (if the maximum degree is fixed).
from openfermion.
I like @kevinsung's idea of generalizing all the various Interaction* objects relating to marginal type objects. The object would have some notion of data (the actual scalar values associated with the RDM) and the 'type' of the RDM--namely, the number of creation/annihilation operators. That way transformations to other objects via Jordan-Wigner and inverse Jordan-Wigner can query the operator 'type'. This general object could represent an entire class of marginals--for example a_{p}a_{q}a_{s}^{\dag}a_{r}^{\dag}--the 2-hole-marginal. I could even imagine defining an algebra for how to combine these objects (wedge product) and contract an object producing a different type order marginal.
For the non-particle conserving and BCS type Hamiltonians you'd want to keep a large number of these general tensor objects around in order to represent all the appropriate correlations in the system (see http://iopscience.iop.org/article/10.1088/1367-2630/14/2/023027/pdf).
I've used an object (called Tensor
--great name--lol) with the above properties plus a way to index into matrices representing 4-tensors. The reason for this extra basis feature is that you commonly
want to represent the RDM as a numpy 4-tensor (as it is currently done in OpenFermion) or as a matrix (more useful for computation). The basis field let's you index from a geminal--if you are dealing with the 2-particle-RDM--to a matrix index using any bijection you would like to define. My first pass at some code that does the above is in this gist. I know this doesn't help with the name but I think it's a sufficiently general to capture InteractionOperator, InteractionRDM, and PolynomialOperator.
Of course, this might be total overkill for your application. Sorry for the long response. I've found that an abstract definition of an RDM is pretty important for manipulating RDMs in a sane way without getting into all the details of how the elements vary contravariantly with respect to the one-particle basis-yadda-yadda-yadda....
from openfermion.
@babbush I just submitted a PR with the changes we discussed. The get/set magics were already implemented and just needed to be updated. I only implemented the dictionary part; I did not change names or add sparse support. I also did not implement arbitrary n-body rotations. I think that in principle, the current functions for one- and two-body rotations can be combined into one function that can do rotations for arbitrary n. However, this is not a priority for me now, and I must admit that I don't really understand the indexing for two-body rotations. Also, when I work out the coefficients for the two-body transformation by hand, I'm off from the expression in the paper draft by some conjugates or transposes. I'm probably just missing something.
from openfermion.
Related Issues (20)
- UHF energy with openfermion HOT 1
- scipy > 1.9.3 breaks QuarticFermionicSimulationGate decompose method. HOT 5
- Incorrect Bounds on Trotter Error
- Incorrect formula to calculate required Trotter steps HOT 1
- Resource estimation code not tested as part of the CI
- Should move to black for formatting.
- Why does MajoranaOperator not subclass SymbolicOperator? HOT 1
- Some inconsistencies in molecular single factorization costings HOT 1
- Inconsistencies in the double factorized chemistry resource estimate costing function
- 91 tests fail HOT 7
- Nightly tests are broken HOT 1
- slight modification to function generate_hamiltonian ?
- Operation between MajoranaOperator and numbers? HOT 5
- QuadraticFermionicSimulationGate tests fail with cirq == 1.3.0 HOT 5
- Hubbard model notebook is flaky
- Trotter evolution time may be off by a factor of 2 HOT 2
- 1 test fails HOT 1
- get_sparse_operator fails on non-simplified QubitOperators
- Bad behavior when working with sympy
- pip installation overwrites module directory HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from openfermion.