How to update arguments in each iteration of scipy.optimize.newton

55 Views Asked by At

I am using newton to optimize a longish cost function that takes in multiple arguments performs some calculations and compares the original value of a variable 'a' to a new version. However, each time newton iterates through the function I would also like it to update the value of another variable that it is not optimizing which also factors in to the calculation.

Essentially:

def func(a, ap, etc..)
   perform calculations
   a_1 = function of (a,ap,etc)
   ap_1 = function of (a,ap,etc)
   return (a - a_1)

and then

root = newton(func, a, args = (ap, etc..))

I would like ap to update to the value of ap_1 in each iteration of newton's Optimization.

Does anyone have any suggestions of how to do this?

I've tried to use a single array X = [a, ap] but I don't want ap to be optimized just a. I have also tried making ap a global variable and updating it inside the function I've defined but that doesn't seem to update within the newton's Optimization function.

1

There are 1 best solutions below

0
Ori Yarden PhD On

We can use a for loop to pass scipy's optimize.newton function updated values of b, and we'll make half the values None so that it is not factored in for those iterations:

import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize

def f(x, a, b):
    if b is not None:
        b += b
    return x**3 - a + b if b is not None else 0

fder = lambda x, a, b: 3 * x**2
rng = np.random.default_rng()
x = rng.standard_normal(100)
a = np.arange(-50, 50)
b = 5
vec_res = [optimize.newton(f, _x, fprime=fder, args=(_a, _b), maxiter=200) for _x, _a, _b in zip(x, a, [b + __b if __b % 2 else None for __b in range(x.shape[0])])]
fig = plt.figure(figsize=(5, 5))
ax = plt.subplot(1, 1, 1)
ax.plot(a, vec_res, ls='-', lw=1.5, color=[1, 0, 0])
plt.show()

Outputs:

enter image description here

Whereas if b is not factored in at all (i.e. b = None):

b = None
vec_res = optimize.newton(f, x, fprime=fder, args=(a, b), maxiter=200)
fig = plt.figure(figsize=(5, 5))
ax = plt.subplot(1, 1, 1)
ax.plot(a, vec_res, ls='-', lw=1.5, color=[1, 0, 0])
plt.show()

Outputs:

enter image description here

And if b is not updated:

b = 5
vec_res = optimize.newton(f, x, fprime=fder, args=(a, b), maxiter=200)
fig = plt.figure(figsize=(5, 5))
ax = plt.subplot(1, 1, 1)
ax.plot(a, vec_res, ls='-', lw=1.5, color=[1, 0, 0])
plt.show()

Outputs:

enter image description here