Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You can use <a href="http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#scipy.optimize.minimize" rel="nofollow"><code>scipy.optimize.minimize</code></a> with <code>jac=True</code>. If that's not an option for some reason, then you can look at <a href="https://github.com/scipy/scipy/blob/master/scipy/optimize/optimize.py#L49" rel="nofollow">how it handles this situation</a>:</p> <pre><code>class MemoizeJac(object): """ Decorator that caches the value gradient of function each time it is called. """ def __init__(self, fun): self.fun = fun self.jac = None self.x = None def __call__(self, x, *args): self.x = numpy.asarray(x).copy() fg = self.fun(x, *args) self.jac = fg[1] return fg[0] def derivative(self, x, *args): if self.jac is not None and numpy.alltrue(x == self.x): return self.jac else: self(x, *args) return self.jac </code></pre> <p>This class wraps a function that returns function value and gradient, keeping a one-element cache and checks that to see if it already knows its result. Usage:</p> <pre><code>fmemo = MemoizeJac(f, fprime) xopt = fmin_cg(fmemo, x0, fmemo.derivative) </code></pre> <p>The strange thing about this code is that it assumes <code>f</code> is always called before <code>fprime</code> (but not every <code>f</code> call is followed by an <code>fprime</code> call). I'm not sure if <code>scipy.optimize</code> actually guarantees that, but the code can be easily adapted to not make that assumption, though. Robust version of the above (<strong>untested</strong>):</p> <pre><code>class MemoizeJac(object): def __init__(self, fun): self.fun = fun self.value, self.jac = None, None self.x = None def _compute(self, x, *args): self.x = numpy.asarray(x).copy() self.value, self.jac = self.fun(x, *args) def __call__(self, x, *args): if self.value is not None and numpy.alltrue(x == self.x): return self.value else: self._compute(x, *args) return self.value def derivative(self, x, *args): if self.jac is not None and numpy.alltrue(x == self.x): return self.jac else: self._compute(x, *args) return self.jac </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload