How to return cost, grad as tuple for scipys fmin_cg function

2024/10/10 12:22:50

How can I make scipy's fmin_cg use one function that returns cost and gradient as a tuple? The problem with having f for cost and fprime for gradient, is that I might have to perform an operation twice (very costly) by which the grad and cost is calculated. Also, sharing the variables between them could be troublesome.

In Matlab however, fmin_cg works with one function that returns cost and gradient as tuple. I don't see why scipy's fmin_cg cannot provide such convenience.

Thanks in advance...

Answer

You can use scipy.optimize.minimize with jac=True. If that's not an option for some reason, then you can look at how it handles this situation:

class MemoizeJac(object):""" Decorator that caches the value gradient of function each time itis called. """def __init__(self, fun):self.fun = funself.jac = Noneself.x = Nonedef __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.jacelse:self(x, *args)return self.jac

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:

fmemo = MemoizeJac(f, fprime)
xopt = fmin_cg(fmemo, x0, fmemo.derivative)

The strange thing about this code is that it assumes f is always called before fprime (but not every f call is followed by an fprime call). I'm not sure if scipy.optimize actually guarantees that, but the code can be easily adapted to not make that assumption, though. Robust version of the above (untested):

class MemoizeJac(object):def __init__(self, fun):self.fun = funself.value, self.jac = None, Noneself.x = Nonedef _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.valueelse:self._compute(x, *args)return self.valuedef derivative(self, x, *args):if self.jac is not None and numpy.alltrue(x == self.x):return self.jacelse:self._compute(x, *args)return self.jac
https://en.xdnf.cn/q/69893.html

Related Q&A

n-gram name analysis in non-english languages (CJK, etc)

Im working on deduping a database of people. For a first pass, Im following a basic 2-step process to avoid an O(n^2) operation over the whole database, as described in the literature. First, I "b…

How to retrieve all the attributes of LDAP database

I am using ldap module of python to connect to ldap server. I am able to query the database but I dont know how to retrieve the fields present in the database, so that I can notify the user in advance …

Why would this dataset implementation run out of memory?

I follow this instruction and write the following code to create a Dataset for images(COCO2014 training set)from pathlib import Path import tensorflow as tfdef image_dataset(filepath, image_size, batch…

Paramiko: Creating a PKey from a public key string

Im trying to use the SSH protocol at a low level (i.e. I dont want to start a shell or anything, I just want to pass data). Thus, I am using Paramikos Transport class directly.Ive got the server side d…

Appending to the end of a file in a concurrent environment

What steps need to be taken to ensure that "full" lines are always correctly appended to the end of a file if multiple of the following (example) program are running concurrently.#!/usr/bin/e…

Cython Pickling in Package not found as Error

Im having trouble pickling a Cython class, but only when its defined inside a package. This problem was noted previously online, but they didnt state how it was resolved. There are two components here:…

How can I process images faster with Python?

Id trying to write a script that will detect an RGB value on the screen then click the x,y values. I know how to perform the click but I need to process the image a lot faster than my code below curren…

KFolds Cross Validation vs train_test_split

I just built my first random forest classifier today and I am trying to improve its performance. I was reading about how cross-validation is important to avoid overfitting of data and hence obtain bett…

Using Keras, how can I input an X_train of images (more than a thousand images)?

My application is accident-avoidance car systems using Machine Learning (Convolutional Neural Networks). My images are 200x100 JPG images and the output is an array of 4 elements: the car would move le…

Fastest way to merge two deques

Exist a faster way to merge two deques than this?# a, b are two deques. The maximum length # of a is greater than the current length # of a plus the current length of bwhile len(b):a.append(b.poplef…