Python scipy fsolve "mismatch between input and output of func argument"
Before getting to my problem, I searched the relevant threads on stackoverflow with the same problem:
- I / O error in scipy.optimize.fsolve file
- Python fsolve () complains about a form. Why?
- fsolve - mismatch between input and output
- I / O shape mismatch when using scipy.optimize.fsolve on a two dimensional anonymous parameter array variable
From what I understand after reading about this error,
raise TypeError (msg)
TypeError: fsolve: there is a mismatch between the input and output form of the 'func' argument 'fsolve_function'
The problem is that the form of input and output is not the same.
In the example code below, I have the following:
-
initialGuess
(an initial estimate to be used in a functionfsolve
in scipy.optimize). Input,initialGuess
has 3 initial estimates for coordinates x, y and z. Therefore, I expect my initial baseline estimate to always have three inputs. -
out
(nonlinear synchronous equations). In this example, I have 4 non-linear equations. -
scipy.optimize.fsolve
raises the error noted above because the input and output do not have the same shape. In my particular case, I want my input to always have three values (in order to guess the starting starting points x, y and z). The output in this case has 4 non-linear equations to be solved using the initial input estimate. - Side note: using the same form of input and output, eg. input form 3 [x, y, z] and output 3 non-linear equations,
fsolve
will do the calculation accordingly. I'm just wondering how you could extendfsolve
to use let say equal or more than 4 non-linear synchronous equations with 3 input initial estimates? -
Code below:
from scipy.optimize import fsolve def fsolve_function(arguments): x = arguments[0] y = arguments[1] z = arguments[2] out = [(35.85 - x)**2 + (93.23 - y)**2 + (-39.50 - z)**2 - 15**2] out.append((42.1 - x)**2 + (81.68 - y)**2 + (-14.64 - z)**2 - 27**2) out.append((-70.90 - x)**2 + (-55.94 - y)**2 + (-68.62 - z)**2 - 170**2) out.append((-118.69 - x)**2 + (-159.80 - y)**2 + (-39.29 - z)**2 - 277**2) return out initialGuess = [35, 93, -39] result = fsolve(fsolve_function, initialGuess) print result
source to share
fsolve
is a MINPACK wrapper hybrd
that requires the function argument and output to have the same cardinality. You can try other algorithms from more general ones scipy.optimize.root
that do not have this limitation (for example lm
):
from scipy.optimize import fsolve, root
def fsolve_function(arguments):
x = arguments[0]
y = arguments[1]
z = arguments[2]
out = [(35.85 - x)**2 + (93.23 - y)**2 + (-39.50 - z)**2 - 15**2]
out.append((42.1 - x)**2 + (81.68 - y)**2 + (-14.64 - z)**2 - 27**2)
out.append((-70.90 - x)**2 + (-55.94 - y)**2 + (-68.62 - z)**2 - 170**2)
out.append((-118.69 - x)**2 + (-159.80 - y)**2 + (-39.29 - z)**2 - 277**2)
return out
initialGuess = [35, 93, -39]
result = root(fsolve_function, initialGuess, method='lm')
print(result.x)
By the way, it can't find a null zero - should there be one?
You can also force fsolve
your function to be used if you give it an initial guess with a "dummy" fourth variable:
initialGuess = [35, 93, -39, 0]
but I'm not sure how reliable the results are in this case.
source to share