用python求解一个非线性方程

用python求解一个非线性方程,python,wolfram-mathematica,nonlinear-functions,Python,Wolfram Mathematica,Nonlinear Functions,我从未使用过python,但Mathematica无法处理我试图解决的方程。我试图求解以下方程中的变量“a”,其中s、c、mu和δt是已知参数 我试着在Mathematica中做解算、解题等,但它已经运行了一个小时,没有运气。因为我不熟悉Python,有没有一种方法可以用Python来解a的这个方程?你不会找到这些方程的解析解,因为它们是超越的,包含了a三角函数的内部和外部 我认为数值解的问题在于a的可接受值范围受到弧sin的限制。由于arcin仅为-1和1之间的参数定义(假设a为实数),因此

我从未使用过python,但Mathematica无法处理我试图解决的方程。我试图求解以下方程中的变量“a”,其中s、c、mu和δt是已知参数


我试着在Mathematica中做解算、解题等,但它已经运行了一个小时,没有运气。因为我不熟悉Python,有没有一种方法可以用Python来解a的这个方程?

你不会找到这些方程的解析解,因为它们是超越的,包含了
a
三角函数的内部和外部

我认为数值解的问题在于
a
的可接受值范围受到
弧sin
的限制。由于
arcin
仅为-1和1之间的参数定义(假设
a
为实数),因此
alpha
beta
的公式需要
a>s/2
a>(s-c)/2

在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)
编辑:


为了阐明
brentq(f,a,b)
的工作方式,它在
[a,b]
间隔上搜索
f
的零。这里,我们知道
a
至少是
max(s/2,(s-c)/2)
。我只是猜测10次这是一个合理的上限,对于给定的参数来说是有效的。一般来说,您需要确保
f
a
b
之间更改符号。您可以在中阅读有关函数如何工作的更多信息。

我认为在尝试解决函数之前,检查函数的行为是值得的。如果不这样做,你就不知道是否有唯一的解决方案,许多解决方案,或者没有解决方案。(最大的问题是许多解决方案,其中数值方法可能无法提供您所需/预期的解决方案-如果您盲目使用它,“坏事”可能会发生)。您可以使用scipy和ipython很好地检查行为。这是一个这样做的示例笔记本

# -*- 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) )
#-*-编码:utf-8-*-
# 3.0
# 
s=10014.6
c=6339.06
mu=398600.0
dt=780.0
# 
def sin_alpha_2(x):
返回整数平方米(s/(2*x))
def sin_β_2(x):
返回numpy.sqrt((s-c)/(2*x))
defα(x):
返回2*numpy.arcin(numpy.clip(sin_alpha_2(x),-0.99,0.99))
defβ(x):
返回2*numpy.arcin(numpy.clip(sin_beta_2(x),-0.99,0.99))
# 
def fn(x):
返回alpha(x)-beta(x)-numpy.sin(alpha(x))+numpy.sin(beta(x))-dt*numpy.sqrt(mu/numpy.power(x,3))
# 
xx=阿兰奇(120000)
pylab图(xx,numpy.clip(fn(xx),-2,2))

#
xx=阿兰奇(400010000)
派拉布地块(xx,fn(xx))

#
xx=阿兰奇(80009000)
派拉布地块(xx,fn(xx))

这表明我们希望找到一个介于8000和9000之间的解决方案。 曲线中约5000处的奇数扭结和约4000处的早期解是由于
使Arcin正常工作所需的剪裁。实际上,在a=5000以下的情况下,这个等式是没有意义的。(精确值为溶液中给出的a0)。这就提供了一个很好的范围,可以与光线解决方案中的技术一起使用。

您能给出一个输入和输出的示例吗?@Serdalis您的意思是什么?这相当复杂,如果您提供一个实际公式的示例,它将极大地帮助任何试图重新创建它的人。没有什么比计算更伟大的了,但是一组值的解会非常有用。@Serdalis公式是代码的最后一行。上面的两行是公式s=10014.6,c=6339.06,mu=398600,delta t=780中α和β的定义,a是我想要找到的。如果
s/(2*a)
(s-c)/(2*a)
都在-1和1之间,那么
sin(alpha)
sin(beta)
可以用代数表示。除此之外…也许可以计算一些泰勒多项式(这将是混乱的),看看他们是否给你任何近似的解决方案?如果Mathematica对此束手无策,那么滚动您自己的代码以找到解决方案将是极其困难的。为什么您需要定义a0,然后说brentq(f,a0,10*a0)?我问这个问题是因为我从未使用过Python,我想知道为什么如果再次遇到类似的情况,我可以自己尝试。brentq的工作方式是它从a(这里是a0)开始,并在a(这里是a0)和b(10*a0)之间寻找给定f函数的零。定义a0是必要的,因为brentq函数需要一个开始查找零的位置。正如Ray提到的,这在第二章中解释了,它没有意义,因为在5017下,我相信轨道的同心圆不相交。这是轨道力学问题的一部分,所以我们正在解决导致物体在13分钟的780秒内转移到p2点的半长轴问题。
# <codecell>

xx=numpy.arange(4000,10000)
pylab.plot(xx,fn(xx))
# <codecell>

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