The basic problem here is that your function f
does not satisfy the criteria required for fsolve
to work. These criteria are described in the documentation - although arguably not very clearly.
The particular things that you need to be aware of are:
- the input to the function that will be solved for must be an n-dimensional vector (referred to in the docs as ndarray), such that the value of
x
you want is the solution to f(x, *args) = 0
.
- the output of
f
must be the same shape as the x
input to f
.
Currently, your function takes a 2 member tuple
of 1x3-arrays
(in p
) and a fixed scalar offset (in a
). It returns a 3 member tuple
of types (scalar
,3x3 array
, 1x3 array
)
As you can see, neither condition 1 nor 2 is met.
It is hard to advise you on exactly how to fix this without being exactly sure of the equation you are trying to solve. It seems you are trying to solve some particular equation f(x,y,a) = 0
for x
and y
with x0 = (1,1,1)
and y0 = (1,1,1)
and a = 9
as a fixed value. You might be able to do this by passing in x
and y
concatenated (e.g. pass in p0 = (1,1,1,1,1,1)
and in the function use x=p[:3]
and y = p[3:]
but then you must modify your function to output x and y concatenated into a 6-dimensional vector similarly. This depends on the exact function your are solving for and I can't work this out from the output of your existing f
(i.e based on a dot product, outer product and sum based tuple).
Note that arguments that you don't pass in the vector (e.g. a
in your case) will be treated as fixed values and won't be varied as part of the optimisation or returned as part of any solution.
Note for those who like the full story...
As the docs say:
fsolve
is a wrapper around MINPACK’s hybrd and hybrj algorithms.
If we look at the MINPACK hybrd documentation, the conditions for the input and output vectors are more clearly stated. See the relevant bits below (I've cut some stuff out for clarity - indicated with ... - and added the comment to show that the input and output must be the same shape - indicated with <--)
1 Purpose.
The purpose of HYBRD is to find a zero of a system of N non-
linear functions in N variables by a modification of the Powell
hybrid method. The user must provide a subroutine which calcu-
lates the functions. The Jacobian is then calculated by a for-
ward-difference approximation.
2 Subroutine and type statements.
SUBROUTINE HYBRD(FCN,N,X, ...
...
FCN
is the name of the user-supplied subroutine which calculates
the functions. FCN must be declared in an EXTERNAL statement
in the user calling program, and should be written as follows.
SUBROUTINE FCN(N,X,FVEC,IFLAG)
INTEGER N,IFLAG
DOUBLE PRECISION X(N),FVEC(N) <-- input X is an array length N, so is output FVEC
----------
CALCULATE THE FUNCTIONS AT X AND
RETURN THIS VECTOR IN FVEC.
----------
RETURN
END
N
is a positive integer input variable set to the number of
functions and variables.
X
is an array of length N. On input X must contain an initial
estimate of the solution vector. On output X contains the
final estimate of the solution vector.