I am trying to solve an overdefined system of equations nummerically with Sympy nsolve, but I keep getting lambdify TypeErrors.
import sympy as sp
f25 = 61900.
f50 = 66200.
f75 = 70700.
f90 = 77700.
#mu = sp.Symbol('mu')
#sigma = sp.Symbol('sigma')
mu = sp.var('mu')
sigma = sp.var('sigma')
def f(x):
f = (1 / sp.sqrt(2 * sp.pi * sp.Pow(sigma,2))) * sp.euler(-1 * (sp.Pow(x - mu,2)) / (2 * sp.Pow(sigma,2)))
return f
f1 = f(f25) - 0.25
f2 = f(f50) - 0.50
f3 = f(f75) - 0.75
f4 = f(f90) - 0.90
sp.nsolve((f1, f2, f3, f4), (mu, sigma), (66000, 10000))
returns
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
File ~\Anaconda3\lib\site-packages\mpmath\calculus\optimization.py:937, in findroot(ctx, f, x0, solver, tol, verbose, verify, **kwargs)
936 try:
--> 937 fx = f(*x0)
938 multidimensional = isinstance(fx, (list, tuple, ctx.matrix))
File <lambdifygenerated-5>:2, in _lambdifygenerated(mu, sigma)
1 def _lambdifygenerated(mu, sigma):
----> 2 return ImmutableDenseMatrix([[mpf((1, 1, -2, 1)) + (mpf(1)/mpf(2))*sqrt(2)*euler(-mpf((0, 239475625, 3, 28))*(1 - mpf((0, 2384070316472963, -67, 52))*mu)**2/sigma**2)/(sqrt(pi)*sqrt(sigma**2))], [mpf((1, 1, -1, 1)) + (mpf(1)/mpf(2))*sqrt(2)*euler(-mpf((0, 68475625, 5, 27))*(1 - mpf((0, 139325861583909, -63, 47))*mu)**2/sigma**2)/(sqrt(pi)*sqrt(sigma**2))], [mpf((1, 3, -2, 2)) + (mpf(1)/mpf(2))*sqrt(2)*euler(-mpf((0, 312405625, 3, 29))*(1 - mpf((0, 8349304248355101, -69, 53))*mu)**2/sigma**2)/(sqrt(pi)*sqrt(sigma**2))], [mpf((1, 8106479329266893, -53, 53)) + (mpf(1)/mpf(2))*sqrt(2)*euler(-mpf((0, 377330625, 3, 29))*(1 - mpf((0, 3798557338215609, -68, 52))*mu)**2/sigma**2)/(sqrt(pi)*sqrt(sigma**2))]])
File ~\Anaconda3\lib\site-packages\mpmath\ctx_mp_python.py:346, in _constant.__call__(self, prec, dps, rounding)
345 if dps: prec = dps_to_prec(dps)
--> 346 return self.context.make_mpf(self.func(prec, rounding))
File ~\Anaconda3\lib\site-packages\mpmath\libmp\libelefun.py:116, in def_mpf_constant.<locals>.f(prec, rnd)
115 wp = prec + 20
--> 116 v = fixed(wp)
117 if rnd in (round_up, round_ceiling):
File ~\Anaconda3\lib\site-packages\mpmath\libmp\libelefun.py:97, in constant_memo.<locals>.g(prec, **kwargs)
96 if prec <= memo_prec:
---> 97 return f.memo_val >> (memo_prec-prec)
98 newprec = int(prec*1.05+10)
TypeError: unsupported operand type(s) for >>: 'int' and 'mpf'
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call last)
Cell In[3], line 24
21 f3 = f(f75) - 0.75
22 f4 = f(f90) - 0.90
---> 24 sp.nsolve((f1, f2, f3, f4), (mu, sigma), (66000, 10000))
File ~\Anaconda3\lib\site-packages\sympy\utilities\decorator.py:88, in conserve_mpmath_dps.<locals>.func_wrapper(*args, **kwargs)
86 dps = mpmath.mp.dps
87 try:
---> 88 return func(*args, **kwargs)
89 finally:
90 mpmath.mp.dps = dps
File ~\Anaconda3\lib\site-packages\sympy\solvers\solvers.py:3000, in nsolve(dict, *args, **kwargs)
2998 J = lambdify(fargs, J, modules)
2999 # solve the system numerically
-> 3000 x = findroot(f, x0, J=J, **kwargs)
3001 if as_dict:
3002 return [dict(zip(fargs, [sympify(xi) for xi in x]))]
File ~\Anaconda3\lib\site-packages\mpmath\calculus\optimization.py:940, in findroot(ctx, f, x0, solver, tol, verbose, verify, **kwargs)
938 multidimensional = isinstance(fx, (list, tuple, ctx.matrix))
939 except TypeError:
--> 940 fx = f(x0[0])
941 multidimensional = False
942 if 'multidimensional' in kwargs:
TypeError: _lambdifygenerated() missing 1 required positional argument: 'sigma'
I have tried to define my variables as both sp.Symbol
and sp.var
.
I have tried to bracket the variables to solve for: sp.nsolve((f1, f2, f3, f4), [(mu, sigma)], (66000, 10000))
. But that just gives me a new TypeError: TypeError: nsolve expected exactly 1 guess vectors, got 2
Bracketing my input guess values yields yet another TypeError: sp.nsolve((f1, f2, f3, f4), [(mu, sigma)], [(66000, 10000)])
. TypeError: cannot create mpf from (66000, 10000)
.
As I am sure you can tell I have all but given up, and are going at it brute force "monkeys and typewriters" style.
Can anyone offer up any advice?
Looking at your f(x)
, they appear to be some kind of normal statistical distribution. If so, you might want to replace sp.euler
with sp.E **
, where sp.E
is Euler's number.