简体   繁体   English

使用python求解非线性方程

[英]using python to solve a nonlinear equation

I have never used python but Mathematica can't handle the equation I am trying to solve. 我从未使用过python,但Mathematica无法处理我要解决的方程式。 I am trying to solve for the variable "a" of the following equations where s, c, mu, and delta t are known parameters. 我正在尝试求解以下方程式的变量“ a”,其中s,c,mu和delt t是已知参数。

在此处输入图片说明

I tried doing NSolve, Solve, etc in Mathematica but it has been running for an hour with no luck. 我尝试在Mathematica中执行NSolve,Solve等,但是已经运行了一个小时,没有运气。 Since I am not familiar with Python, is there a way I can use Python to solve this equation for a? 由于我不熟悉Python,有没有一种方法可以使用Python来解决此方程?

You're not going to find an analytic solution to these equations because they're transcendental, containing a both inside and outside of a trigonometric function. 你不会找到一个解析解这些方程,因为他们是超然的,包含a内部和三角函数之外。

I think the trouble you're having with numerical solutions is that the range of acceptable values for a is constrained by the arcsin . 我认为您在使用数字解决方案时遇到的麻烦是a的可接受值范围受arcsin约束。 Since arcsin is only defined for arguments between -1 and 1 (assuming you want a to be real), your formulas for alpha and beta require that a > s/2 and a > (sc)/2 . 由于arcsin仅为-1和1之间的参数定义(假设您希望a为实数),因此您的alphabeta公式要求a > s/2a > (sc)/2

In Python, you can find a zero of your third equation (rewritten in the form f(a) = 0 ) using the brentq function: 在Python中,您可以使用brentq函数找到第三个方程的零(以f(a) = 0的形式重写):

import numpy as np
from scipy.optimize import brentq

s = 10014.6
c = 6339.06
mu = 398600.0
dt = 780.0
def f(a):
    alpha = 2*np.arcsin(np.sqrt(s/(2*a)))
    beta = 2*np.arcsin(np.sqrt((s-c)/(2*a)))
    return alpha - beta - (np.sin(alpha)-np.sin(beta)) - np.sqrt(mu/a**3)*dt

a0 = max(s/2, (s-c)/2)
a = brentq(f, a0, 10*a0)

Edit: 编辑:

To clarify the way brentq(f,a,b) works is that it searches for a zero of f on an interval [a,b] . 为了阐明brentq(f,a,b)工作方式,是在间隔[a,b]上搜索f的零。 Here, we know that a is at least max(s/2, (sc)/2) . 在这里,我们知道a至少是max(s/2, (sc)/2) I just guessed that 10 times that was a plausible upper bound, and that worked for the given parameters. 我只是猜测10次是合理的上限,并且对给定的参数有效。 More generally, you need to make sure that f changes sign between a and b . 更一般而言,您需要确保fab之间改变符号。 You can read more about how the function works in the SciPy docs . 您可以在SciPy文档中阅读有关该功能如何工作的更多信息。

I think its worth examining the behaviour of the function before atempting to solve it. 我认为值得在尝试解决该功能之前先对其进行研究。 Without doing that you dont know if there is a unique solution, many solutions, or no solution. 如果不这样做,您将不知道是否有独特的解决方案,很多解决方案或没有解决方案。 (The biggest problem is many solutions, where numerical methods may not give you the solution you require/expect - and if you blindly use it "bad things" might happen). (最大的问题是许多解决方案,其中数值方法可能无法为您提供所需/期望的解决方案-如果您盲目使用它,则可能会发生“不好的事情”)。 You examine the behaviour nicely using scipy and ipython. 您可以使用scipy和ipython很好地检查行为。 This is an example notebook that does that 这是一个示例笔记本

# -*- coding: utf-8 -*-
# <nbformat>3.0</nbformat>

# <codecell>

s = 10014.6
c = 6339.06
mu = 398600.0
dt = 780.0

# <codecell>

def sin_alpha_2(x):
    return numpy.sqrt(s/(2*x))
def sin_beta_2(x):
    return numpy.sqrt((s-c)/(2*x))
def alpha(x):
    return 2*numpy.arcsin( numpy.clip(sin_alpha_2(x),-0.99,0.99) )
def beta(x):
    return 2*numpy.arcsin( numpy.clip(sin_beta_2(x),-0.99,0.99) )

# <codecell>

def fn(x):
    return alpha(x)-beta(x)-numpy.sin(alpha(x))+numpy.sin(beta(x)) - dt * numpy.sqrt( mu / numpy.power(x,3) )

# <codecell>

xx = numpy.arange(1,20000)
pylab.plot(xx, numpy.clip(fn(xx),-2,2) )

fn图

# <codecell>

xx=numpy.arange(4000,10000)
pylab.plot(xx,fn(xx))

在此处输入图片说明

# <codecell>

xx=numpy.arange(8000,9000)
pylab.plot(xx,fn(xx))

在此处输入图片说明

This shows that we expect to find a solution with a between 8000 and 9000. The odd kink in the curve at about 5000 and earlier solution at about 4000 is due to the clipping required to make arcsin behave. 这表明我们期望找到一个介于8000和9000之间的解决方案。曲线中的奇数扭结在约5000处,而较早的解在约4000处,这是由于使反正弦表现为必需的削波。 Really the equation does not make sense below about a=5000. 实际上,在大约a = 5000以下,该方程式没有任何意义。 (exact value is the a0 given in Rays solution). (精确值是Rays解决方案中给定的a0)。 This then gives a nice range that can be used with the techniques in Rays solution. 然后,这提供了一个很好的范围,可以与Rays解决方案中的技术一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM