1

I'm trying to return multiple values that are obtained inside a scipy root finding function (scipy.optimize.root).

For example:

B = 1
def testfun(x, B):
    B = x + 7
    return B**2 + 9/18 - x

y = scipy.optimize.root(testfun, 7, (B))

Is there any way to return the value of B without using globals?

DivideByZero
  • 131
  • 2
  • 11

1 Answers1

1

I'm not aware of anything SciPy specific, but how about a simple closure:

from scipy import optimize

def testfun_factory():
    params = {}
    def testfun(x, B):
        params['B'] = x + 7
        return params['B']**2 + 9/18 - x
    return params, testfun

params, testfun = testfun_factory()
y = optimize.root(testfun, 7, 1)
print(params['B'])

Alternatively, an instance of a class with __call__ could also be passed as the callable.

wrwrwr
  • 1,008
  • 2
  • 11
  • 19
  • @ wrwrwr Perfect, this did the trick. I'm curious, is there a way to use a closure like this with a variable or list of variables such that they retain their names? In this case, B would be updated rather than params['B'] – DivideByZero Oct 09 '16 at 22:40
  • Technically, you could probably extend [this](http://stackoverflow.com/questions/31675756/temporarily-unpack-dictionary#answer-31675967) to update the dictionary in `__exit__`. For simplicity, just use `B` in place of `params['B']` and update the dictionary before the inner return. You can also use a namespace (`class Params: pass`) or a [`namedtuple`](https://docs.python.org/3/library/collections.html#collections.namedtuple) instead of the `dict` to shorten the notation to `params.B`. – wrwrwr Oct 10 '16 at 10:17