-
Notifications
You must be signed in to change notification settings - Fork 2
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 general integer exponents #128
Conversation
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.
As test I would just do a regression test for the function.
@@ -17,6 +17,27 @@ def gamma(x: torch.Tensor) -> torch.Tensor: | |||
return torch.exp(gammaln(x)) | |||
|
|||
|
|||
# Auxilary function for stable Fourier transform implementation | |||
def gammainc_upper_over_powerlaw(exponent, zz): |
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.
Give the equation in the docstring here.
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, but there are some things that need to be double-checked. I will continue updating the tests once we fix them.
if exponent == 2: | ||
return torch.sqrt(torch.pi / zz) * torch.erfc(torch.sqrt(zz)) | ||
if exponent == 3: | ||
return -torch.expi(-zz) |
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.
As far as I know torch.expi
doesn't exist in torch
module ...
def gammainc_upper_over_powerlaw(exponent, zz): | ||
if exponent not in [1, 2, 3, 4, 5, 6]: | ||
raise ValueError(f"Unsupported exponent: {exponent}") | ||
|
||
if exponent == 1: | ||
return torch.exp(-zz) / zz | ||
if exponent == 2: | ||
return torch.sqrt(torch.pi / zz) * torch.erfc(torch.sqrt(zz)) | ||
if exponent == 3: | ||
return -torch.expi(-zz) | ||
if exponent == 4: | ||
return 2 * ( | ||
torch.exp(-zz) - torch.sqrt(torch.pi * zz) * torch.erfc(torch.sqrt(zz)) | ||
) | ||
if exponent == 5: | ||
return torch.exp(-zz) + zz * torch.expi(-zz) | ||
if exponent == 6: | ||
return ( | ||
(2 - 4 * zz) * torch.exp(-zz) | ||
+ 4 * torch.sqrt(torch.pi) * zz**1.5 * torch.erfc(torch.sqrt(zz)) | ||
) / 3 | ||
|
||
|
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.
Can we double-check that everything here is correct? With the new implementation, test_values_ewald.py
fails for inverse potentials with an exponent of 1, as it does not coincide with the Madelung constant.
The current status is as follows: For arbitrary odd integer exponents ( p >=3 ), we need the exponential integral, which is not implemented in PyTorch. The current solution is to use the existing However, there is a specific issue when p = 3. In this case, certain variables become degenerate, leading to situations where we raise values to the power of zero and even encounter division by zero (e.g. Can someone provide insights into this issue and suggest potential solutions? |
…functions in the InversePowerLawPotential class
In the last commit, I made the following changes: As discussed with @ceriottm, one possible solution to overcome the absence of the exponential integral in PyTorch is to implement it using a spline potential. Therefore, I also drafted how this could be implemented in a separate So far, the numerically splined implementation coincides with the reference SciPy one with good accuracy. However, we still need to discuss what to do with p <= 3. From what I found in the literature, our current implementation is correct for p>3. However, for p<=3, one should be careful as certain constraints (e.g., charge or dipole neutrality) need to be enforced (this is apperently why we are having trouble right now in the code with p = 3). Please correct me if I misinterpreted this while reviewing the literature. If that’s the case, I think we should add some constraints in the code for the above-mentioned exponents. |
The idea of the "background correction" is to add a uniform density that cancels out the total pseudocharge making the system overall neutral. I see no reason why this wouldn't be doable for p=2,3 so there might be an error in the expression for p=3 |
This is from Thus, there are indeed some restrictions for p<3, which might be causing the divergences. Alternatively, I might have misunderstood the issue, and we may have implemented the |
…ort backpropagation
Okay, implementing a custom backpropagation-compatible PyTorch exponential integral turned out to be not that hard(thanks @kvhuguenin for noticing it), so it’s done. Now, we need to resolve the |
I added tests to compare theoretical values and their derivatives with the splined potential for exponents 4, 5, and 6. I also decided to delete the SplinedInteger potential, as it has become redundant now that we have theoretical backpropagatable integer potentials. The only thing left to check is the background correction and what’s happening with p = 3 , and then it will be ready to merge. |
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.
Awesome!
…r consistency with SciPy
…Compatibility with Potentials (#143) * Refactor parameter handling in calculators and potentials for improved dtype and device management * Updated docstrings and changelog, added an assertion to check for an instance of the potential, and resolved the TorchScript Potential/Calculator incompatibility. * Update changelog and add test for potential and calculator compatibility
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.
Very nice. I have just a suggestion to keep the repo a bit clean.
Thanks @E-Rum !
Add exponents >3 to the main branch.
The core changes in the potential have already been implemented.
The most important change that still has to be implemented and tested in the rest of the code is that
exponent
now is of data typeint
rather thanfloat
.Also, we need some good unit tests. I was thinking of a combination of regression tests for some of the more complicated structures + generalized Madelung constants that I have computed in the past with a different code.
Contributor (creator of pull-request) checklist
Reviewer checklist
📚 Documentation preview 📚: https://torch-pme--128.org.readthedocs.build/en/128/