Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
cythonized example of scipy.optimized.newton to solve solar-cell for 100,000 different cases
from __future__ import division, print_function, absolute_import
from math import exp, sin
from scipy.optimize.cython_optimize cimport zeros
NUM_OF_IRRAD = 10
IL = [sin(il) + 6.0 for il in range(NUM_OF_IRRAD)]
# governing equations
cdef double f_solarcell(double i, tuple args):
v, il, io, rs, rsh, vt = args
vd = v + i * rs
return il - io * (exp(vd / vt) - 1.0) - vd / rsh - i
cdef double fprime(double i, tuple args):
v, il, io, rs, rsh, vt = args
return -io * exp((v + i * rs) / vt) * rs / vt - rs / rsh - 1
#solver
cdef double solarcell_newton(tuple args):
"""test newton with array"""
return zeros.newton(f_solarcell, 6.0, fprime, args)
# cython
def bench_cython_newton(v=5.25, il=IL, args=(1e-09, 0.004, 10, 0.27456)):
return map(solarcell_newton,
((v, il_,) + args for il_ in il))
ctypedef double (*callback_type)(double, tuple);
cdef double newton(callback_type func, double x0, callback_type fprime, tuple args)
from __future__ import division, print_function, absolute_import
import warnings
TOL = 1.48e-8
MAXITER = 50
cdef double newton(callback_type func, double p0, callback_type fprime, tuple args):
# Newton-Rapheson method
for iter in range(MAXITER):
fder = fprime(p0, args)
if fder == 0:
msg = "derivative was zero."
warnings.warn(msg, RuntimeWarning)
return p0
fval = func(p0, args)
# Newton step
p = p0 - fval / fder
if abs(p - p0) < TOL: # np_abs(p - p0).max() < tol:
return p
p0 = p
msg = "Failed to converge after %d iterations, value is %s" % (MAXITER, p)
raise RuntimeError(msg)
@wholmgren

This comment has been minimized.

Copy link

wholmgren commented Feb 5, 2018

Cool!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.