def mp_solve(f, p, x0=0.01, limits=None, method='muller'): if not limits: return mp.findroot(lambda x: f(x, p=p), x0, solver=method) else: if method == 'muller': method = 'anderson' return mp.findroot(lambda x: f(x, p=p), limits, solver=method)
def mp_solve(f, x0=0.01, limits=None, method="muller"): if not limits: return mp.findroot(f, x0, solver=method) else: if method == "muller": method = "anderson" return mp.findroot(f, limits, solver=method)
def _eval_evalf(self, prec): """Evaluate this complex root to the given precision. """ _prec, mp.prec = mp.prec, prec try: func = lambdify(self.poly.gen, self.expr) interval = self._get_interval() refined = False while True: if self.is_real: x0 = mpf(str(interval.center)) else: x0 = mpc(*map(str, interval.center)) try: root = findroot(func, x0) except ValueError: interval = interval.refine() refined = True continue else: if refined: self._set_interval(interval) break finally: mp.prec = _prec return Float._new(root.real._mpf_, prec) + I*Float._new(root.imag._mpf_, prec)
def _eval_evalf(self, prec): """Evaluate this complex root to the given precision. """ with workprec(prec): g = self.poly.gen if not g.is_Symbol: d = Dummy('x') func = lambdify(d, self.expr.subs(g, d)) else: func = lambdify(g, self.expr) interval = self._get_interval() if not self.is_real: # For complex intervals, we need to keep refining until the # imaginary interval is disjunct with other roots, that is, # until both ends get refined. ay = interval.ay by = interval.by while interval.ay == ay or interval.by == by: interval = interval.refine() while True: if self.is_real: x0 = mpf(str(interval.center)) else: x0 = mpc(*map(str, interval.center)) try: root = findroot(func, x0, verify=False) # If the (real or complex) root is not in the 'interval', # then keep refining the interval. This happens if findroot # accidentally finds a different root outside of this # interval because our initial estimate 'x0' was not close # enough. if self.is_real: a = mpf(str(interval.a)) b = mpf(str(interval.b)) if a == b: root = a break if not (a < root < b): raise ValueError("Root not in the interval.") else: ax = mpf(str(interval.ax)) bx = mpf(str(interval.bx)) ay = mpf(str(interval.ay)) by = mpf(str(interval.by)) if ax == bx and ay == by: root = ax + S.ImaginaryUnit * by break if not (ax < root.real < bx and ay < root.imag < by): raise ValueError("Root not in the interval.") except ValueError: interval = interval.refine() continue else: break return Float._new(root.real._mpf_, prec) + I * Float._new(root.imag._mpf_, prec)
def _eval_evalf(self, prec): """Evaluate this complex root to the given precision. """ _prec, mp.prec = mp.prec, prec try: func = lambdify(self.poly.gen, self.expr) interval = self._get_interval() if not self.is_real: # For complex intervals, we need to keep refining until the # imaginary interval is disjunct with other roots, that is, # until both ends get refined. ay = interval.ay by = interval.by while interval.ay == ay or interval.by == by: interval = interval.refine() while True: if self.is_real: x0 = mpf(str(interval.center)) else: x0 = mpc(*map(str, interval.center)) try: root = findroot(func, x0) # If the (real or complex) root is not in the 'interval', # then keep refining the interval. This happens if findroot # accidentally finds a different root outside of this # interval because our initial estimate 'x0' was not close # enough. if self.is_real: a = mpf(str(interval.a)) b = mpf(str(interval.b)) # This is needed due to the bug #3364: a, b = min(a, b), max(a, b) if not (a < root < b): raise ValueError("Root not in the interval.") else: ax = mpf(str(interval.ax)) bx = mpf(str(interval.bx)) ay = mpf(str(interval.ay)) by = mpf(str(interval.by)) # This is needed due to the bug #3364: ax, bx = min(ax, bx), max(ax, bx) ay, by = min(ay, by), max(ay, by) if not (ax < root.real < bx and ay < root.imag < by): raise ValueError("Root not in the interval.") except ValueError: interval = interval.refine() continue else: break finally: mp.prec = _prec return Float._new(root.real._mpf_, prec) + I * Float._new(root.imag._mpf_, prec)
def _eval_evalf(self, prec): """Evaluate this complex root to the given precision. """ with workprec(prec): g = self.poly.gen if not g.is_Symbol: d = Dummy('x') func = lambdify(d, self.expr.subs(g, d)) else: func = lambdify(g, self.expr) interval = self._get_interval() if not self.is_real: # For complex intervals, we need to keep refining until the # imaginary interval is disjunct with other roots, that is, # until both ends get refined. ay = interval.ay by = interval.by while interval.ay == ay or interval.by == by: interval = interval.refine() while True: if self.is_real: x0 = mpf(str(interval.center)) else: x0 = mpc(*map(str, interval.center)) try: root = findroot(func, x0, verify=False) # If the (real or complex) root is not in the 'interval', # then keep refining the interval. This happens if findroot # accidentally finds a different root outside of this # interval because our initial estimate 'x0' was not close # enough. if self.is_real: a = mpf(str(interval.a)) b = mpf(str(interval.b)) if a == b: root = a break if not (a < root < b): raise ValueError("Root not in the interval.") else: ax = mpf(str(interval.ax)) bx = mpf(str(interval.bx)) ay = mpf(str(interval.ay)) by = mpf(str(interval.by)) if ax == bx and ay == by: root = ax + S.ImaginaryUnit*by break if not (ax < root.real < bx and ay < root.imag < by): raise ValueError("Root not in the interval.") except ValueError: interval = interval.refine() continue else: break return Float._new(root.real._mpf_, prec) + I*Float._new(root.imag._mpf_, prec)
def _eval_evalf(self, prec): """Evaluate this complex root to the given precision. """ _prec, mp.prec = mp.prec, prec try: func = lambdify(self.poly.gen, self.expr) interval = self._get_interval() if not self.is_real: # For complex intervals, we need to keep refining until the # imaginary interval is disjunct with other roots, that is, # until both ends get refined. ay = interval.ay by = interval.by while interval.ay == ay or interval.by == by: interval = interval.refine() while True: if self.is_real: x0 = mpf(str(interval.center)) else: x0 = mpc(*map(str, interval.center)) try: root = findroot(func, x0) # If the (real or complex) root is not in the 'interval', # then keep refining the interval. This happens if findroot # accidentally finds a different root outside of this # interval because our initial estimate 'x0' was not close # enough. if self.is_real: a = mpf(str(interval.a)) b = mpf(str(interval.b)) # This is needed due to the bug #3364: a, b = min(a, b), max(a, b) if not (a < root < b): raise ValueError("Root not in the interval.") else: ax = mpf(str(interval.ax)) bx = mpf(str(interval.bx)) ay = mpf(str(interval.ay)) by = mpf(str(interval.by)) # This is needed due to the bug #3364: ax, bx = min(ax, bx), max(ax, bx) ay, by = min(ay, by), max(ay, by) if not (ax < root.real < bx and ay < root.imag < by): raise ValueError("Root not in the interval.") except ValueError: interval = interval.refine() continue else: break finally: mp.prec = _prec return Float._new(root.real._mpf_, prec) + I*Float._new(root.imag._mpf_, prec)
def critical_par(par="L1", p=p, extra_par={}): old_p = p.copy() p.update(extra_par) if par != "r": g = lambda x: G(0, p=p, extra_par={par: x}) - p["r"] else: g = lambda x: G(0, p=p, extra_par={par: x}) - x result = mp.findroot(g, p[par], solver="secant") p.update(old_p) return result
def search_extreme_points(list_a): def f(x): return d_polynomial(x, list_a) - sm.cos(x); def df(x): return dd_polynomial(x, list_a) + sm.sin(x); check_points = numpy.linspace(0.0, sm.pi, 100) sign_reverse_section = \ [p for p in zip(check_points, check_points[1:]) if f(p[0])*f(p[1]) <= 0.0] return [sm.findroot(f, x, df=df, tol=1.0e-20) for x,_ in sign_reverse_section]
def search_extreme_points(list_a): def f(x): return d_polynomial(x, list_a) - sm.cos(x) def df(x): return dd_polynomial(x, list_a) + sm.sin(x) check_points = numpy.linspace(0.0, sm.pi, 100) sign_reverse_section = \ [p for p in zip(check_points, check_points[1:]) if f(p[0])*f(p[1]) <= 0.0] return [ sm.findroot(f, x, df=df, tol=1.0e-20) for x, _ in sign_reverse_section ]
def solver(f, x): if method == "sympy": # findroot(solver="newton") or findroot(solver="secant") can't find # the root within the given tolerance. So we use solver="muller", # which converges towards complex roots (even for real starting # points), and so we need to chop all complex parts (that are small # anyway). Also we need to set the tolerance, as it sometimes fail # without it. def f_real(x): return f(complex(x).real) root = findroot(f_real, x, solver="muller", tol=1e-9) root = complex(root).real elif method == "scipy": root = newton(f, x) else: raise NotImplementedError("Unknown method.") return root
def improve_mu_m(self, beam_type, mode, decimal_precision=DEFAULT_DECIMAL_PRECISION, **kwargs): f = self._get_f(beam_type, decimal_precision) with mpmath.workdps(decimal_precision): # If not converted to `sympy.Float` precision will be lost after the # original `mpmath` context is restored return Float( mpmath.findroot(f=f, x0=self.x0(beam_type, mode, decimal_precision), solver=self.solver_name, maxsteps=self.max_iterations, verify=False, **kwargs), decimal_precision)
def find_roots(p): '''Return set of roots of polynomial *p*. :param p: sympy polynomial This uses the *nroots* method of the SymPy polynomial class to give rough roots, and subsequently refines these roots to arbitrary precision using mpmath. Returns a sorted *set* of roots. ''' x = sympy.var('x') roots = set() for x0 in p.nroots(): xi = mpmath.findroot(lambda z: p.eval(x, z), x0) roots.add(xi) return sorted(roots)
def _eval_evalf(self, prec): """Evaluate this complex root to the given precision. """ _prec, mp.prec = mp.prec, prec try: func = lambdify(self.poly.gen, self.expr) interval, refined = self._get_interval(), False while True: if self.is_real: x0 = mpf(str(interval.center)) else: re, im = interval.center re = mpf(str(re)) im = mpf(str(im)) x0 = mpc(re, im) try: root = findroot(func, x0) except ValueError: interval = interval.refine() refined = True continue else: if refined: self._set_interval(interval) if self.is_conjugate: root = root.conjugate() break finally: mp.prec = _prec return Real._new(root.real._mpf_, prec) + I * Real._new(root.imag._mpf_, prec)
def _eval_evalf(self, prec): """Evaluate this complex root to the given precision. """ _prec, mp.prec = mp.prec, prec try: func = lambdify(self.poly.gen, self.expr) interval, refined = self._get_interval(), False while True: if self.is_real: x0 = mpf(str(interval.center)) else: re, im = interval.center re = mpf(str(re)) im = mpf(str(im)) x0 = mpc(re, im) try: root = findroot(func, x0) except ValueError: interval = interval.refine() refined = True continue else: if refined: self._set_interval(interval) if self.is_conjugate: root = root.conjugate() break finally: mp.prec = _prec return Real._new(root.real._mpf_, prec) + I*Real._new(root.imag._mpf_, prec)
def nsolve(*args, **kwargs): """ Solve a nonlinear equation system numerically. nsolve(f, [args,] x0, modules=['mpmath'], **kwargs) f is a vector function of symbolic expressions representing the system. args are the variables. If there is only one variable, this argument can be omitted. x0 is a starting vector close to a solution. Use the modules keyword to specify which modules should be used to evaluate the function and the Jacobian matrix. Make sure to use a module that supports matrices. For more information on the syntax, please see the docstring of lambdify. Overdetermined systems are supported. >>> from sympy import Symbol, nsolve >>> import sympy >>> sympy.mpmath.mp.dps = 15 >>> x1 = Symbol('x1') >>> x2 = Symbol('x2') >>> f1 = 3 * x1**2 - 2 * x2**2 - 1 >>> f2 = x1**2 - 2 * x1 + x2**2 + 2 * x2 - 8 >>> print nsolve((f1, f2), (x1, x2), (-1, 1)) [-1.19287309935246] [ 1.27844411169911] For one-dimensional functions the syntax is simplified: >>> from sympy import sin, nsolve >>> from sympy.abc import x >>> nsolve(sin(x), x, 2) 3.14159265358979 >>> nsolve(sin(x), 2) 3.14159265358979 mpmath.findroot is used, you can find there more extensive documentation, especially concerning keyword parameters and available solvers. """ # interpret arguments if len(args) == 3: f = args[0] fargs = args[1] x0 = args[2] elif len(args) == 2: f = args[0] fargs = None x0 = args[1] elif len(args) < 2: raise TypeError("nsolve expected at least 2 arguments, got %i" % len(args)) else: raise TypeError("nsolve expected at most 3 arguments, got %i" % len(args)) modules = kwargs.get("modules", ["mpmath"]) if isinstance(f, (list, tuple)): f = Matrix(f).T if not isinstance(f, Matrix): # assume it's a sympy expression if isinstance(f, Equality): f = f.lhs - f.rhs f = f.evalf() atoms = f.atoms(Symbol) if fargs is None: fargs = atoms.copy().pop() if not (len(atoms) == 1 and (fargs in atoms or fargs[0] in atoms)): raise ValueError("expected a one-dimensional and numerical function") # the function is much better behaved if there is no denominator f = f.as_numer_denom()[0] f = lambdify(fargs, f, modules) return findroot(f, x0, **kwargs) if len(fargs) > f.cols: raise NotImplementedError("need at least as many equations as variables") verbose = kwargs.get("verbose", False) if verbose: print "f(x):" print f # derive Jacobian J = f.jacobian(fargs) if verbose: print "J(x):" print J # create functions f = lambdify(fargs, f.T, modules) J = lambdify(fargs, J, modules) # solve the system numerically x = findroot(f, x0, J=J, **kwargs) return x
def nsolve(*args, **kwargs): """ Solve a nonlinear equation system numerically. nsolve(f, [args,] x0, modules=['mpmath'], **kwargs) f is a vector function of symbolic expressions representing the system. args are the variables. If there is only one variable, this argument can be omitted. x0 is a starting vector close to a solution. Use the modules keyword to specify which modules should be used to evaluate the function and the Jacobian matrix. Make sure to use a module that supports matrices. For more information on the syntax, please see the docstring of lambdify. Overdetermined systems are supported. >>> from sympy import Symbol, nsolve >>> import sympy >>> sympy.mpmath.mp.dps = 15 >>> x1 = Symbol('x1') >>> x2 = Symbol('x2') >>> f1 = 3 * x1**2 - 2 * x2**2 - 1 >>> f2 = x1**2 - 2 * x1 + x2**2 + 2 * x2 - 8 >>> print nsolve((f1, f2), (x1, x2), (-1, 1)) [-1.19287309935246] [ 1.27844411169911] For one-dimensional functions the syntax is simplified: >>> from sympy import sin, nsolve >>> from sympy.abc import x >>> nsolve(sin(x), x, 2) 3.14159265358979 >>> nsolve(sin(x), 2) 3.14159265358979 mpmath.findroot is used, you can find there more extensive documentation, especially concerning keyword parameters and available solvers. """ # interpret arguments if len(args) == 3: f = args[0] fargs = args[1] x0 = args[2] elif len(args) == 2: f = args[0] fargs = None x0 = args[1] elif len(args) < 2: raise TypeError('nsolve expected at least 2 arguments, got %i' % len(args)) else: raise TypeError('nsolve expected at most 3 arguments, got %i' % len(args)) modules = kwargs.get('modules', ['mpmath']) if isinstance(f, (list, tuple)): f = Matrix(f).T if not isinstance(f, Matrix): # assume it's a sympy expression if isinstance(f, Equality): f = f.lhs - f.rhs f = f.evalf() atoms = f.atoms(Symbol) if fargs is None: fargs = atoms.copy().pop() if not (len(atoms) == 1 and (fargs in atoms or fargs[0] in atoms)): raise ValueError( 'expected a one-dimensional and numerical function') # the function is much better behaved if there is no denominator f = f.as_numer_denom()[0] f = lambdify(fargs, f, modules) return findroot(f, x0, **kwargs) if len(fargs) > f.cols: raise NotImplementedError( 'need at least as many equations as variables') verbose = kwargs.get('verbose', False) if verbose: print 'f(x):' print f # derive Jacobian J = f.jacobian(fargs) if verbose: print 'J(x):' print J # create functions f = lambdify(fargs, f.T, modules) J = lambdify(fargs, J, modules) # solve the system numerically x = findroot(f, x0, J=J, **kwargs) return x
from sympy import Symbol, ln, latex, diff, pretty_print from sympy.mpmath import findroot # p4 x = Symbol('x') g = (1 + x) * ln(1 + x) R = (x ** 2) / (2 * (1 + x / 3)) form = g - x - R diff_1 = diff(form, x, 1) diff_2 = diff(form, x, 2) def diff_func(x): return 2*x**2/(3*(2*x/3 + 2)**2) - 2*x/(2*x/3 + 2) + ln(x + 1) findroot(diff_func, 0)
print('d=', sm.nstr(d, 17)) # -2*s0*s1*s3*x**3 + s0*s2*x + s1**2*s3*x**4 + x**2*(s0**2*s3 - s1*s2) def f(s0,s1,s2,s3): return s0*s2 - list_a[1], \ s0**2*s3 - s1*s2 - list_a[2], \ -2*s0*s1*s3 - list_a[3], \ s1**2*s3 - list_a[4] print() print('Newton method calculating...', end='') initilal = (1.2732395447351627, 0.40528473456935109, 0.77633023248007499, 0.22308510060189463); list_s = sm.findroot( f, initilal, method='newton', maxsteps=10000, tol=1.0e-25) print(' OK') for k,s in enumerate(list_s): print('s[' + str(k) + ']=', sm.nstr(s, 17)) # #Remez algorithm calculating... OK #a[0]= 0.0 #a[1]= 0.9897151132173856 #a[2]= 0.044771099390202579 #a[3]= -0.22906038058222875 #a[4]= 0.036456091836172492 #d= -0.00073239476651250248
print('d=', sm.nstr(d, 17)) # -2*s0*s1*s3*x**3 + s0*s2*x + s1**2*s3*x**4 + x**2*(s0**2*s3 - s1*s2) def f(s0, s1, s2, s3): return s0*s2 - list_a[1], \ s0**2*s3 - s1*s2 - list_a[2], \ -2*s0*s1*s3 - list_a[3], \ s1**2*s3 - list_a[4] print() print('Newton method calculating...', end='') initilal = (1.2732395447351627, 0.40528473456935109, 0.77633023248007499, 0.22308510060189463) list_s = sm.findroot(f, initilal, method='newton', maxsteps=10000, tol=1.0e-25) print(' OK') for k, s in enumerate(list_s): print('s[' + str(k) + ']=', sm.nstr(s, 17)) # #Remez algorithm calculating... OK #a[0]= 0.0 #a[1]= 0.9897151132173856 #a[2]= 0.044771099390202579 #a[3]= -0.22906038058222875 #a[4]= 0.036456091836172492 #d= -0.00073239476651250248
f = simplify(pQ.pos_from(pP) & N.z) print("f = {}\n".format(msprint(f))) # calculate the derivative of f for use with newton-raphson df = simplify(f.diff(theta)) print("df/dθ = {}\n".format(msprint(df))) # constraint function for zero steer/lean configuration and # using the benchmark parameters f0 = lambdify(theta, f.subs({phi: 0, delta: 0}).subs(benchmark_parameters)) df0 = lambdify(theta, df.subs({phi: 0, delta: 0}).subs(benchmark_parameters)) print("verifying constraint equations are correct") print("for zero steer/lean, pitch should be pi/10") findroot(f0, 0.3, solver="newton", tol=1e-8, verbose=True, df=df0) c_sym = [Symbol('lean'), Symbol('pitch'), Symbol('steer')] c_sym_dict = dict(zip([phi, theta, delta], c_sym)) fc = ccode(f.subs(c_sym_dict)) dfc = ccode(df.subs(c_sym_dict)) cs_math = { 'cos': 'Math.Cos', 'sin': 'Math.Sin', 'pow': 'Math.Pow', 'sqrt': 'Math.Sqrt' } fcs = fc