-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Use explicit finite difference instead of scipy.misc.derivative in pvsyst_temperature_coeff #1674
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
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.
Thanks for this! Some ideas, tell me what you think?
- Would you be open to moving this to a new function in
tools.py
orutils.py
where ever appropriate so it could be reused? - My preference would be to define a constant
DX
at module top instead of hardcoding here. If defining a new function, then ‘dx’ could be an optional argument with defaultDX
- Traditionally dx is the cube root of epsilon, the machine precision of the system, which you can get from numpy
Originally I did implement it as a standalone function in
I generally have the view that module-level variables are best treated as read-only. If we want dx to be configurable, I'd favor it being an optional argument to
Nice! Some googling reports that this choice is not only traditional, but optimal (not sure in what sense...). Thanks! |
I agree 💯 and that's sort of what I meant like this... # in tools.py
import numpy as np
EPS = np.finfo('float64').eps # machine precision NumPy-1.20
DX = EPS**(1/3) # optimal differential element
def _my_private_explicit_derivative_calc(f, x0, dx=DX):
"""no docstring required for private functions"""
df = f(x0+dx) - f(x0-dx)
return df / 2/ dx I believe there are advantages to having epsilon defined here rather than inside a function. Mainly, it can be reused without recalculating.
I think it's okay to make it private and put minimal docstring, maybe just define args, don't even really need formatting, could doc in comments
That's a relief I've just seen this in other code, and sort of followed it without knowing exactly why, or maybe I did at one point but don't remember? Anyway, I think it has to do with floating point precision or something, this may be the smallest value for Anyway, I won't be a blocker. Whatever you decide I approve. |
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.
lgtm! Thanks!
Co-Authored-By: Mark Mikofski <[email protected]>
If the function is very flat it seems to me you can run into problems choosing a small dx. The derivative function had a default of 1.0, which could be for this reason. Also, I often use float32 in large data sets... |
pvlib/ivtools/sdm.py
Outdated
# first order centered difference at temp_ref | ||
dx = 1e-3 | ||
x0 = temp_ref | ||
dy = maxp(x0+dx, *args) - maxp(x0-dx, *args) |
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.
Since bishop88
is vectorized it shouldn't cost any more to compute 4 values than 2. Why not x = [x0-2dx, x0-dx, x0+dx, x0+2dx], pmp = maxp(x, ...) and use the fourth order formula?
gamma_pdc = np.array([1, -8, 8, -1]) * pmp / (12 * dx)
https://www.dam.brown.edu/people/alcyew/handouts/numdiff.pdf
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 didn't hit the button to submit this comment. No action required here, archiving the comment in case the issue arises.
[ ] Tests added[ ] Updates entries indocs/sphinx/source/reference
for API changes.docs/sphinx/source/whatsnew
for all changes. Includes link to the GitHub Issue with:issue:`num`
or this Pull Request with:pull:`num`
. Includes contributor name and/or GitHub username (link with:ghuser:`user`
).[ ] New code is fully documented. Includes numpydoc compliant docstrings, examples, and comments where necessary.remote-data
) and Milestone are assigned to the Pull Request and linked Issue.pvsyst_temperature_coeff
uses the default step size of 1 in its call toscipy.misc.derivative
. I haven't checked the reference to see if that value is intentional, but if not, it seems a little large to me. I've reduced the step size to the rather arbitrary value of 1e-3 here, which changes the answer very slightly: