Just as an exercise, I am numerically solving the following system of equations:
$$ \begin{equation} \begin{cases} x^2 + y^2 = 32 \\ 3x + 7y = 15 \end{cases} \end{equation} $$
I use the following code:
from scipy.optimize import root
nfev = 0
def fun(x):
global nfev
nfev += 1
return x[0]**2 + x[1]**2 - 32, 3 * x[0] + 7 * x[1] - 15
njev = 0
def jac(x):
global njev
njev += 1
jacobian = [[2 * x[0], 2 * x[1]], [3, 7]]
return jacobian
x0 = [0, 0]
result = root(fun, x0, jac=jac)
print(result)
print(nfev, njev)
I get the following output:
message: The solution converged.
success: True
status: 1
fun: [-1.269e-08 -7.468e-10]
x: [ 1.500e+00 -5.454e+00]
nfev: 13
njev: 1
fjac: [[-9.147e-02 -9.958e-01]
[-9.958e-01 9.147e-02]]
r: [-9.918e+00 9.915e-01 1.082e+01]
qtf: [-2.960e-08 4.167e-07]
15 2
There are 15 calls to fun and 2 calls to jac
which are different from 13 and 1 for respectively nfev
and njev
result fields.
Removing jac=jac
, I get the following output:
message: The solution converged.
success: True
status: 1
fun: [-3.553e-15 0.000e+00]
x: [ 1.500e+00 5.454e+00]
nfev: 17
fjac: [[-7.626e-02 -9.971e-01]
[ 9.971e-01 -7.626e-02]]
r: [-1.003e+01 -8.319e-01 1.088e+01]
qtf: [ 6.485e-10 -8.479e-09]
19 0
There are 19 calls to fun which is different than nfev = 17
shown in the result.
What could explain the discrepancies? Would providing the Jacobian accelerate the calculations or improve the accuracy? If so in which circumstances?
Adding two print statements at the end of the jac
function as so:
print(x)
print(jacobian)
I get the following extra output:
[0 0]
[[0, 0], [3, 7]]
[0. 0.]
[[0.0, 0.0], [3, 7]]
This shows that jac
is called twice with the same x
values. This does not make much sense. Any clue?
root
solver, which is a modified Powell's method and is based on the implementation here math.utah.edu/software/minpack/minpack/hybrd.html $\endgroup$