Open
Description
Problem
As described in #968 singlediode.bishop88_i_from_v()
and singlediode.bishop88_v_from_i()
can be very slow using how method=brentq
Solution
Scipy made changes to access Brent using Cython which can be compiled without the GIL and with prange
, a Cython command that parallelizes long loops. Compiled code is already typically very fast, so this could result in 10-100x speed improvements. Here's a gist with a Jupyter notebook benchmark that demonstrates about 30x reduction in runtime, but YMMV.
Alternatives
- An alternative to Brent is Newton which is already vectorized in Scipy using NumPy arrays. A Newton how-method is already available in
singlediode
but Newton is unbounded, and so it's not guaranteed to converge like Brent, which is a bounded search method. - write a custom vectorized bisection method - actually there already is one, I think Rob Andrews may have authored it in
pvlib.tools
:_golden_sect_DataFrame
, I think it's a golden search algorithm, not as fast as Brent, but still very good. Should we test it? Might need modification to work because I think it was specifically written for solving LambertW problems. - is there a numba way to solve this problem?
- is there a pythran solution to this?
- wait til next summer and make this a GSoC project 😉
Additional context
There might be some unpleasant hurdles:
- how do you maintain cython code in your repo?
- this should work fine for conda-forge & pvlib Anaconda channels, but what about PyPI users? We don't have a binary distribution on PyPI,
- The closest experience we've had is with the NREL SPA algorithm, which we've sort of abandoned because the NumPy & numba versions are so much faster and easier
- would we consider making binaries for deployment on multiple platforms like Windows (win32) & Mac OS X (darwin)
- would we make Linux users build their own wheels or figure out how to get involved with manylinux?