0

I have three dimensional function randomly defined by a user Z=f(x,y)

def f(x,y): return ((7*x*y)/(np.exp(x**2+y**2)))

I converted this function to polar coordinates by substituting:

x_c = r*np.cos(theta)+x1; y_c = r*np.sin(theta)+y1;

where

theta = np.linspace(0, 2*np.pi, 30);

r,x1 and y1 are constant

Now I need to find the roots for the function Z(theta) in the polar form using NR method:

from scipy.optimize import newton

Z_func = f(x_c,y_c);
root = newton(Z_func,theta.any());

the error message shows:

q0 = func(*((p0,) + args)) TypeError: 'numpy.ndarray' object is not callable

newton method accepts only a callable function how can I make the function f(x_c,y_c) callable?

I do not want to substitute as shown below and call it in newton method

7*(r*np.cos(theta)+x1)*(r*np.sin(theta)+y1))/(np.exp((r*np.cos(theta)+x1)**2+(r*np.sin(theta)+y1)**2)

because I do not know the function f(x,y) that will be given.

Any idea will be appreciated

SuperKogito
  • 2,998
  • 3
  • 16
  • 37
yahya.k
  • 21
  • 4

1 Answers1

0

Well you are right about your issue. The scipy.optimize.newton() only accepts a callable function. So You can simply define z_func(): a function that takes in your optimization variable (in this case it is theta) and returns the output of the function whose zero is wanted. I chose to separate the functions and keep your structure but with the use of the lambda operator (see code below).

import numpy as np
from scipy import optimize

# define functions
f   = lambda         x, y : (7 * x * y) / np.exp(x**2 + y**2)
x_c = lambda r, theta, x1 : r * np.cos(theta) + x1 
y_c = lambda r, theta, y1 : r * np.sin(theta) + y1
z_f = lambda        theta : f(x_c(1, theta, 1), y_c(1, theta, 1))

# define theta
theta = np.linspace(0, 2*np.pi, 30)

# optimize
root   = optimize.newton(z_f, theta.any())
print("root: ", root)

Remark: I am not sure why are you using theta.any() as a starting value, as it returns a True and that translates to 1, which makes me question the definition of the theta array since all you need is just a starting value (which is nevertheless important as it will change the root the code will converge to or might even cause a RuntimeError if it fails to converge).

SuperKogito
  • 2,998
  • 3
  • 16
  • 37