简体   繁体   中英

using python to solve a nonlinear equation

I have never used python but Mathematica can't handle the equation I am trying to solve. I am trying to solve for the variable "a" of the following equations where s, c, mu, and delta t are known parameters.

在此处输入图片说明

I tried doing NSolve, Solve, etc in Mathematica but it has been running for an hour with no luck. Since I am not familiar with Python, is there a way I can use Python to solve this equation for a?

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.

I think the trouble you're having with numerical solutions is that the range of acceptable values for a is constrained by the 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 .

In Python, you can find a zero of your third equation (rewritten in the form f(a) = 0 ) using the brentq function:

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] . Here, we know that a is at least max(s/2, (sc)/2) . I just guessed that 10 times that was a plausible upper bound, and that worked for the given parameters. More generally, you need to make sure that f changes sign between a and b . You can read more about how the function works in the SciPy docs .

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. 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. Really the equation does not make sense below about a=5000. (exact value is the a0 given in Rays solution). This then gives a nice range that can be used with the techniques in Rays solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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