Last active
April 24, 2018 23:51
-
-
Save mikofski/164f4cf202737d68c6277d4a97c447f2 to your computer and use it in GitHub Desktop.
cythonized example of scipy.optimized.newton to solve solar-cell for 100,000 different cases
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ctypedef double (*callback_type)(double, tuple); | |
cdef double newton(callback_type func, double x0, callback_type fprime, tuple args) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Cool!