diff --git a/docs/sphinx/source/whatsnew/v0.9.5.rst b/docs/sphinx/source/whatsnew/v0.9.5.rst index c11d72f0de..78f751690a 100644 --- a/docs/sphinx/source/whatsnew/v0.9.5.rst +++ b/docs/sphinx/source/whatsnew/v0.9.5.rst @@ -32,6 +32,8 @@ Bug fixes * When using ``utc_time_range`` with :py:func:`pvlib.iotools.read_ecmwf_macc`, the time index subset is now selected with ``nearest`` instead of ``before`` and ``after`` for consistency with ``cftime>=1.6.0``. (:issue:`1609`, :pull:`1656`) +* :py:func:`~pvlib.ivtools.sdm.pvsyst_temperature_coeff` no longer raises + a scipy deprecation warning (and is slightly more accurate) (:issue:`1644`, :pull:`1674`) Testing diff --git a/pvlib/ivtools/sdm.py b/pvlib/ivtools/sdm.py index 70c3be389f..34f5c66c0b 100644 --- a/pvlib/ivtools/sdm.py +++ b/pvlib/ivtools/sdm.py @@ -11,7 +11,6 @@ from scipy import constants from scipy import optimize from scipy.special import lambertw -from scipy.misc import derivative from pvlib.pvsystem import calcparams_pvsyst, singlediode, v_from_i from pvlib.singlediode import bishop88_mpp @@ -19,6 +18,8 @@ from pvlib.ivtools.utils import rectify_iv_curve, _numdiff from pvlib.ivtools.sde import _fit_sandia_cocontent +from pvlib.tools import _first_order_centered_difference + CONSTANTS = {'E0': 1000.0, 'T0': 25.0, 'k': constants.k, 'q': constants.e} @@ -1344,5 +1345,6 @@ def maxp(temp_cell, irrad_ref, alpha_sc, gamma_ref, mu_gamma, I_L_ref, I_o_ref, R_sh_ref, R_sh_0, R_s, cells_in_series, R_sh_exp, EgRef, temp_ref) pmp = maxp(temp_ref, *args) - gamma_pdc = derivative(maxp, temp_ref, args=args) + gamma_pdc = _first_order_centered_difference(maxp, x0=temp_ref, args=args) + return gamma_pdc / pmp diff --git a/pvlib/tools.py b/pvlib/tools.py index 229c5dd444..f1a569bb1f 100644 --- a/pvlib/tools.py +++ b/pvlib/tools.py @@ -458,3 +458,14 @@ def _degrees_to_index(degrees, coordinate): index = int(np.around(index)) return index + + +EPS = np.finfo('float64').eps # machine precision NumPy-1.20 +DX = EPS**(1/3) # optimal differential element + + +def _first_order_centered_difference(f, x0, dx=DX, args=()): + # simple replacement for scipy.misc.derivative, which is scheduled for + # removal in scipy 1.12.0 + df = f(x0+dx, *args) - f(x0-dx, *args) + return df / 2 / dx