-
Notifications
You must be signed in to change notification settings - Fork 22
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
Add functions for 1rdms and 2-body exchange hole #165
base: master
Are you sure you want to change the base?
Conversation
…s in return statements in density.py
for more information, see https://pre-commit.ci
This has showed up in workflows three times in the last year, so I told @sanchezw17 to implement in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
hi @sanchezw17, thanks a lot for your PR. I am currently going through the code. I was just testing your new function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left comments from my first review. Your new tests pass on my laptop but I haven't checked them in detail. Overall it looks really good to me so if we work out the comments, on my side I will be good to merge it. Thanks again for the PR @sanchezw17.
gbasis/evals/density.py
Outdated
@@ -625,7 +783,7 @@ def evaluate_posdef_kinetic_energy_density( | |||
min_output = np.min(output) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you forgot to change output
to posdef_kindetic_energy_density
. Also, maybe you have a typo there and wanted to use posdef_kinetic_energy_density
? Just double checking
gbasis/evals/density.py
Outdated
|
||
orb_evals = [] | ||
# evaluate basi(e)s on the point set(s) | ||
for grid in points_list: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are using a list to pass the points arrays. Lists are mutable objects and I think gbasis tries to reduce the use of them and use more numpy arrays. I was wondering if this this list is ever going to be longer than 2 sets of points? If it is the case it's always going to be either 1 or 2 sets of points (meaning 1 or 2 numpy arrays) I would suggest to provide the sets separately as an argument to the function so you don't have to loop. If not, maybe I would change it to a tuple as it is immutable in python.
gbasis/evals/density.py
Outdated
if not np.allclose(one_density_matrix, one_density_matrix.T): | ||
raise ValueError("One-electron density matrix must be symmetric.") | ||
|
||
# Tensor product for \gamma(\mathbf{r}_1,\mathbf{r}_2) = \sum_{pq} \gamma_{pq} \chi_p(\mathbf{r}_1) \chi_q(\mathbf{r}_2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here probably is that I am not familiar with the math, but based on this equation I would guess the output would be of dimension Npoints_1, Npoints_2
, in your notation k,l
. But you are returning an array Npoints_1, Npoints_2, K_orb, K_orb
. Let me know your thoughts, @sanchezw17, @PaulWAyers
gbasis/evals/density.py
Outdated
|
||
|
||
def evaluate_dm_density(one_density_matrix, basis, points_list, transform=None): | ||
r"""Return the density of the given basis set at the given points. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I checked correctly this is the same docstring as in evaluate_density
. I know they are similar but here two sets of points are used instead of one. Maybe we can add this in the docstring.
gbasis/evals/density.py
Outdated
dm_eval = evaluate_dm_density(one_density_matrix, basis, points_list, transform=transform) | ||
|
||
# evaluate hole function | ||
numerator = np.einsum("ijkl,ijkl->ijkl", dm_eval, dm_eval) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I am not wrong, you are multiplying dm_eval * dm_eval right? If this is the case, I was wondering if it would be more efficient to do dm_eval * dm_eval
? I know using einsum is clear for notation so I am not against it.
Hi @leila-pujal, thank you for the review. I can add either a warning or a comment at the very least (whichever you think is most appropriate in this situation). I am still working on implementing these functions, but my idea is to use these functions as callables which are integrated point-by-point, so i believe the entire 4D matrix is never stored. At the moment, I do not see the usefulness of storing the entire matrix other than bug-hunting or testing with small bases. |
Okay I see...just to check if I understood your message you mean you want to use on-the-fly elements of this matrix so you think you are not gonna need to store the whole array? Just to give more information to my message I got the error at this line |
@leila-pujal you are 100% correct I can have a function pass 2 points instead of 2 sets of points. Since I am in the early stages of working with n_dimentional integration which hasn't been fully tested yet, I want the option to have the full matrix on a grid so it closely matches the shape of "evaluate_density" (which works with grid integration) to help with bug testing. I will add another function that takes two points and returns the density matrix evaluated at that point. |
I think we should not try to vectorize over orbitals, but just accumulate the sum over the orbitals. Otherwise the memory is just too much. Or loop over the orbitals whenever the number of grid points is very high. |
I think a reasonable API is to read in a set of 3D or 6D points, and then you export the DM/xHOLE on either the 3Dx3D tensor product grid or the DM/xHOLE on the 6D points. |
The density matrix is given in terms of its basis set expansion, where we have assumed that the orbitals are real. To avoid too much memory, a sensible procedure is:
It would be ideal (not required) to allow passing a set of 3-D points (in which case the 6D tensor-product grid is formed internally) or a set of 6-D points (where two 3D sets which may not be the same are appended to each other). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @sanchezw17, thanks a lot for updating your code and sorry for the late reply. I reviewed your code and everything looks good. Just a comment, I think it would be more appropriate to use reduced density matrix (rdm) instead of density matrix. For example I would change the name evaluate_dm_using_evaluated_orbs
to evaluate_rdm_using_evaluated_orbs
even maybe to be more specific evaluate_1rdm_using_evaluated_orbs
. Also I think it would be better to specify it on the docstring too so instead of writing density matrix specify first order reduced density matrix. What do you think @FarnazH, @PaulWAyers ? This is a personal preference suggestion so if you think it is good as it is I don't have any problem.
I also pushed a commit to change using numpy.all()
because I was checking the test locally with numpy 2.0 and now np.all for an array of None
values returns false so your assertion fails (https://numpy.org/doc/stable/reference/generated/numpy.all.html).
I checked your tests for the first-order reduced density matrix and it looks good but for the exchange hole I don't know why this assertation np.allclose(eh, np.ones((len(points1), len(points1))) * -1)
. I am sure @PaulWAyers gave you some literature and this is 100% correct but I just wanted to comment that I only checked the test pass.
I will merge this in the following days probably after I merge the pytest PR #187. Feel free to leave any comments/doubts about my review. Thanks again for working on this.
I also made small edits in density.py variable names. There were a few occasions where the var_name mentioned in docustrings did not match those used in the actual function bodies.
Checklist
Type of Changes